diff -Nru base0120/src/emu/emu.mak w0120/src/emu/emu.mak --- base0120/src/emu/emu.mak 2007-10-15 19:58:53.000000000 +1300 +++ w0120/src/emu/emu.mak 2007-10-16 01:00:34.000000000 +1300 @@ -75,6 +75,7 @@ $(EMUOBJ)/uitext.o \ $(EMUOBJ)/validity.o \ $(EMUOBJ)/video.o \ + $(EMUOBJ)/inpview.o \ ifdef PROFILER EMUOBJS += \ diff -Nru base0120/src/emu/emuopts.c w0120/src/emu/emuopts.c --- base0120/src/emu/emuopts.c 2007-09-11 18:16:58.000000000 +1200 +++ w0120/src/emu/emuopts.c 2007-10-16 00:58:01.000000000 +1300 @@ -156,6 +156,8 @@ { "bios", "default", 0, "select the system BIOS to use" }, { "cheat;c", "0", OPTION_BOOLEAN, "enable cheat subsystem" }, { "skip_gameinfo", "0", OPTION_BOOLEAN, "skip displaying the information screen at startup" }, + { "inpview;iv", "0", 0, "enable input viewer" }, + { "inplayout;il", "standard", 0, "set input viewer layout type" }, { NULL } }; diff -Nru base0120/src/emu/inptport.c w0120/src/emu/inptport.c --- base0120/src/emu/inptport.c 2007-09-29 15:57:09.000000000 +1200 +++ w0120/src/emu/inptport.c 2007-10-16 00:58:01.000000000 +1300 @@ -106,6 +106,7 @@ #include "inputx.h" #endif +#include "inpview.h" /*************************************************************************** CONSTANTS @@ -1140,6 +1141,9 @@ /* register callbacks for when we load configurations */ config_register("input", input_port_load, input_port_save); + /* INPVIEW: initialise -inpview and -inplayout options */ + inpview_set_data(options_get_int(mame_options(),"inpview"),options_get_string(mame_options(),"inplayout")); + /* open playback and record files if specified */ setup_playback(machine); setup_record(machine); @@ -3599,3 +3603,30 @@ break; } } + +int input_port_used(int type,int player) +{ + int portnum, bitnum; + + /* loop over all input ports */ + for (portnum = 0; portnum < MAX_INPUT_PORTS; portnum++) + { + input_port_info *portinfo = &port_info[portnum]; + input_bit_info *info; + unsigned long portvalue; + + for (bitnum = 0, info = &portinfo->bit[0]; bitnum < MAX_BITS_PER_PORT && info->port; bitnum++, info++) + { + portvalue = portinfo->playback; + + if(info->port->type == type && info->port->player == player) + { + if((info->port->type == type) && (portvalue & info->port->mask) != (info->port->default_value & info->port->mask)) + return 1; + else + return 0; + } + } + } + return 0; +} diff -Nru base0120/src/emu/inptport.h w0120/src/emu/inptport.h --- base0120/src/emu/inptport.h 2007-09-29 15:57:09.000000000 +1200 +++ w0120/src/emu/inptport.h 2007-10-16 00:58:01.000000000 +1300 @@ -899,4 +899,6 @@ UINT32 readinputportbytag(const char *tag); UINT32 readinputportbytag_safe(const char *tag, UINT32 defvalue); +int input_port_used(int, int); + #endif /* __INPTPORT_H__ */ diff -Nru base0120/src/emu/inpview.c w0120/src/emu/inpview.c --- base0120/src/emu/inpview.c 1970-01-01 13:00:00.000000000 +1300 +++ w0120/src/emu/inpview.c 2007-10-16 00:58:01.000000000 +1300 @@ -0,0 +1,258 @@ +// Input viewer module for MAME +// Complete re-write started Aug 23, 2006 + +#include +#include "ui.h" +#include "uitext.h" +#include "inptport.h" +#include "render.h" +#include "inpview.h" + +#define CHAR_WIDTH (1.0f / 80.0f) +#define INPUT_TYPES 5 + +#define COL_RED MAKE_ARGB(0xff, 0xff, 0x00, 0x00) +#define COL_BLUE MAKE_ARGB(0xff, 0x00, 0x00, 0xff) +#define COL_GREEN MAKE_ARGB(0xff, 0x00, 0xff, 0x00) +#define COL_YELLOW MAKE_ARGB(0xff, 0xff, 0xff, 0x00) +#define COL_ORANGE MAKE_ARGB(0xff, 0xff, 0x80, 0x00) +#define COL_BLACK MAKE_ARGB(0xff, 0x00, 0x00, 0x00) +#define COL_GRAY MAKE_ARGB(0xff, 0x80, 0x80, 0x80) +#define COL_WHITE MAKE_ARGB(0xff, 0xff, 0xff, 0xff) + +#define BGCOL MAKE_ARGB(0x80, 0x80, 0x00, 0x00) + +// uncomment if you plan to use MAME's built-in font +//#define OLD_UI_FONT 1 + +#ifndef OLD_UI_FONT +#define DIR_LEFT 0x2190 +#define DIR_UP 0x2191 +#define DIR_RIGHT 0x2192 +#define DIR_DOWN 0x2193 +#else +#define DIR_LEFT 'L' +#define DIR_UP 'U' +#define DIR_RIGHT 'R' +#define DIR_DOWN 'D' +#endif + +struct input_type_definition inptype[INPUT_TYPES] = +{ + { + "standard", + 1, + { + {"1P", IPT_START1, 1, 50, 0, 0, COL_WHITE}, + {"2P", IPT_START2, 1, 53, 0, 0, COL_WHITE}, + {"3P", IPT_START3, 1, 56, 0, 0, COL_WHITE}, + {"4P", IPT_START4, 1, 59, 0, 0, COL_WHITE}, + {"5P", IPT_START5, 1, 62, 0, 0, COL_WHITE}, + {"6P", IPT_START6, 1, 65, 0, 0, COL_WHITE}, + {"7P", IPT_START7, 1, 68, 0, 0, COL_WHITE}, + {"8P", IPT_START8, 1, 71, 0, 0, COL_WHITE}, + {"1", IPT_BUTTON1, 1, 20, 0, 1, COL_WHITE}, + {"2", IPT_BUTTON2, 1, 22, 0, 1, COL_WHITE}, + {"3", IPT_BUTTON3, 1, 24, 0, 1, COL_WHITE}, + {"4", IPT_BUTTON4, 1, 26, 0, 1, COL_WHITE}, + {"5", IPT_BUTTON5, 1, 28, 0, 1, COL_WHITE}, + {"6", IPT_BUTTON6, 1, 30, 0, 1, COL_WHITE}, + {"7", IPT_BUTTON7, 1, 32, 0, 1, COL_WHITE}, + {"8", IPT_BUTTON8, 1, 34, 0, 1, COL_WHITE}, + {"9", IPT_BUTTON9, 1, 36, 0, 1, COL_WHITE}, + {"0", IPT_BUTTON10, 1, 38, 0, 1, COL_WHITE}, + {"_L", IPT_JOYSTICK_LEFT, 1, 10, 0, 1, COL_WHITE}, + {"_R", IPT_JOYSTICK_RIGHT, 1, 12, 0, 1, COL_WHITE}, + {"_U", IPT_JOYSTICK_UP, 1, 14, 0, 1, COL_WHITE}, + {"_D", IPT_JOYSTICK_DOWN, 1, 16, 0, 1, COL_WHITE}, + {"NULL", -1, 0,0,0,0,0} + } + }, + { + "mahjong", + 2, + { + {"1P", IPT_START1, 1, 50, 0, 0, COL_WHITE}, + {"2P", IPT_START2, 1, 53, 0, 0, COL_WHITE}, + {"3P", IPT_START3, 1, 56, 0, 0, COL_WHITE}, + {"4P", IPT_START4, 1, 59, 0, 0, COL_WHITE}, + {"5P", IPT_START5, 1, 62, 0, 0, COL_WHITE}, + {"6P", IPT_START6, 1, 65, 0, 0, COL_WHITE}, + {"7P", IPT_START7, 1, 68, 0, 0, COL_WHITE}, + {"8P", IPT_START8, 1, 71, 0, 0, COL_WHITE}, + {"A", IPT_MAHJONG_A, 1, 10, 0, 1, COL_WHITE}, + {"B", IPT_MAHJONG_B, 1, 12, 0, 1, COL_WHITE}, + {"C", IPT_MAHJONG_C, 1, 14, 0, 1, COL_WHITE}, + {"D", IPT_MAHJONG_D, 1, 16, 0, 1, COL_WHITE}, + {"E", IPT_MAHJONG_E, 1, 18, 0, 1, COL_WHITE}, + {"F", IPT_MAHJONG_F, 1, 20, 0, 1, COL_WHITE}, + {"G", IPT_MAHJONG_G, 1, 22, 0, 1, COL_WHITE}, + {"H", IPT_MAHJONG_H, 1, 24, 0, 1, COL_WHITE}, + {"I", IPT_MAHJONG_I, 1, 26, 0, 1, COL_WHITE}, + {"J", IPT_MAHJONG_J, 1, 28, 0, 1, COL_WHITE}, + {"K", IPT_MAHJONG_K, 1, 30, 0, 1, COL_WHITE}, + {"L", IPT_MAHJONG_L, 1, 32, 0, 1, COL_WHITE}, + {"M", IPT_MAHJONG_M, 1, 34, 0, 1, COL_WHITE}, + {"N", IPT_MAHJONG_N, 1, 36, 0, 1, COL_WHITE}, + {"O", IPT_MAHJONG_O, 1, 38, 0, 1, COL_WHITE}, + {"P", IPT_MAHJONG_P, 1, 40, 0, 1, COL_WHITE}, + {"Q", IPT_MAHJONG_Q, 1, 42, 0, 1, COL_WHITE}, + {"REACH", IPT_MAHJONG_REACH, 2, 14, 0, 1, COL_WHITE}, + {"CHI", IPT_MAHJONG_CHI, 2, 26, 0, 1, COL_WHITE}, + {"PON", IPT_MAHJONG_PON, 2, 34, 0, 1, COL_WHITE}, + {"KAN", IPT_MAHJONG_KAN, 2, 42, 0, 1, COL_WHITE}, + {"RON", IPT_MAHJONG_RON, 2, 50, 0, 1, COL_WHITE}, + {"BET", IPT_MAHJONG_BET, 2, 58, 0, 1, COL_WHITE}, + {"NULL", -1, 0,0,0,0,0} + } + }, + { + "dualstick", + 1, + { + {"1P", IPT_START1, 1, 50, 0, 0, COL_WHITE}, + {"2P", IPT_START2, 1, 53, 0, 0, COL_WHITE}, + {"3P", IPT_START3, 1, 56, 0, 0, COL_WHITE}, + {"4P", IPT_START4, 1, 59, 0, 0, COL_WHITE}, + {"5P", IPT_START5, 1, 62, 0, 0, COL_WHITE}, + {"6P", IPT_START6, 1, 65, 0, 0, COL_WHITE}, + {"7P", IPT_START7, 1, 68, 0, 0, COL_WHITE}, + {"8P", IPT_START8, 1, 71, 0, 0, COL_WHITE}, + {"1", IPT_BUTTON1, 1, 30, 0, 1, COL_WHITE}, + {"2", IPT_BUTTON2, 1, 32, 0, 1, COL_WHITE}, + {"3", IPT_BUTTON3, 1, 34, 0, 1, COL_WHITE}, + {"4", IPT_BUTTON4, 1, 36, 0, 1, COL_WHITE}, + {"5", IPT_BUTTON5, 1, 38, 0, 1, COL_WHITE}, + {"6", IPT_BUTTON6, 1, 40, 0, 1, COL_WHITE}, + {"7", IPT_BUTTON7, 1, 42, 0, 1, COL_WHITE}, + {"8", IPT_BUTTON8, 1, 44, 0, 1, COL_WHITE}, + {"9", IPT_BUTTON9, 1, 46, 0, 1, COL_WHITE}, + {"0", IPT_BUTTON10, 1, 48, 0, 1, COL_WHITE}, + {"_L", IPT_JOYSTICKLEFT_LEFT, 1, 6, 0, 1, COL_WHITE}, + {"_R", IPT_JOYSTICKLEFT_RIGHT, 1, 8, 0, 1, COL_WHITE}, + {"_U", IPT_JOYSTICKLEFT_UP, 1, 10, 0, 1, COL_WHITE}, + {"_D", IPT_JOYSTICKLEFT_DOWN, 1, 12, 0, 1, COL_WHITE}, + {"_L", IPT_JOYSTICKRIGHT_LEFT, 1, 18, 0, 1, COL_WHITE}, + {"_R", IPT_JOYSTICKRIGHT_RIGHT, 1, 20, 0, 1, COL_WHITE}, + {"_U", IPT_JOYSTICKRIGHT_UP, 1, 22, 0, 1, COL_WHITE}, + {"_D", IPT_JOYSTICKRIGHT_DOWN, 1, 24, 0, 1, COL_WHITE}, + {"NULL", -1, 0,0,0,0,0} + } + }, + { + "neogeo", + 2, + { + {"1P", IPT_START1, 2, 53, 0, 0, COL_YELLOW}, + {"2P", IPT_START2, 1, 53, 0, 0, COL_YELLOW}, + {"A", IPT_BUTTON1, 1, 26, 0, 1, COL_RED}, + {"B", IPT_BUTTON2, 2, 29, 0, 1, COL_YELLOW}, + {"C", IPT_BUTTON3, 2, 32, 0, 1, COL_GREEN}, + {"D", IPT_BUTTON4, 1, 35, 0, 1, COL_BLUE}, + {"_L", IPT_JOYSTICK_LEFT, 1, 15, 0, 1, COL_WHITE}, + {"_R", IPT_JOYSTICK_RIGHT, 1, 19, 0, 1, COL_WHITE}, + {"_U", IPT_JOYSTICK_UP, 2, 17, 0, 1, COL_WHITE}, + {"_D", IPT_JOYSTICK_DOWN, 1, 17, 0, 1, COL_WHITE}, + {"NULL", -1, 0,0,0,0,0} + } + }, + { + "6button", + 2, + { + {"1P", IPT_START1, 2, 53, 0, 0, COL_YELLOW}, + {"2P", IPT_START2, 1, 53, 0, 0, COL_YELLOW}, + {"1", IPT_BUTTON1, 2, 30, 0, 1, COL_WHITE}, + {"2", IPT_BUTTON2, 2, 33, 0, 1, COL_WHITE}, + {"3", IPT_BUTTON3, 2, 36, 0, 1, COL_WHITE}, + {"4", IPT_BUTTON4, 1, 30, 0, 1, COL_WHITE}, + {"5", IPT_BUTTON5, 1, 33, 0, 1, COL_WHITE}, + {"6", IPT_BUTTON6, 1, 36, 0, 1, COL_WHITE}, + {"_L", IPT_JOYSTICK_LEFT, 1, 15, 0, 1, COL_WHITE}, + {"_R", IPT_JOYSTICK_RIGHT, 1, 19, 0, 1, COL_WHITE}, + {"_U", IPT_JOYSTICK_UP, 2, 17, 0, 1, COL_WHITE}, + {"_D", IPT_JOYSTICK_DOWN, 1, 17, 0, 1, COL_WHITE}, + {"NULL", -1, 0,0,0,0,0} + } + } +}; + +int player; +int layout; + +void render_input() +{ + int port = 0; + char txt[6]; + float height = ui_get_line_height(); + + if(player < 1 || player > 8) + return; // invalid player + + render_ui_add_rect(0.0f,1.0f-(float)(inptype[layout].lines*height),1.0f,1.0f,BGCOL,PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + while(inptype[layout].inp[port].port != -1) + { + strcpy(txt,inptype[layout].inp[port].text); + + if(inptype[layout].inp[port].playerspecific == 0) + { + if(input_port_used(inptype[layout].inp[port].port,0) != 0) + { + int ch = convert_txt(txt); + int col = inptype[layout].inp[port].colour; + if(ch == 0) + ui_draw_text_full(txt,(float)(inptype[layout].inp[port].x * CHAR_WIDTH),1.0f - (float)(height * inptype[layout].inp[port].line),1.0f,JUSTIFY_LEFT,WRAP_NEVER,DRAW_OPAQUE,col,0,NULL,NULL); + else + render_ui_add_char((float)(inptype[layout].inp[port].x * CHAR_WIDTH),1.0f - (float)(height * inptype[layout].inp[port].line),height,render_get_ui_aspect(),col,ui_get_font(),ch); + } + } + else + { + if(input_port_used(inptype[layout].inp[port].port,player-1) != 0) + { + int ch = convert_txt(txt); + int col = inptype[layout].inp[port].colour; + if(ch == 0) + ui_draw_text_full(txt,(float)(inptype[layout].inp[port].x * CHAR_WIDTH),1.0f - (float)(height * inptype[layout].inp[port].line),1.0f,JUSTIFY_LEFT,WRAP_NEVER,DRAW_OPAQUE,col,0,NULL,NULL); + else + render_ui_add_char((float)(inptype[layout].inp[port].x * CHAR_WIDTH),1.0f - (float)(height * inptype[layout].inp[port].line),height,render_get_ui_aspect(),col,ui_get_font(),ch); + } + } + port++; + } +} + +void inpview_set_data(int ply, const char* lay) +{ + player = ply; + layout = 0; + while(layout < INPUT_TYPES) + { + if(strcmp(inptype[layout].name,lay) == 0) + { + printf("INPVIEW: using layout type '%s'\n",lay); + return; + } + layout++; + } + printf("INPVIEW: invalid type specified, standard layout in use\n"); + layout = 0; +} + +int inpview_get_player() +{ + return player; +} + +unsigned int convert_txt(char* txt) +{ + if(strcmp(txt,"_L") == 0) + return DIR_LEFT; + if(strcmp(txt,"_R") == 0) + return DIR_RIGHT; + if(strcmp(txt,"_U") == 0) + return DIR_UP; + if(strcmp(txt,"_D") == 0) + return DIR_DOWN; + return 0; +} diff -Nru base0120/src/emu/inpview.h w0120/src/emu/inpview.h --- base0120/src/emu/inpview.h 1970-01-01 13:00:00.000000000 +1300 +++ w0120/src/emu/inpview.h 2007-10-16 00:58:01.000000000 +1300 @@ -0,0 +1,24 @@ +// Input viewer header + +struct inputs +{ + char text[6]; // character(s) to display + int port; // port to check + int line; // line to display on + int x; // location on line to display at + char isanalogue; // non-zero if the input is analogue + char playerspecific; // is a player specific port (if 0, then player should be 0 too) + unsigned long colour; +}; + +struct input_type_definition +{ + char name[13]; // NULL-terminated string to identify different type using a possible -inplayout option + int lines; // number of lines to use for this type + struct inputs inp[64]; // list of displayed buttons, and the inputs they correspond to (64 max) +}; + +void render_input(void); +void inpview_set_data(int,const char*); +int inpview_get_player(void); +unsigned int convert_txt(char*); diff -Nru base0120/src/emu/ui.c w0120/src/emu/ui.c --- base0120/src/emu/ui.c 2007-09-07 04:42:07.000000000 +1200 +++ w0120/src/emu/ui.c 2007-10-16 00:58:01.000000000 +1300 @@ -31,7 +31,7 @@ #include #include - +#include "inpview.h" /*************************************************************************** CONSTANTS @@ -452,6 +452,10 @@ /* let MESS display its stuff */ mess_ui_update(); #endif + + // Input viewer + if(Machine->playback_file && inpview_get_player() != 0) + render_input(); }