diff --git a/Makefile.libretro b/Makefile.libretro index 669c573..0680bf8 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -199,6 +199,7 @@ LIBRETRO_SRC := $(GENPLUS_SRC_DIR)/genesis.c \ $(GENPLUS_SRC_DIR)/input_hw/teamplayer.c \ $(GENPLUS_SRC_DIR)/input_hw/xe_1ap.c \ $(GENPLUS_SRC_DIR)/input_hw/terebi_oekaki.c \ + $(GENPLUS_SRC_DIR)/input_hw/graphic_board.c \ $(GENPLUS_SRC_DIR)/cd_hw/cd_cart.c \ $(GENPLUS_SRC_DIR)/cd_hw/cdc.c \ $(GENPLUS_SRC_DIR)/cd_hw/cdd.c \ diff --git a/builds/genesis_plus_gx_libretro.dll b/builds/genesis_plus_gx_libretro.dll index b5ebad8..56e7433 100644 Binary files a/builds/genesis_plus_gx_libretro.dll and b/builds/genesis_plus_gx_libretro.dll differ diff --git a/builds/genplus_cube.dol b/builds/genplus_cube.dol index 7a86415..0dfe724 100644 Binary files a/builds/genplus_cube.dol and b/builds/genplus_cube.dol differ diff --git a/builds/genplus_wii.dol b/builds/genplus_wii.dol index c797356..ca6a374 100644 Binary files a/builds/genplus_wii.dol and b/builds/genplus_wii.dol differ diff --git a/core/cart_hw/sms_cart.c b/core/cart_hw/sms_cart.c index 2729858..2a63a29 100644 --- a/core/cart_hw/sms_cart.c +++ b/core/cart_hw/sms_cart.c @@ -258,6 +258,9 @@ static const rominfo_t game_list[] = {0xFAB6F52F, 0, 0, SYSTEM_MASTERTAP, MAPPER_NONE, SYSTEM_SMS2, REGION_USA}, /* BOom (v1.0) */ {0x143AB50B, 0, 0, SYSTEM_MASTERTAP, MAPPER_NONE, SYSTEM_SMS2, REGION_USA}, /* BOom (v1.1) */ + /* games requiring Sega Graphic Board */ + {0x276AA542, 0, 0, SYSTEM_GRAPHIC_BOARD, MAPPER_NONE, SYSTEM_SMS, REGION_USA}, /* Sega Graphic Board v2.0 Software (Prototype) */ + /* games supporting YM2413 FM */ {0x1C951F8E, 0, 1, SYSTEM_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* After Burner */ {0xC13896D5, 0, 1, SYSTEM_GAMEPAD, MAPPER_SEGA, SYSTEM_SMS2, REGION_USA}, /* Alex Kidd: The Lost Stars */ @@ -420,7 +423,7 @@ void sms_cart_init(void) } /* auto-detect required peripherals */ - input.system[0] = input.system[1] = game_list[i].peripheral; + input.system[0] = game_list[i].peripheral; /* auto-detect 3D glasses support */ cart.special = game_list[i].g_3d; diff --git a/core/input_hw/graphic_board.c b/core/input_hw/graphic_board.c new file mode 100644 index 0000000..9153e00 --- /dev/null +++ b/core/input_hw/graphic_board.c @@ -0,0 +1,111 @@ +/*************************************************************************************** + * Genesis Plus + * Sega Graphic Board support + * + * Copyright (C) 2014 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#include "shared.h" + +static struct +{ + uint8 State; + uint8 Counter; + uint8 Port; +} board; + +void graphic_board_reset(int port) +{ + input.analog[0][0] = 128; + input.analog[0][1] = 128; + board.State = 0x7f; + board.Counter = 0; + board.Port = port; +} + +unsigned char graphic_board_read(void) +{ + uint8 data; + + if (board.State & 0x20) + { + return 0x60; + } + + switch (board.Counter & 7) + { + case 0: + data = ~input.pad[board.Port]; + break; + case 1: + data = 0x0f; + break; + case 2: + data = 0x0f; + break; + case 3: + data = input.analog[board.Port][0] >> 4; + break; + case 4: + data = input.analog[board.Port][0]; + break; + case 5: + data = input.analog[board.Port][1] >> 4; + break; + case 6: + data = input.analog[board.Port][1]; + break; + case 7: + data = 0x0f; + break; + } + + return (board.State & ~0x1f) | (data & 0x0f); +} + +void graphic_board_write(unsigned char data, unsigned char mask) +{ + data = (board.State & ~mask) | (data & mask); + + if ((data ^ board.State) & 0x20) + { + board.Counter = 0; + } + else if ((data ^ board.State) & 0x40) + { + board.Counter++; + } + + board.State = data; +} diff --git a/core/input_hw/graphic_board.h b/core/input_hw/graphic_board.h new file mode 100644 index 0000000..a222c80 --- /dev/null +++ b/core/input_hw/graphic_board.h @@ -0,0 +1,47 @@ +/*************************************************************************************** + * Genesis Plus + * Sega Graphic board support + * + * Copyright (C) 2017 Eke-Eke (Genesis Plus GX) + * + * Redistribution and use of this code or any derivative works are permitted + * provided that the following conditions are met: + * + * - Redistributions may not be sold, nor may they be used in a commercial + * product or activity. + * + * - Redistributions that are modified from the original source must include the + * complete source code, including the source code for all components used by a + * binary built from the modified sources. However, as a special exception, the + * source code distributed need not include anything that is normally distributed + * (in either source or binary form) with the major components (compiler, kernel, + * and so on) of the operating system on which the executable runs, unless that + * component itself accompanies the executable. + * + * - Redistributions must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************/ + +#ifndef _GRAPHIC_H_ +#define _GRAPHIC_H_ + +/* Function prototypes */ +extern void graphic_board_reset(int port); +extern unsigned char graphic_board_read(void); +extern void graphic_board_write(unsigned char data, unsigned char mask); + +#endif diff --git a/core/input_hw/input.c b/core/input_hw/input.c index 4fbc847..66e90d0 100644 --- a/core/input_hw/input.c +++ b/core/input_hw/input.c @@ -47,6 +47,7 @@ #include "paddle.h" #include "sportspad.h" #include "terebi_oekaki.h" +#include "graphic_board.h" t_input input; int old_system[2] = {-1,-1}; @@ -203,6 +204,13 @@ void input_init(void) player++; break; } + + case SYSTEM_GRAPHIC_BOARD: + { + input.dev[0] = DEVICE_GRAPHIC_BOARD; + player++; + break; + } } if (player == MAX_INPUTS) @@ -322,6 +330,13 @@ void input_init(void) player++; break; } + + case SYSTEM_GRAPHIC_BOARD: + { + input.dev[4] = DEVICE_GRAPHIC_BOARD; + player++; + break; + } } /* J-CART */ @@ -405,6 +420,12 @@ void input_reset(void) break; } + case DEVICE_GRAPHIC_BOARD: + { + graphic_board_reset(i); + break; + } + default: { break; diff --git a/core/input_hw/input.h b/core/input_hw/input.h index 846eb84..6221722 100644 --- a/core/input_hw/input.h +++ b/core/input_hw/input.h @@ -44,33 +44,35 @@ #define MAX_DEVICES (8) /* Ports configuration */ -#define NO_SYSTEM (0) /* unconnected port*/ -#define SYSTEM_GAMEPAD (1) /* 2-buttons, 3-buttons or 6-buttons Control Pad */ -#define SYSTEM_MOUSE (2) /* Sega Mouse (only supported in either port A or port B) */ -#define SYSTEM_MENACER (3) /* Sega Menacer (only supported in port B) */ -#define SYSTEM_JUSTIFIER (4) /* Konami Justifiers (only supported in port B) */ -#define SYSTEM_XE_1AP (5) /* XE-1AP analog controller */ -#define SYSTEM_ACTIVATOR (6) /* Sega Activator */ -#define SYSTEM_LIGHTPHASER (7) /* Sega Light Phaser */ -#define SYSTEM_PADDLE (8) /* Sega Paddle Control */ -#define SYSTEM_SPORTSPAD (9) /* Sega Sports Pad */ -#define SYSTEM_MASTERTAP (10) /* Multi Tap -- Furrtek's Master Tap (unofficial) */ -#define SYSTEM_TEAMPLAYER (11) /* Multi Tap -- Sega TeamPlayer */ -#define SYSTEM_WAYPLAY (12) /* Multi Tap -- EA 4-Way Play (use both ports) */ +#define NO_SYSTEM (0) /* unconnected port*/ +#define SYSTEM_GAMEPAD (1) /* 2-buttons, 3-buttons or 6-buttons Control Pad */ +#define SYSTEM_MOUSE (2) /* Sega Mouse (only supported in either port A or port B) */ +#define SYSTEM_MENACER (3) /* Sega Menacer (only supported in port B) */ +#define SYSTEM_JUSTIFIER (4) /* Konami Justifiers (only supported in port B) */ +#define SYSTEM_XE_1AP (5) /* XE-1AP analog controller */ +#define SYSTEM_ACTIVATOR (6) /* Sega Activator */ +#define SYSTEM_LIGHTPHASER (7) /* Sega Light Phaser */ +#define SYSTEM_PADDLE (8) /* Sega Paddle Control */ +#define SYSTEM_SPORTSPAD (9) /* Sega Sports Pad */ +#define SYSTEM_GRAPHIC_BOARD (10) /* Sega Graphic Board */ +#define SYSTEM_MASTERTAP (11) /* Multi Tap -- Furrtek's Master Tap (unofficial) */ +#define SYSTEM_TEAMPLAYER (12) /* Multi Tap -- Sega TeamPlayer */ +#define SYSTEM_WAYPLAY (13) /* Multi Tap -- EA 4-Way Play (use both ports) */ /* Device type */ -#define NO_DEVICE (0xff) /* unconnected device (fixed ID for Team Player) */ -#define DEVICE_PAD3B (0x00) /* 3-buttons Control Pad (fixed ID for Team Player)*/ -#define DEVICE_PAD6B (0x01) /* 6-buttons Control Pad (fixed ID for Team Player) */ -#define DEVICE_PAD2B (0x02) /* 2-buttons Control Pad */ -#define DEVICE_MOUSE (0x03) /* Sega Mouse */ -#define DEVICE_LIGHTGUN (0x04) /* Sega Light Phaser, Menacer or Konami Justifiers */ -#define DEVICE_PADDLE (0x05) /* Sega Paddle Control */ -#define DEVICE_SPORTSPAD (0x06) /* Sega Sports Pad */ -#define DEVICE_PICO (0x07) /* PICO tablet */ -#define DEVICE_TEREBI (0x08) /* Terebi Oekaki tablet */ -#define DEVICE_XE_1AP (0x09) /* XE-1AP analog controller */ -#define DEVICE_ACTIVATOR (0x0a) /* Activator */ +#define NO_DEVICE (0xff) /* unconnected device (fixed ID for Team Player) */ +#define DEVICE_PAD3B (0x00) /* 3-buttons Control Pad (fixed ID for Team Player)*/ +#define DEVICE_PAD6B (0x01) /* 6-buttons Control Pad (fixed ID for Team Player) */ +#define DEVICE_PAD2B (0x02) /* 2-buttons Control Pad */ +#define DEVICE_MOUSE (0x03) /* Sega Mouse */ +#define DEVICE_LIGHTGUN (0x04) /* Sega Light Phaser, Menacer or Konami Justifiers */ +#define DEVICE_PADDLE (0x05) /* Sega Paddle Control */ +#define DEVICE_SPORTSPAD (0x06) /* Sega Sports Pad */ +#define DEVICE_GRAPHIC_BOARD (0x07) /* Sega Graphic Board */ +#define DEVICE_PICO (0x08) /* PICO tablet */ +#define DEVICE_TEREBI (0x09) /* Terebi Oekaki tablet */ +#define DEVICE_XE_1AP (0x0a) /* XE-1AP analog controller */ +#define DEVICE_ACTIVATOR (0x0b) /* Activator */ /* Default Input bitmasks */ #define INPUT_MODE (0x0800) @@ -127,6 +129,11 @@ #define INPUT_ACTIVATOR_1U (0x0002) #define INPUT_ACTIVATOR_1L (0x0001) +/* Graphic Board specific bitmasks */ +#define INPUT_GRAPHIC_PEN (0x0004) +#define INPUT_GRAPHIC_DO (0x0002) +#define INPUT_GRAPHIC_MENU (0x0001) + typedef struct { uint8 system[2]; /* can be one of the SYSTEM_* values */ diff --git a/core/io_ctrl.c b/core/io_ctrl.c index 07eefc6..3800f17 100644 --- a/core/io_ctrl.c +++ b/core/io_ctrl.c @@ -48,6 +48,7 @@ #include "teamplayer.h" #include "paddle.h" #include "sportspad.h" +#include "graphic_board.h" uint8 io_reg[0x10]; @@ -150,6 +151,13 @@ void io_init(void) break; } + case SYSTEM_GRAPHIC_BOARD: + { + port[0].data_w = graphic_board_write; + port[0].data_r = graphic_board_read; + break; + } + default: { port[0].data_w = dummy_write; @@ -244,6 +252,13 @@ void io_init(void) break; } + case SYSTEM_GRAPHIC_BOARD: + { + port[1].data_w = graphic_board_write; + port[1].data_r = graphic_board_read; + break; + } + default: { port[1].data_w = dummy_write; diff --git a/gx/gui/menu.c b/gx/gui/menu.c index 315886c..451b99c 100644 --- a/gx/gui/menu.c +++ b/gx/gui/menu.c @@ -109,6 +109,7 @@ extern const u8 Ctrl_sportspad_png[]; extern const u8 Ctrl_none_png[]; extern const u8 Ctrl_teamplayer_png[]; extern const u8 Ctrl_mastertap_png[]; +extern const u8 Ctrl_graphic_board_png[]; extern const u8 Ctrl_pad_auto_png[]; extern const u8 Ctrl_pad2b_png[]; extern const u8 Ctrl_pad3b_png[]; @@ -2205,37 +2206,39 @@ static void ctrlmenu(void) u32 exp, index = 0; /* System devices */ - gui_item items_sys[2][13] = + gui_item items_sys[2][14] = { { - {NULL,Ctrl_none_png ,"","Select Port 1 device",110,130,48,72}, - {NULL,Ctrl_gamepad_png ,"","Select Port 1 device",100,109,68,92}, - {NULL,Ctrl_mouse_png ,"","Select Port 1 device", 97,113,64,88}, - {NULL,Ctrl_menacer_png ,"","Select Port 1 device", 94,113,80,88}, - {NULL,Ctrl_justifiers_png ,"","Select Port 1 device", 88,117,80,84}, - {NULL,Ctrl_xe_1ap_png ,"","Select Port 1 device", 98,118,72,84}, - {NULL,Ctrl_activator_png ,"","Select Port 1 device", 94,121,72,80}, - {NULL,Ctrl_lightphaser_png,"","Select Port 1 device", 89,109,88,92}, - {NULL,Ctrl_paddle_png ,"","Select Port 1 device", 86,117,96,84}, - {NULL,Ctrl_sportspad_png ,"","Select Port 1 device", 95,117,76,84}, - {NULL,Ctrl_mastertap_png ,"","Select Port 1 device", 96,104,76,96}, - {NULL,Ctrl_teamplayer_png ,"","Select Port 1 device", 94,109,80,92}, - {NULL,Ctrl_4wayplay_png ,"","Select Port 1 device", 98,110,72,92} + {NULL,Ctrl_none_png ,"","Select Port 1 device",110,130,48,72}, + {NULL,Ctrl_gamepad_png ,"","Select Port 1 device",100,109,68,92}, + {NULL,Ctrl_mouse_png ,"","Select Port 1 device", 97,113,64,88}, + {NULL,Ctrl_menacer_png ,"","Select Port 1 device", 94,113,80,88}, + {NULL,Ctrl_justifiers_png ,"","Select Port 1 device", 88,117,80,84}, + {NULL,Ctrl_xe_1ap_png ,"","Select Port 1 device", 98,118,72,84}, + {NULL,Ctrl_activator_png ,"","Select Port 1 device", 94,121,72,80}, + {NULL,Ctrl_lightphaser_png ,"","Select Port 1 device", 89,109,88,92}, + {NULL,Ctrl_paddle_png ,"","Select Port 1 device", 86,117,96,84}, + {NULL,Ctrl_sportspad_png ,"","Select Port 1 device", 95,117,76,84}, + {NULL,Ctrl_graphic_board_png ,"","Select Port 1 device", 90,105,88,96}, + {NULL,Ctrl_mastertap_png ,"","Select Port 1 device", 96,104,76,96}, + {NULL,Ctrl_teamplayer_png ,"","Select Port 1 device", 94,109,80,92}, + {NULL,Ctrl_4wayplay_png ,"","Select Port 1 device", 98,110,72,92} }, { - {NULL,Ctrl_none_png ,"","Select Port 2 device",110,300,48,72}, - {NULL,Ctrl_gamepad_png ,"","Select Port 2 device",100,279,68,92}, - {NULL,Ctrl_mouse_png ,"","Select Port 2 device", 97,283,64,88}, - {NULL,Ctrl_menacer_png ,"","Select Port 2 device", 94,283,80,88}, - {NULL,Ctrl_justifiers_png ,"","Select Port 2 device", 88,287,80,84}, - {NULL,Ctrl_xe_1ap_png ,"","Select Port 2 device", 98,288,72,84}, - {NULL,Ctrl_activator_png ,"","Select Port 2 device", 94,291,72,80}, - {NULL,Ctrl_lightphaser_png,"","Select Port 2 device", 89,279,88,92}, - {NULL,Ctrl_paddle_png ,"","Select Port 2 device", 86,287,96,84}, - {NULL,Ctrl_sportspad_png ,"","Select Port 2 device", 95,287,76,84}, - {NULL,Ctrl_mastertap_png ,"","Select Port 1 device", 96,274,76,96}, - {NULL,Ctrl_teamplayer_png ,"","Select Port 2 device", 94,279,80,92}, - {NULL,Ctrl_4wayplay_png ,"","Select Port 2 device", 98,280,72,92} + {NULL,Ctrl_none_png ,"","Select Port 2 device",110,300,48,72}, + {NULL,Ctrl_gamepad_png ,"","Select Port 2 device",100,279,68,92}, + {NULL,Ctrl_mouse_png ,"","Select Port 2 device", 97,283,64,88}, + {NULL,Ctrl_menacer_png ,"","Select Port 2 device", 94,283,80,88}, + {NULL,Ctrl_justifiers_png ,"","Select Port 2 device", 88,287,80,84}, + {NULL,Ctrl_xe_1ap_png ,"","Select Port 2 device", 98,288,72,84}, + {NULL,Ctrl_activator_png ,"","Select Port 2 device", 94,291,72,80}, + {NULL,Ctrl_lightphaser_png ,"","Select Port 2 device", 89,279,88,92}, + {NULL,Ctrl_paddle_png ,"","Select Port 2 device", 86,287,96,84}, + {NULL,Ctrl_sportspad_png ,"","Select Port 2 device", 95,287,76,84}, + {NULL,Ctrl_graphic_board_png ,"","Select Port 2 device", 90,275,88,96}, + {NULL,Ctrl_mastertap_png ,"","Select Port 1 device", 96,274,76,96}, + {NULL,Ctrl_teamplayer_png ,"","Select Port 2 device", 94,279,80,92}, + {NULL,Ctrl_4wayplay_png ,"","Select Port 2 device", 98,280,72,92} } }; @@ -2300,7 +2303,7 @@ static void ctrlmenu(void) button_player_none_data.texture[0] = gxTextureOpenPNG(button_player_none_data.image[0],0); /* initialize custom images */ - for (i=0; i<13; i++) + for (i=0; i<14; i++) { items_sys[1][i].texture = items_sys[0][i].texture = gxTextureOpenPNG(items_sys[0][i].data,0); } @@ -2378,6 +2381,12 @@ static void ctrlmenu(void) input.system[0]++; } + /* allow only one connected graphic board */ + if ((input.system[0] == SYSTEM_GRAPHIC_BOARD) && (input.system[1] == SYSTEM_GRAPHIC_BOARD)) + { + input.system[0]++; + } + /* 4-wayplay uses both ports */ if (input.system[0] == SYSTEM_WAYPLAY) { @@ -2471,6 +2480,12 @@ static void ctrlmenu(void) input.system[1]++; } + /* allow only one connected graphic board */ + if ((input.system[0] == SYSTEM_GRAPHIC_BOARD) && (input.system[1] == SYSTEM_GRAPHIC_BOARD)) + { + input.system[1]++; + } + /* 4-wayplay uses both ports */ if (input.system[1] == SYSTEM_WAYPLAY) { @@ -2852,7 +2867,7 @@ static void ctrlmenu(void) if (config.input[player].device >= 0) { GUI_MsgBoxOpen("Keys Configuration", "",0); - if ((*special == 3) && !system_hw) + if (!system_hw && special && (*special == 3)) { /* no auto-detected pad type, use 6-buttons key mapping as default */ gx_input_Config(config.input[player].port, config.input[player].device, DEVICE_PAD6B); @@ -2985,7 +3000,7 @@ static void ctrlmenu(void) gxTextureClose(&button_player_none_data.texture[0]); /* delete custom images */ - for (i=0; i<13; i++) + for (i=0; i<14; i++) { gxTextureClose(&items_sys[0][i].texture); } diff --git a/gx/gx_input.c b/gx/gx_input.c index 4573131..7fd82e6 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -386,10 +386,8 @@ static void pad_update(s8 chan, u8 i) if (input.analog[0][1] < 0x1fc) input.analog[0][1] = 0x1fc; else if (input.analog[0][1] > 0x2f7) input.analog[0][1] = 0x2f7; - /* PEN button */ + /* PEN & RED button */ if (p & pad_keymap[KEY_BUTTONA]) input.pad[0] |= INPUT_PICO_RED; - - /* RED button */ if (p & pad_keymap[KEY_BUTTONB]) input.pad[0] |= INPUT_PICO_PEN; /* PAGE index increment */ @@ -416,6 +414,26 @@ static void pad_update(s8 chan, u8 i) break; } + case DEVICE_GRAPHIC_BOARD: + { + /* PEN screen position (x,y) */ + input.analog[0][0] += x / ANALOG_SENSITIVITY; + input.analog[0][1] -= y / ANALOG_SENSITIVITY; + + /* Limits */ + if (input.analog[0][0] < 0) input.analog[0][0] = 0; + else if (input.analog[0][0] > 255) input.analog[0][0] = 255; + if (input.analog[0][1] < 0) input.analog[0][1] = 0; + else if (input.analog[0][1] > 255) input.analog[0][1] = 255; + + /* MODE buttons */ + if (p & pad_keymap[KEY_BUTTONA]) input.pad[0] |= INPUT_GRAPHIC_PEN; + if (p & pad_keymap[KEY_BUTTONB]) input.pad[0] |= INPUT_GRAPHIC_DO; + if (p & pad_keymap[KEY_BUTTONC]) input.pad[0] |= INPUT_GRAPHIC_MENU; + + break; + } + case DEVICE_ACTIVATOR: { /* Left & right analog stick angle [0-360] */ @@ -893,12 +911,25 @@ static void wpad_update(s8 chan, u8 i, u32 exp) case DEVICE_MOUSE: { /* Mouse relative movement (-255,255) */ - input.analog[i][0] = (x / ANALOG_SENSITIVITY) * 2; - input.analog[i][1] = (y / ANALOG_SENSITIVITY) * 2; - - /* Wiimote IR (buggy) */ - if (exp != WPAD_EXP_CLASSIC) + if (MOUSE_IsConnected()) { + /* USB mouse support */ + mouse_event event; + MOUSE_GetEvent(&event); + MOUSE_FlushEvents(); + + /* USB mouse position (-127;+127) -> (-255;+255) */ + input.analog[i][0] = event.rx * 2; + input.analog[i][1] = event.ry * 2; + + /* USB mouse buttons */ + if (event.button & 1) input.pad[i] |= INPUT_MOUSE_RIGHT; + if (event.button & 2) input.pad[i] |= INPUT_MOUSE_CENTER; + if (event.button & 4) input.pad[i] |= INPUT_MOUSE_LEFT; + } + else if (exp != WPAD_EXP_CLASSIC) + { + /* Wiimote IR (buggy) */ struct ir_t ir; WPAD_IR(chan, &ir); @@ -909,23 +940,11 @@ static void wpad_update(s8 chan, u8 i, u32 exp) input.analog[i][1] = (int)((ir.sy - 384) * 2 / 3 / ANALOG_SENSITIVITY); } } - - /* USB mouse support */ - if (MOUSE_IsConnected()) + else { - /* read mouse data */ - mouse_event event; - MOUSE_GetEvent(&event); - MOUSE_FlushEvents(); - - /* mouse position (-127;+127) -> (-255;+255) */ - input.analog[i][0] = event.rx * 2; - input.analog[i][1] = event.ry * 2; - - /* mouse buttons */ - if (event.button & 1) input.pad[i] |= INPUT_MOUSE_RIGHT; - if (event.button & 2) input.pad[i] |= INPUT_MOUSE_CENTER; - if (event.button & 4) input.pad[i] |= INPUT_MOUSE_LEFT; + /* Classic Controller analog stick position (-127;+127) -> (-255;+255) */ + input.analog[i][0] = (x / ANALOG_SENSITIVITY) * 2; + input.analog[i][1] = (y / ANALOG_SENSITIVITY) * 2; } /* Y-Axis inversion */ @@ -952,18 +971,9 @@ static void wpad_update(s8 chan, u8 i, u32 exp) else if (p & PAD_BUTTON_RIGHT) input.pad[i] |= INPUT_RIGHT; /* PEN screen position (x,y) */ - input.analog[0][0] += x / ANALOG_SENSITIVITY; - input.analog[0][1] -= y / ANALOG_SENSITIVITY; - - /* Limits */ - if (input.analog[0][0] > 0x17c) input.analog[0][0] = 0x17c; - else if (input.analog[0][0] < 0x3c) input.analog[0][0] = 0x3c; - if (input.analog[0][1] < 0x1fc) input.analog[0][1] = 0x1fc; - else if (input.analog[0][1] > 0x2f7) input.analog[0][1] = 0x2f7; - - /* Wiimote IR */ if (exp != WPAD_EXP_CLASSIC) { + /* Wiimote IR */ struct ir_t ir; WPAD_IR(chan, &ir); if (ir.valid) @@ -972,11 +982,21 @@ static void wpad_update(s8 chan, u8 i, u32 exp) input.analog[0][1] = 0x1fc + ((ir.y + config.caly) * (0x2f7 - 0x1fc + 1)) / 480; } } + else + { + /* Classic Controller analog stick */ + input.analog[0][0] += x / ANALOG_SENSITIVITY; + input.analog[0][1] -= y / ANALOG_SENSITIVITY; - /* PEN button */ + /* Limits */ + if (input.analog[0][0] > 0x17c) input.analog[0][0] = 0x17c; + else if (input.analog[0][0] < 0x3c) input.analog[0][0] = 0x3c; + if (input.analog[0][1] < 0x1fc) input.analog[0][1] = 0x1fc; + else if (input.analog[0][1] > 0x2f7) input.analog[0][1] = 0x2f7; + } + + /* PEN & RED buttons */ if (p & wpad_keymap[KEY_BUTTONA]) input.pad[0] |= INPUT_PICO_PEN; - - /* RED button */ if (p & wpad_keymap[KEY_BUTTONB]) input.pad[0] |= INPUT_PICO_RED; /* PAGE index increment */ @@ -988,18 +1008,9 @@ static void wpad_update(s8 chan, u8 i, u32 exp) case DEVICE_TEREBI: { /* PEN screen position (x,y) */ - input.analog[0][0] += x / ANALOG_SENSITIVITY; - input.analog[0][1] -= y / ANALOG_SENSITIVITY; - - /* Limits */ - if (input.analog[0][0] < 0) input.analog[0][0] = 0; - else if (input.analog[0][0] > 250) input.analog[0][0] = 250; - if (input.analog[0][1] < 0) input.analog[0][1] = 0; - else if (input.analog[0][1] > 250) input.analog[0][1] = 250; - - /* Wiimote IR */ if (exp != WPAD_EXP_CLASSIC) { + /* Wiimote IR */ struct ir_t ir; WPAD_IR(chan, &ir); if (ir.valid) @@ -1008,6 +1019,18 @@ static void wpad_update(s8 chan, u8 i, u32 exp) input.analog[0][1] = ((ir.y + config.caly) * 250) / 480; } } + else + { + /* Classic Controller analog stick */ + input.analog[0][0] += x / ANALOG_SENSITIVITY; + input.analog[0][1] -= y / ANALOG_SENSITIVITY; + + /* Limits */ + if (input.analog[0][0] < 0)input.analog[0][0] = 0; + else if (input.analog[0][0] > 250) input.analog[0][0] = 250; + if (input.analog[0][1] < 0) input.analog[0][1] = 0; + else if (input.analog[0][1] > 250) input.analog[0][1] = 250; + } /* PEN button */ if (p & wpad_keymap[KEY_BUTTONA]) input.pad[0] |= INPUT_BUTTON1; @@ -1015,6 +1038,41 @@ static void wpad_update(s8 chan, u8 i, u32 exp) break; } + case DEVICE_GRAPHIC_BOARD: + { + /* PEN screen position (x,y) */ + if (exp != WPAD_EXP_CLASSIC) + { + /* Wiimote IR */ + struct ir_t ir; + WPAD_IR(chan, &ir); + if (ir.valid) + { + input.analog[0][0] = ((ir.x + config.calx) * 255) / 640; + input.analog[0][1] = ((ir.y + config.caly) * 255) / 480; + } + } + else + { + /* Classic Controller analog stick */ + input.analog[0][0] += x / ANALOG_SENSITIVITY; + input.analog[0][1] -= y / ANALOG_SENSITIVITY; + + /* Limits */ + if (input.analog[0][0] < 0)input.analog[0][0] = 0; + else if (input.analog[0][0] > 255) input.analog[0][0] = 255; + if (input.analog[0][1] < 0) input.analog[0][1] = 0; + else if (input.analog[0][1] > 255) input.analog[0][1] = 255; + } + + /* MODE Buttons */ + if (p & wpad_keymap[KEY_BUTTONA]) input.pad[0] |= INPUT_GRAPHIC_PEN; + if (p & wpad_keymap[KEY_BUTTONB]) input.pad[0] |= INPUT_GRAPHIC_DO; + if (p & wpad_keymap[KEY_BUTTONC]) input.pad[0] |= INPUT_GRAPHIC_MENU; + + break; + } + case DEVICE_ACTIVATOR: { /* Classic Controller only */ @@ -1421,6 +1479,17 @@ void gx_input_Config(u8 chan, u8 device, u8 type) break; } + case DEVICE_GRAPHIC_BOARD: + { + first_key = KEY_BUTTONA; + last_key = KEY_START; + sprintf(keyname[KEY_BUTTONA],"PEN Button"); + sprintf(keyname[KEY_BUTTONB],"DO Button"); + sprintf(keyname[KEY_BUTTONC],"MENU Button"); + sprintf(keyname[KEY_START],"PAUSE Button"); + break; + } + default: { first_key = KEY_BUTTONA; diff --git a/gx/images/Ctrl_graphic_board.png b/gx/images/Ctrl_graphic_board.png new file mode 100644 index 0000000..2783087 Binary files /dev/null and b/gx/images/Ctrl_graphic_board.png differ diff --git a/libretro/libretro.c b/libretro/libretro.c index 6119c46..8178836 100644 --- a/libretro/libretro.c +++ b/libretro/libretro.c @@ -27,6 +27,7 @@ #define RETRO_DEVICE_PHASER RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 0) #define RETRO_DEVICE_MENACER RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 1) #define RETRO_DEVICE_JUSTIFIERS RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 2) +#define RETRO_DEVICE_GRAPHIC_BOARD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_POINTER, 0) #include "shared.h" #include "libretro.h" @@ -334,15 +335,6 @@ void osd_input_update(void) input.analog[i][0] = ((input_state_cb(player, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) + 0x7fff) * 250) / 0xfffe; input.analog[i][1] = ((input_state_cb(player, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y) + 0x7fff) * 250) / 0xfffe; - if (input.analog[0][0] < 0) - input.analog[0][0] = 0; - else if (input.analog[0][0] > 250) - input.analog[0][0] = 250; - if (input.analog[0][1] < 0) - input.analog[0][1] = 0; - else if (input.analog[0][1] > 250) - input.analog[0][1] = 250; - if (input_state_cb(player, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT)) temp |= INPUT_BUTTON1; if (input_state_cb(player, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_MIDDLE)) @@ -352,6 +344,22 @@ void osd_input_update(void) break; } + case DEVICE_GRAPHIC_BOARD: + { + input.analog[i][0] = ((input_state_cb(player, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X) + 0x7fff) * 255) / 0xfffe; + input.analog[i][1] = ((input_state_cb(player, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y) + 0x7fff) * 255) / 0xfffe; + + if (input_state_cb(player, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT)) + temp |= INPUT_GRAPHIC_PEN; + if (input_state_cb(player, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_MIDDLE)) + temp |= INPUT_GRAPHIC_DO; + if (input_state_cb(player, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT)) + temp |= INPUT_GRAPHIC_MENU; + + player++; + break; + } + case DEVICE_XE_1AP: { int rx = input.analog[i][0] = input_state_cb(player, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X); @@ -960,6 +968,7 @@ void retro_set_environment(retro_environment_t cb) { "MS Light Phaser", RETRO_DEVICE_PHASER }, { "MS Paddle Control", RETRO_DEVICE_PADDLE }, { "MS Sports Pad", RETRO_DEVICE_SPORTSPAD }, + { "MS Graphic Board", RETRO_DEVICE_GRAPHIC_BOARD }, { "MD XE-1AP", RETRO_DEVICE_XE_1AP }, { "MD Mouse", RETRO_DEVICE_MOUSE }, }; @@ -980,13 +989,14 @@ void retro_set_environment(retro_environment_t cb) { "MS Light Phaser", RETRO_DEVICE_PHASER }, { "MS Paddle Control", RETRO_DEVICE_PADDLE }, { "MS Sports Pad", RETRO_DEVICE_SPORTSPAD }, + { "MS Graphic Board", RETRO_DEVICE_GRAPHIC_BOARD }, { "MD XE-1AP", RETRO_DEVICE_XE_1AP }, { "MD Mouse", RETRO_DEVICE_MOUSE }, }; static const struct retro_controller_info ports[] = { - { port_1, 15 }, - { port_2, 17 }, + { port_1, 16 }, + { port_2, 18 }, { 0 }, }; @@ -1111,6 +1121,9 @@ void retro_set_controller_port_device(unsigned port, unsigned device) case RETRO_DEVICE_MOUSE: input.system[port] = SYSTEM_MOUSE; break; + case RETRO_DEVICE_GRAPHIC_BOARD: + input.system[port] = SYSTEM_GRAPHIC_BOARD; + break; case RETRO_DEVICE_JOYPAD: default: config.input[port*4].padtype = DEVICE_PAD2B | DEVICE_PAD6B | DEVICE_PAD3B; diff --git a/sdl/Makefile b/sdl/Makefile index 3dbce0c..6134e52 100644 --- a/sdl/Makefile +++ b/sdl/Makefile @@ -50,16 +50,17 @@ OBJECTS += $(OBJDIR)/genesis.o \ $(OBJDIR)/state.o \ $(OBJDIR)/loadrom.o -OBJECTS += $(OBJDIR)/input.o \ - $(OBJDIR)/gamepad.o \ - $(OBJDIR)/lightgun.o \ - $(OBJDIR)/mouse.o \ - $(OBJDIR)/activator.o \ - $(OBJDIR)/xe_1ap.o \ - $(OBJDIR)/teamplayer.o \ - $(OBJDIR)/paddle.o \ - $(OBJDIR)/sportspad.o \ - $(OBJDIR)/terebi_oekaki.o +OBJECTS += $(OBJDIR)/input.o \ + $(OBJDIR)/gamepad.o \ + $(OBJDIR)/lightgun.o \ + $(OBJDIR)/mouse.o \ + $(OBJDIR)/activator.o \ + $(OBJDIR)/xe_1ap.o \ + $(OBJDIR)/teamplayer.o \ + $(OBJDIR)/paddle.o \ + $(OBJDIR)/sportspad.o \ + $(OBJDIR)/terebi_oekaki.o \ + $(OBJDIR)/graphic_board.o OBJECTS += $(OBJDIR)/sound.o \ $(OBJDIR)/sn76489.o \ diff --git a/sdl/main.c b/sdl/main.c index de77218..ff68004 100644 --- a/sdl/main.c +++ b/sdl/main.c @@ -649,6 +649,24 @@ int sdl_input_update(void) break; } + case DEVICE_GRAPHIC_BOARD: + { + /* get mouse (absolute values) */ + int x,y; + int state = SDL_GetMouseState(&x,&y); + + /* Calculate X Y axis values */ + input.analog[0][0] = (x * 255) / VIDEO_WIDTH; + input.analog[0][1] = (y * 255) / VIDEO_HEIGHT; + + /* Map mouse buttons to player #1 inputs */ + if(state & SDL_BUTTON_LMASK) input.pad[0] |= INPUT_GRAPHIC_PEN; + if(state & SDL_BUTTON_RMASK) input.pad[0] |= INPUT_GRAPHIC_MENU; + if(state & SDL_BUTTON_MMASK) input.pad[0] |= INPUT_GRAPHIC_DO; + + break; + } + case DEVICE_ACTIVATOR: { if(keystate[SDLK_g]) input.pad[joynum] |= INPUT_ACTIVATOR_7L;