diff --git a/controls.cpp b/controls.cpp index 65d2b337..8c71090a 100644 --- a/controls.cpp +++ b/controls.cpp @@ -227,7 +227,8 @@ using namespace std; #define SUPERSCOPE 10 #define ONE_JUSTIFIER 11 #define TWO_JUSTIFIERS 12 -#define NUMCTLS 13 // This must be LAST +#define MACSRIFLE 13 +#define NUMCTLS 14 // This must be LAST #define POLL_ALL NUMCTLS @@ -241,6 +242,8 @@ using namespace std; #define JUSTIFIER_START 0x20 #define JUSTIFIER_SELECT 0x08 +#define MACSRIFLE_TRIGGER 0x01 + #define MAP_UNKNOWN (-1) #define MAP_NONE 0 #define MAP_BUTTON 1 @@ -321,6 +324,14 @@ static struct int8 pads[4]; } mp5[2]; +static struct +{ + int16 x, y; + uint8 buttons; + uint32 ID; + struct crosshair crosshair; +} macsrifle; + static set exemultis; static set pollmap[NUMCTLS + 1]; static map keymap; @@ -466,6 +477,7 @@ static const char *command_names[LAST_COMMAND + 1] = static void DisplayStateChange (const char *, bool8); static void DoGunLatch (int, int); +static void DoMacsRifleLatch (int, int); static int maptype (int); static bool strless (const char *, const char *); static int findstr (const char *, const char **, int); @@ -516,6 +528,12 @@ static void DoGunLatch (int x, int y) PPU.GunHLatch = (uint16) x; } +static void DoMacsRifleLatch (int x, int y) +{ + PPU.GunVLatch = (uint16) (y + 42);// + (int16) macsrifle.adjust_y; + PPU.GunHLatch = (uint16) (x + 76);// + (int16) macsrifle.adjust_x; +} + static int maptype (int t) { switch (t) @@ -527,6 +545,7 @@ static int maptype (int t) case S9xButtonMouse: case S9xButtonSuperscope: case S9xButtonJustifier: + case S9xButtonMacsRifle: case S9xButtonCommand: case S9xButtonPseudopointer: case S9xButtonPort: @@ -554,6 +573,7 @@ void S9xControlsReset (void) mouse[0].buttons &= ~0x30; mouse[1].buttons &= ~0x30; justifier.buttons &= ~JUSTIFIER_SELECT; + macsrifle.buttons = 0; } void S9xControlsSoftReset (void) @@ -641,6 +661,17 @@ void S9xUnmapAllControls (void) if (!(superscope.crosshair.set & 4)) superscope.crosshair.bg = 1; + macsrifle.x = macsrifle.y = 0; + macsrifle.buttons = 0; + macsrifle.ID = InvalidControlID; + + if (!(macsrifle.crosshair.set & 1)) + macsrifle.crosshair.img = 2; + if (!(macsrifle.crosshair.set & 2)) + macsrifle.crosshair.fg = 5; + if (!(macsrifle.crosshair.set & 4)) + macsrifle.crosshair.bg = 1; + memset(pseudobuttons, 0, sizeof(pseudobuttons)); turbo_time = 1; @@ -697,6 +728,16 @@ void S9xSetController (int port, enum controllers controller, int8 id1, int8 id2 newcontrollers[port] = ONE_JUSTIFIER + id1; return; + case CTL_MACSRIFLE: + if (!Settings.MacsRifleMaster) + { + S9xMessage(S9X_CONFIG_INFO, S9X_ERROR, "Cannot select SNES M.A.C.S. Rifle: MacsRifleMaster disabled"); + break; + } + + newcontrollers[port] = MACSRIFLE; + return; + case CTL_MP5: if (id1 < -1 || id1 > 7) break; @@ -800,6 +841,26 @@ bool S9xVerifyControllers (void) break; + case MACSRIFLE: + if (!Settings.MacsRifleMaster) + { + S9xMessage(S9X_CONFIG_INFO, S9X_ERROR, "Cannot select SNES M.A.C.S. Rifle: MacsRifleMaster disabled"); + newcontrollers[port] = NONE; + ret = true; + break; + } + + if (used[i]++ > 0) + { + snprintf(buf, sizeof(buf), "M.A.C.S. Rifle used more than once! Disabling extra instances"); + S9xMessage(S9X_CONFIG_INFO, S9X_ERROR, buf); + newcontrollers[port] = NONE; + ret = true; + break; + } + + break; + case MP5: if (!Settings.MultiPlayer5Master) { @@ -901,6 +962,11 @@ void S9xGetController (int port, enum controllers *controller, int8 *id1, int8 * *controller = CTL_JUSTIFIER; *id1 = i - ONE_JUSTIFIER; return; + + case MACSRIFLE: + *controller = CTL_MACSRIFLE; + *id1 = 1; + return; } } @@ -969,6 +1035,13 @@ void S9xReportControllers (void) else c += sprintf(c, "Blue and Pink Justifiers. "); break; + + case MACSRIFLE: + if (port == 0) + c += sprintf(c, "M.A.C.S. Rifle (cannot fire). "); + else + c += sprintf(c, "M.A.C.S. Rifle. "); + break; } } @@ -1056,6 +1129,17 @@ char * S9xGetCommandName (s9xcommand_t command) break; + case S9xButtonMacsRifle: + if (!command.button.macsrifle.trigger) + return (strdup("None")); + + s = "MacsRifle"; + + c = ' '; + if (command.button.macsrifle.trigger) { s += c; s += "Trigger"; c = '+'; } + + break; + case S9xButtonCommand: if (command.button.command >= LAST_COMMAND) return (strdup("None")); @@ -1063,7 +1147,7 @@ char * S9xGetCommandName (s9xcommand_t command) return (strdup(command_names[command.button.command])); case S9xPointer: - if (!command.pointer.aim_mouse0 && !command.pointer.aim_mouse1 && !command.pointer.aim_scope && !command.pointer.aim_justifier0 && !command.pointer.aim_justifier1) + if (!command.pointer.aim_mouse0 && !command.pointer.aim_mouse1 && !command.pointer.aim_scope && !command.pointer.aim_justifier0 && !command.pointer.aim_justifier1 && !command.pointer.aim_macsrifle) return (strdup("None")); s = "Pointer"; @@ -1074,6 +1158,7 @@ char * S9xGetCommandName (s9xcommand_t command) if (command.pointer.aim_scope ) { s += c; s += "Superscope"; c = '+'; } if (command.pointer.aim_justifier0) { s += c; s += "Justifier1"; c = '+'; } if (command.pointer.aim_justifier1) { s += c; s += "Justifier2"; c = '+'; } + if (command.pointer.aim_macsrifle) { s += c; s += "MacsRifle"; c = '+'; } break; @@ -1407,6 +1492,19 @@ s9xcommand_t S9xGetCommandT (const char *name) cmd.type = S9xButtonJustifier; } else + if (!strncmp(name, "MacsRifle ", 10)) + { + s = name + 10; + i = 0; + + if ((cmd.button.macsrifle.trigger = strncmp(s, "Trigger", 7) ? 0 : 1)) { s += i = 7; } + + if (i == 0 || *s != 0 || *(s - 1) == '+') + return (cmd); + + cmd.type = S9xButtonMacsRifle; + } + else if (!strncmp(name, "Pointer ", 8)) { s = name + 8; @@ -1416,7 +1514,8 @@ s9xcommand_t S9xGetCommandT (const char *name) if ((cmd.pointer.aim_mouse1 = strncmp(s, "Mouse2", 6) ? 0 : 1)) { s += i = 6; if (*s == '+') s++; } if ((cmd.pointer.aim_scope = strncmp(s, "Superscope", 10) ? 0 : 1)) { s += i = 10; if (*s == '+') s++; } if ((cmd.pointer.aim_justifier0 = strncmp(s, "Justifier1", 10) ? 0 : 1)) { s += i = 10; if (*s == '+') s++; } - if ((cmd.pointer.aim_justifier1 = strncmp(s, "Justifier2", 10) ? 0 : 1)) { s += i = 10; } + if ((cmd.pointer.aim_justifier1 = strncmp(s, "Justifier2", 10) ? 0 : 1)) { s += i = 10; if (*s == '+') s++; } + if ((cmd.pointer.aim_macsrifle = strncmp(s, "MacsRifle", 9) ? 0 : 1)) { s += i = 9; } if (i == 0 || *s != 0 || *(s - 1) == '+') return (cmd); @@ -1717,6 +1816,7 @@ void S9xUnmapID (uint32 id) if (superscope.ID == id) superscope.ID = InvalidControlID; if (justifier.ID[0] == id) justifier.ID[0] = InvalidControlID; if (justifier.ID[1] == id) justifier.ID[1] = InvalidControlID; + if (macsrifle.ID == id) macsrifle.ID = InvalidControlID; if (id >= PseudoPointerBase) pseudopointer[id - PseudoPointerBase].mapped = false; @@ -1782,6 +1882,10 @@ bool S9xMapButton (uint32 id, s9xcommand_t mapping, bool poll) t = ONE_JUSTIFIER + mapping.button.justifier.idx; break; + case S9xButtonMacsRifle: + t = MACSRIFLE; + break; + case S9xButtonCommand: case S9xButtonPseudopointer: case S9xButtonPort: @@ -1888,6 +1992,12 @@ bool S9xMapPointer (uint32 id, s9xcommand_t mapping, bool poll) fprintf(stderr, "ERROR: Rejecting attempt to control Justifier2 with two pointers\n"); return (false); } + + if (mapping.pointer.aim_macsrifle && macsrifle.ID != InvalidControlID && macsrifle.ID != id) + { + fprintf(stderr, "ERROR: Rejecting attempt to control M.A.C.S. Rifle with two pointers\n"); + return (false); + } } S9xUnmapID(id); @@ -1906,6 +2016,7 @@ bool S9xMapPointer (uint32 id, s9xcommand_t mapping, bool poll) if (mapping.pointer.aim_scope ) pollmap[SUPERSCOPE ].insert(id); if (mapping.pointer.aim_justifier0) pollmap[ONE_JUSTIFIER ].insert(id); if (mapping.pointer.aim_justifier1) pollmap[TWO_JUSTIFIERS].insert(id); + if (mapping.pointer.aim_macsrifle ) pollmap[MACSRIFLE ].insert(id); break; case S9xPointerPort: @@ -1925,6 +2036,7 @@ bool S9xMapPointer (uint32 id, s9xcommand_t mapping, bool poll) if (mapping.pointer.aim_scope ) superscope.ID = id; if (mapping.pointer.aim_justifier0) justifier.ID[0] = id; if (mapping.pointer.aim_justifier1) justifier.ID[1] = id; + if (mapping.pointer.aim_macsrifle ) macsrifle.ID = id; return (true); } @@ -2193,6 +2305,17 @@ void S9xApplyCommand (s9xcommand_t cmd, int16 data1, int16 data2) return; + case S9xButtonMacsRifle: + i = 0; + if (cmd.button.macsrifle.trigger) i |= MACSRIFLE_TRIGGER; + + if(data1) + macsrifle.buttons |= i; + else + macsrifle.buttons &= ~i; + + return; + case S9xButtonCommand: if (((enum command_numbers) cmd.button.command) >= LAST_COMMAND) { @@ -2588,6 +2711,12 @@ void S9xApplyCommand (s9xcommand_t cmd, int16 data1, int16 data2) justifier.y[1] = data2; } + if (cmd.pointer.aim_macsrifle) + { + macsrifle.x = data1; + macsrifle.y = data2; + } + return; case S9xButtonPseudopointer: @@ -2943,6 +3072,10 @@ void S9xSetJoypadLatch (bool latch) do_polling(ONE_JUSTIFIER); break; + case MACSRIFLE: + do_polling(i); + break; + default: break; } @@ -2993,6 +3126,10 @@ uint8 S9xReadJOYSERn (int n) case TWO_JUSTIFIERS: return (bits); + case MACSRIFLE: + do_polling(i); + return (bits | ((macsrifle.buttons & 0x01) ? 1 : 0)); + default: return (bits); } @@ -3088,6 +3225,10 @@ uint8 S9xReadJOYSERn (int n) return (bits | 1); } + case MACSRIFLE: + do_polling(i); + return (bits | ((macsrifle.buttons & 0x01) ? 1 : 0)); + default: read_idx[n][0]++; return (bits); @@ -3155,6 +3296,13 @@ void S9xDoAutoJoypad (void) WRITE_WORD(Memory.FillRAM + 0x421c + n * 2, 0); break; + case MACSRIFLE: + read_idx[n][0] = 16; + Memory.FillRAM[0x4218 + n * 2] = 0xff; + Memory.FillRAM[0x4219 + n * 2] = macsrifle.buttons; + WRITE_WORD(Memory.FillRAM + 0x421c + n * 2, 0); + break; + default: WRITE_WORD(Memory.FillRAM + 0x4218 + n * 2, 0); WRITE_WORD(Memory.FillRAM + 0x421c + n * 2, 0); @@ -3257,6 +3405,18 @@ void S9xControlEOF (void) break; + case MACSRIFLE: + if (n == 1) + { + DoMacsRifleLatch(macsrifle.x, macsrifle.y); + + c = &macsrifle.crosshair; + if (IPPU.RenderThisFrame) + S9xDrawCrosshair(S9xGetCrosshair(c->img), c->fg, c->bg, macsrifle.x, macsrifle.y); + } + + break; + default: break; } @@ -3362,6 +3522,7 @@ void S9xSetControllerCrosshair (enum crosscontrols ctl, int8 idx, const char *fg case X_SUPERSCOPE: c = &superscope.crosshair; break; case X_JUSTIFIER1: c = &justifier.crosshair[0]; break; case X_JUSTIFIER2: c = &justifier.crosshair[1]; break; + case X_MACSRIFLE: c = &macsrifle.crosshair; break; default: fprintf(stderr, "S9xSetControllerCrosshair() called with an invalid controller ID %d\n", ctl); return; @@ -3453,6 +3614,7 @@ void S9xGetControllerCrosshair (enum crosscontrols ctl, int8 *idx, const char ** case X_SUPERSCOPE: c = &superscope.crosshair; break; case X_JUSTIFIER1: c = &justifier.crosshair[0]; break; case X_JUSTIFIER2: c = &justifier.crosshair[1]; break; + case X_MACSRIFLE: c = &macsrifle.crosshair; break; default: fprintf(stderr, "S9xGetControllerCrosshair() called with an invalid controller ID %d\n", ctl); return; @@ -3471,7 +3633,7 @@ void S9xGetControllerCrosshair (enum crosscontrols ctl, int8 *idx, const char ** void S9xControlPreSaveState (struct SControlSnapshot *s) { memset(s, 0, sizeof(*s)); - s->ver = 3; + s->ver = 4; for (int j = 0; j < 2; j++) { @@ -3520,6 +3682,10 @@ void S9xControlPreSaveState (struct SControlSnapshot *s) for (int k = 0; k < 2; k++) COPY(mp5[j].pads[k]); + COPY(macsrifle.x); + COPY(macsrifle.y); + COPY(macsrifle.buttons); + assert(i == sizeof(s->internal)); #undef COPY @@ -3591,7 +3757,14 @@ void S9xControlPostLoadState (struct SControlSnapshot *s) for (int k = 0; k < 2; k++) COPY(mp5[j].pads[k]); - assert(i == sizeof(s->internal)); + if (s->ver > 3) + { + COPY(macsrifle.x); + COPY(macsrifle.y); + COPY(macsrifle.buttons); + + assert(i == sizeof(s->internal)); + } #undef COPY } @@ -3711,3 +3884,30 @@ void MovieSetJustifier (int i, uint8 in[11]) justifier.offscreen[0] = *ptr++; justifier.offscreen[1] = *ptr; } + +bool MovieGetMacsRifle (int i, uint8 out[5]) +{ + if (i < 0 || i > 1 || curcontrollers[i] != MACSRIFLE) + return (false); + + uint8 *ptr = out; + + WRITE_WORD(ptr, macsrifle.x); ptr += 2; + WRITE_WORD(ptr, macsrifle.y); ptr += 2; + *ptr = macsrifle.buttons; + + return (true); +} + +void MovieSetMacsRifle (int i, uint8 in[5]) +{ + if (i < 0 || i > 1 || curcontrollers[i] != MACSRIFLE) + return; + + uint8 *ptr = in; + + macsrifle.x = READ_WORD(ptr); ptr += 2; + macsrifle.y = READ_WORD(ptr); ptr += 2; + macsrifle.buttons = *ptr; +} + diff --git a/controls.h b/controls.h index 5834fc78..c254386d 100644 --- a/controls.h +++ b/controls.h @@ -200,8 +200,9 @@ #define S9xButtonJustifier 4 #define S9xButtonCommand 5 #define S9xButtonMulti 6 -#define S9xAxisJoypad 7 -#define S9xPointer 8 +#define S9xButtonMacsRifle 7 +#define S9xAxisJoypad 8 +#define S9xPointer 9 #define S9xButtonPseudopointer 254 #define S9xAxisPseudopointer 253 @@ -274,6 +275,11 @@ typedef struct uint8 aim_offscreen:1; // Pretend we're pointing the gun offscreen (ignore the pointer) } justifier; + struct + { + uint8 trigger:1; + } macsrifle; + int32 multi_idx; uint16 command; } button; @@ -311,6 +317,7 @@ typedef struct uint16 aim_scope:1; uint16 aim_justifier0:1; uint16 aim_justifier1:1; + uint16 aim_macsrifle:1; } pointer; uint8 port[4]; @@ -330,7 +337,8 @@ enum controllers CTL_MOUSE, // use id1 to specify 0-1 CTL_SUPERSCOPE, CTL_JUSTIFIER, // use id1: 0=one justifier, 1=two justifiers - CTL_MP5 // use id1-id4 to specify pad 0-7 (or -1) + CTL_MP5, // use id1-id4 to specify pad 0-7 (or -1) + CTL_MACSRIFLE }; void S9xSetController (int port, enum controllers controller, int8 id1, int8 id2, int8 id3, int8 id4); // port=0-1 @@ -459,7 +467,7 @@ struct SControlSnapshot uint8 justifier_select; uint8 dummy3[8]; bool8 pad_read, pad_read_last; - uint8 internal[60]; // yes, we need to save this! + uint8 internal[65]; // yes, we need to save this! }; void S9xControlPreSaveState (struct SControlSnapshot *s); diff --git a/crosshairs.h b/crosshairs.h index 2cbab76e..d5de8009 100644 --- a/crosshairs.h +++ b/crosshairs.h @@ -214,6 +214,7 @@ const char * S9xGetCrosshair (int idx); // Superscope: 2 White Black // Justifier 1: 4 Blue Black // Justifier 2: 4 MagicPink Black +// Macs Rifle: 2 White Black // // Available colors are: Trans, Black, 25Grey, 50Grey, 75Grey, White, Red, Orange, // Yellow, Green, Cyan, Sky, Blue, Violet, MagicPink, and Purple. @@ -226,7 +227,8 @@ enum crosscontrols X_MOUSE2, X_SUPERSCOPE, X_JUSTIFIER1, - X_JUSTIFIER2 + X_JUSTIFIER2, + X_MACSRIFLE }; void S9xSetControllerCrosshair (enum crosscontrols ctl, int8 idx, const char *fg, const char *bg); diff --git a/gfx.cpp b/gfx.cpp index df70a885..6f307cd6 100644 --- a/gfx.cpp +++ b/gfx.cpp @@ -2160,6 +2160,22 @@ static void DisplayPressedKeys (void) break; } + case CTL_MACSRIFLE: + { + /* + uint8 buf[6], *p = buf; + MovieGetScope(port, buf); + int16 x = READ_WORD(p); + int16 y = READ_WORD(p + 2); + uint8 buttons = buf[4]; + sprintf(string, "#%d %d: (%03d,%03d) %c%c%c%c", port, ids[0], x, y, + (buttons & 0x80) ? 'F' : ' ', (buttons & 0x40) ? 'C' : ' ', + (buttons & 0x20) ? 'T' : ' ', (buttons & 0x10) ? 'P' : ' '); + S9xDisplayString(string, line++, 1, false); + */ + break; + } + case CTL_NONE: { sprintf(string, "#%d -", port); diff --git a/snes9x.cpp b/snes9x.cpp index 5640da73..2826985d 100644 --- a/snes9x.cpp +++ b/snes9x.cpp @@ -241,6 +241,9 @@ static bool parse_controller_spec (int port, const char *arg) if (!strcasecmp(arg, "two-justifiers")) S9xSetController(port, CTL_JUSTIFIER, 1, 0, 0, 0); else + if (!strcasecmp(arg, "macsrifle")) + S9xSetController(port, CTL_MACSRIFLE, 0, 0, 0, 0); + else if (!strncasecmp(arg, "mp5:", 4) && ((arg[4] >= '1' && arg[4] <= '8') || arg[4] == 'n') && ((arg[5] >= '1' && arg[5] <= '8') || arg[5] == 'n') && ((arg[6] >= '1' && arg[6] <= '8') || arg[6] == 'n') && @@ -465,6 +468,7 @@ void S9xLoadConfigFiles (char **argv, int argc) Settings.MouseMaster = conf.GetBool("Controls::MouseMaster", true); Settings.SuperScopeMaster = conf.GetBool("Controls::SuperscopeMaster", true); Settings.JustifierMaster = conf.GetBool("Controls::JustifierMaster", true); + Settings.MacsRifleMaster = conf.GetBool("Controls::MacsRifleMaster", true); Settings.MultiPlayer5Master = conf.GetBool("Controls::MP5Master", true); Settings.UpAndDown = conf.GetBool("Controls::AllowLeftRight", false); @@ -483,6 +487,8 @@ void S9xLoadConfigFiles (char **argv, int argc) parse_crosshair_spec(X_JUSTIFIER1, conf.GetString("Controls::Justifier1Crosshair")); if (conf.Exists("Controls::Justifier2Crosshair")) parse_crosshair_spec(X_JUSTIFIER2, conf.GetString("Controls::Justifier2Crosshair")); + if (conf.Exists("Controls::MacsRifleCrosshair")) + parse_crosshair_spec(X_MACSRIFLE, conf.GetString("Controls::MacsRifleCrosshair")); // Hack Settings.SuperFXClockMultiplier = conf.GetUInt("Hack::SuperFXClockMultiplier", 100); @@ -557,6 +563,7 @@ void S9xUsage (void) S9xMessage(S9X_INFO, S9X_USAGE, "-nomouse Disable emulation of the SNES mouse"); S9xMessage(S9X_INFO, S9X_USAGE, "-nosuperscope Disable emulation of the Superscope"); S9xMessage(S9X_INFO, S9X_USAGE, "-nojustifier Disable emulation of the Konami Justifier"); + S9xMessage(S9X_INFO, S9X_USAGE, "-nomacsrifle Disable emulation of the M.A.C.S. Rifle"); S9xMessage(S9X_INFO, S9X_USAGE, "-port# Specify which controller to emulate in port 1/2"); S9xMessage(S9X_INFO, S9X_USAGE, " Controllers: none No controller"); S9xMessage(S9X_INFO, S9X_USAGE, " pad# Joypad number 1-8"); @@ -565,6 +572,7 @@ void S9xUsage (void) S9xMessage(S9X_INFO, S9X_USAGE, " justifier Blue Justifier (not useful with -port1)"); S9xMessage(S9X_INFO, S9X_USAGE, " two-justifiers Blue & Pink Justifiers"); S9xMessage(S9X_INFO, S9X_USAGE, " mp5:#### MP5 with the 4 named pads (1-8 or n)"); + S9xMessage(S9X_INFO, S9X_USAGE, " macsrifle M.A.C.S. Rifle"); S9xMessage(S9X_INFO, S9X_USAGE, ""); // ROM OPTIONS @@ -736,6 +744,9 @@ char * S9xParseArgs (char **argv, int argc) if (!strcasecmp(argv[i], "-nojustifier")) Settings.JustifierMaster = FALSE; else + if (!strcasecmp(argv[i], "-nomacsrifle")) + Settings.MacsRifleMaster = FALSE; + else if (!strcasecmp(argv[i], "-port1") || !strcasecmp(argv[i], "-port2")) { diff --git a/snes9x.h b/snes9x.h index 3cc9ca30..b14e7a8c 100644 --- a/snes9x.h +++ b/snes9x.h @@ -393,7 +393,8 @@ struct SSettings bool8 SuperScopeMaster; bool8 JustifierMaster; bool8 MultiPlayer5Master; - + bool8 MacsRifleMaster; + bool8 ForceLoROM; bool8 ForceHiROM; bool8 ForceHeader; diff --git a/win32/rsrc/resource.h b/win32/rsrc/resource.h index 8799dc1b..48756a4f 100644 --- a/win32/rsrc/resource.h +++ b/win32/rsrc/resource.h @@ -521,6 +521,7 @@ #define ID_FILE_LOAD8 44028 #define ID_FILE_LOAD9 44029 #define ID_FILE_LOAD_FILE 44030 +#define IDM_MACSRIFLE_TOGGLE 44031 #define IDC_STATIC -1 // Next default values for new objects diff --git a/win32/rsrc/snes9x.rc b/win32/rsrc/snes9x.rc index ec7a82a9..2ad100a3 100644 --- a/win32/rsrc/snes9x.rc +++ b/win32/rsrc/snes9x.rc @@ -950,6 +950,7 @@ BEGIN MENUITEM "Use Mouse in alternate port", IDM_MOUSE_SWAPPED MENUITEM "Use Multitaps (8-player)", IDM_MULTITAP8 MENUITEM "Use Dual Justifiers", IDM_JUSTIFIERS + MENUITEM "Use M.A.C.S. Rifle", IDM_MACSRIFLE_TOGGLE END POPUP "&Sound" BEGIN diff --git a/win32/wlanguage.h b/win32/wlanguage.h index 42287fea..481aa892 100644 --- a/win32/wlanguage.h +++ b/win32/wlanguage.h @@ -426,6 +426,7 @@ Nintendo is a trade mark.") #define WINPROC_CONTROLERS4 "Superscope on #1" #define WINPROC_CONTROLERS5 "Justifier 1 on #1" #define WINPROC_CONTROLERS6 "Justifier 2 on #1" +#define WINPROC_CONTROLERS7 "M.A.C.S. Rifle on #1" #define WINPROC_BGHACK "Background layering hack" #define WINPROC_MODE7INTER "Mode 7 Interpolation" #define WINPROC_TRANSPARENCY "Transparency effects" diff --git a/win32/wsnes9x.cpp b/win32/wsnes9x.cpp index ac955d27..7f3b7f9c 100644 --- a/win32/wsnes9x.cpp +++ b/win32/wsnes9x.cpp @@ -732,7 +732,7 @@ void S9xMouseOn () else SetCursor (NULL); } - else if (GUI.ControllerOption!=SNES_SUPERSCOPE && GUI.ControllerOption!=SNES_JUSTIFIER && GUI.ControllerOption!=SNES_JUSTIFIER_2) + else if (GUI.ControllerOption!=SNES_SUPERSCOPE && GUI.ControllerOption!=SNES_JUSTIFIER && GUI.ControllerOption!=SNES_JUSTIFIER_2 && GUI.ControllerOption!=SNES_MACSRIFLE) { SetCursor (GUI.Arrow); GUI.CursorTimer = 60; @@ -771,6 +771,8 @@ void ControllerOptionsFromControllers() GUI.ControllerOption = SNES_JUSTIFIER; else if (controller[0] == CTL_JOYPAD && controller[1] == CTL_JUSTIFIER && ids[0]) GUI.ControllerOption = SNES_JUSTIFIER_2; + else if (controller[0] == CTL_JOYPAD && controller[1] == CTL_MACSRIFLE) + GUI.ControllerOption = SNES_MACSRIFLE; } void ChangeInputDevice(void) @@ -779,6 +781,7 @@ void ChangeInputDevice(void) Settings.JustifierMaster = false; Settings.SuperScopeMaster = false; Settings.MultiPlayer5Master = false; + Settings.MacsRifleMaster = false; switch(GUI.ControllerOption) { @@ -817,6 +820,11 @@ void ChangeInputDevice(void) S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); S9xSetController(1, CTL_JUSTIFIER, 1, 0, 0, 0); break; + case SNES_MACSRIFLE: + Settings.MacsRifleMaster = true; + S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); + S9xSetController(1, CTL_MACSRIFLE, 0, 0, 0, 0); + break; default: case SNES_JOYPAD: S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0); @@ -1827,6 +1835,11 @@ LRESULT CALLBACK WinProc( GUI.ControllerOption = SNES_JUSTIFIER_2; ChangeInputDevice(); break; + case IDM_MACSRIFLE_TOGGLE: + MOVIE_LOCKED_SETTING + GUI.ControllerOption = SNES_MACSRIFLE; + ChangeInputDevice(); + break; //start turbo case ID_TURBO_R: @@ -2553,7 +2566,7 @@ LRESULT CALLBACK WinProc( { CenterCursor(); } - else if (GUI.ControllerOption==SNES_SUPERSCOPE || GUI.ControllerOption==SNES_JUSTIFIER || GUI.ControllerOption==SNES_JUSTIFIER_2) + else if (GUI.ControllerOption==SNES_SUPERSCOPE || GUI.ControllerOption==SNES_JUSTIFIER || GUI.ControllerOption==SNES_JUSTIFIER_2 || GUI.ControllerOption==SNES_MACSRIFLE) { RECT size; GetClientRect (GUI.hWnd, &size); @@ -3032,6 +3045,7 @@ enum k_MO = 0x02000000, k_SS = 0x04000000, k_LG = 0x08000000, + k_RF = 0x10000000, k_BT = 0x00100000, k_PT = 0x00200000, @@ -3171,10 +3185,13 @@ enum kWinCMapLGun2Trigger, kWinCMapLGun2Start, + kWinCMapMacsRifleTrigger = k_HD | k_BT | k_RF | k_C1, + kWinCMapMouse1Pointer = k_HD | k_PT | k_MO | k_C1, kWinCMapMouse2Pointer = k_HD | k_PT | k_MO | k_C2, kWinCMapSuperscopePointer = k_HD | k_PT | k_SS | k_C1, kWinCMapJustifier1Pointer = k_HD | k_PT | k_LG | k_C1, + kWinCMapMacsRiflePointer = k_HD | k_PT | k_RF | k_C1, kWinCMapPseudoPtrBase = k_HD | k_PS | k_LG | k_C2 // for Justifier 2P }; @@ -3314,10 +3331,13 @@ void S9xSetupDefaultKeymap(void) ASSIGN_BUTTONt(kWinCMapLGun2Trigger, "Justifier2 Trigger"); ASSIGN_BUTTONt(kWinCMapLGun2Start, "Justifier2 Start"); + ASSIGN_BUTTONt(kWinCMapMacsRifleTrigger, "MacsRifle Trigger"); + ASSIGN_POINTRt(kWinCMapMouse1Pointer, "Pointer Mouse1"); ASSIGN_POINTRt(kWinCMapMouse2Pointer, "Pointer Mouse2"); ASSIGN_POINTRt(kWinCMapSuperscopePointer, "Pointer Superscope"); ASSIGN_POINTRt(kWinCMapJustifier1Pointer, "Pointer Justifier1"); + ASSIGN_POINTRt(kWinCMapMacsRiflePointer, "Pointer MacsRifle"); ASSIGN_POINTRf(PseudoPointerBase, "Pointer Justifier2"); ASSIGN_BUTTONf(kWinCMapPseudoPtrBase + 0, "ButtonToPointer 1u Med"); @@ -3660,7 +3680,7 @@ int WINAPI WinMain( { if (--GUI.CursorTimer == 0) { - if (GUI.ControllerOption != SNES_SUPERSCOPE && GUI.ControllerOption != SNES_JUSTIFIER && GUI.ControllerOption != SNES_JUSTIFIER_2) + if (GUI.ControllerOption != SNES_SUPERSCOPE && GUI.ControllerOption != SNES_JUSTIFIER && GUI.ControllerOption != SNES_JUSTIFIER_2 && GUI.ControllerOption != SNES_MACSRIFLE) SetCursor (NULL); } } @@ -4064,6 +4084,10 @@ static void CheckMenuStates () mii.fState = validFlag | (GUI.ControllerOption == SNES_JUSTIFIER_2 ? MFS_CHECKED : MFS_UNCHECKED); SetMenuItemInfo (GUI.hMenu, IDM_JUSTIFIERS, FALSE, &mii); + validFlag = (((1<