You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Add MAX_NUM_PLAYERS
This commit is contained in:
@@ -10,12 +10,32 @@
|
||||
*/
|
||||
#define INTERNAL_ROM_NAME "HackerSM64 "
|
||||
|
||||
/**
|
||||
* Force the game to delete any existing save data originating from a different hack. This requires INTERNAL_ROM_NAME to be unique to work properly.
|
||||
* It is recommended to enable this if any significant changes to the save file are made that could cause issues with this or other hacks.
|
||||
* NOTE: Using save editors with this define will likely just end up wiping your save, since SM64 specific save editors most likely use hardcoded save magic.
|
||||
*/
|
||||
// #define UNIQUE_SAVE_DATA
|
||||
|
||||
/**
|
||||
* Enables Rumble Pak Support.
|
||||
* Currently not recommended, as it may cause random crashes.
|
||||
*/
|
||||
// #define ENABLE_RUMBLE (1 || VERSION_SH)
|
||||
|
||||
/**
|
||||
* The maximum number of supported players/controllers. 1-4.
|
||||
* This will save performance if the player has extra unused controllers plugged in.
|
||||
* NOTE: Default is 2, maximum is 4.
|
||||
* NOTE: This needs to be at least 2 for now for gamecube controller swap to work.
|
||||
*/
|
||||
#define MAX_NUM_PLAYERS 2
|
||||
|
||||
/**
|
||||
* Informs supported emulators to default to gamecube controller inputs.
|
||||
*/
|
||||
// #define USE_GAMECUBE_CONTROLLER
|
||||
|
||||
/**
|
||||
* Screen Size Defines.
|
||||
*/
|
||||
@@ -29,18 +49,6 @@
|
||||
#define BORDER_HEIGHT_CONSOLE 0
|
||||
#define BORDER_HEIGHT_EMULATOR 0
|
||||
|
||||
/**
|
||||
* Force the game to delete any existing save data originating from a different hack. This requires INTERNAL_ROM_NAME to be unique to work properly.
|
||||
* It is recommended to enable this if any significant changes to the save file are made that could cause issues with this or other hacks.
|
||||
* NOTE: Using save editors with this define will likely just end up wiping your save, since SM64 specific save editors most likely use hardcoded save magic.
|
||||
*/
|
||||
// #define UNIQUE_SAVE_DATA
|
||||
|
||||
/**
|
||||
* Informs supported emulators to default to gamecube controller inputs.
|
||||
*/
|
||||
// #define USE_GAMECUBE_CONTROLLER
|
||||
|
||||
/**
|
||||
* RCVI hack. Increases performance on emulator, and does nothing on console.
|
||||
* Might break on some emulators. Use at your own risk, and don't use it unless you actually need the extra performance.
|
||||
|
||||
@@ -33,20 +33,18 @@ struct Config {
|
||||
};
|
||||
|
||||
struct Controller {
|
||||
/*0x00*/ s16 rawStickX; //
|
||||
/*0x02*/ s16 rawStickY; //
|
||||
/*0x04*/ f32 stickX; // [-64, 64] positive is right
|
||||
/*0x08*/ f32 stickY; // [-64, 64] positive is up
|
||||
/*0x0C*/ f32 stickMag; // distance from center [0, 64]
|
||||
/*0x10*/ u16 buttonDown;
|
||||
/*0x12*/ u16 buttonPressed;
|
||||
/*0x14*/ u16 buttonReleased;
|
||||
/*0x18*/ OSContStatus *statusData;
|
||||
/*0x1C*/ OSContPadEx *controllerData;
|
||||
#if ENABLE_RUMBLE
|
||||
/*0x20*/ s32 port;
|
||||
#endif
|
||||
};
|
||||
/*0x00*/ s16 rawStickX; // Analog stick [-80, 80] positive is right. Used for menus.
|
||||
/*0x02*/ s16 rawStickY; // Analog stick [-80, 80] positive is up. Used for menus.
|
||||
/*0x04*/ f32 stickX; // Analog stick [-64, 64] positive is right. Used for gameplay.
|
||||
/*0x08*/ f32 stickY; // Analog stick [-64, 64] positive is up. Used for gameplay.
|
||||
/*0x0C*/ f32 stickMag; // Analog stick distance from center [0, 64]. Used for gameplay.
|
||||
/*0x10*/ u16 buttonDown; // Buttons held down on the current frame.
|
||||
/*0x12*/ u16 buttonPressed; // Buttons pressed on the current frame but not held on the previous frame.
|
||||
/*0x14*/ u16 buttonReleased; // Burrons released on the current frame and held on the previous frame.
|
||||
/*0x18*/ OSContStatus* statusData; // Pointer to the controller status data in gControllerStatuses.
|
||||
/*0x1C*/ OSContPadEx* controllerData; // Pointer to the raw input data in gControllerPads.
|
||||
/*0x20*/ s32 port; // The port index this controller is plugged into [0, 3].
|
||||
}; /*0x24*/
|
||||
|
||||
// -- Booleans --
|
||||
|
||||
|
||||
@@ -39,11 +39,10 @@ u8 *gGfxPoolEnd;
|
||||
struct GfxPool *gGfxPool;
|
||||
|
||||
// OS Controllers
|
||||
struct Controller gControllers[4];
|
||||
OSContStatus gControllerStatuses[4];
|
||||
OSContPadEx gControllerPads[4];
|
||||
u8 gControllerBits;
|
||||
s8 gGamecubeControllerPort = -1; // HackerSM64: This is set to -1 if there's no GC controller, 0 if there's one in the first port and 1 if there's one in the second port.
|
||||
struct Controller gControllers[MAX_NUM_PLAYERS];
|
||||
OSContStatus gControllerStatuses[MAXCONTROLLERS];
|
||||
OSContPadEx gControllerPads[MAXCONTROLLERS];
|
||||
u8 gControllerBits = 0b0000;
|
||||
u8 gIsConsole = TRUE; // Needs to be initialized before audio_reset_session is called
|
||||
u8 gCacheEmulated = TRUE;
|
||||
u8 gBorderHeight;
|
||||
@@ -86,11 +85,11 @@ u16 sRenderingFramebuffer = 0;
|
||||
// Goddard Vblank Function Caller
|
||||
void (*gGoddardVblankCallback)(void) = NULL;
|
||||
|
||||
// Defined controller slots
|
||||
struct Controller *gPlayer1Controller = &gControllers[0];
|
||||
struct Controller *gPlayer2Controller = &gControllers[1];
|
||||
struct Controller *gPlayer3Controller = &gControllers[2];
|
||||
struct Controller *gPlayer4Controller = &gControllers[3];
|
||||
// Defined controller slots. Anything above MAX_NUM_PLAYERS will be unused.
|
||||
struct Controller* const gPlayer1Controller = &gControllers[0];
|
||||
struct Controller* const gPlayer2Controller = &gControllers[1];
|
||||
struct Controller* const gPlayer3Controller = &gControllers[2];
|
||||
struct Controller* const gPlayer4Controller = &gControllers[3];
|
||||
|
||||
// Title Screen Demo Handler
|
||||
struct DemoInput *gCurrDemoInput = NULL;
|
||||
@@ -492,36 +491,25 @@ UNUSED static void record_demo(void) {
|
||||
*/
|
||||
void run_demo_inputs(void) {
|
||||
// Eliminate the unused bits.
|
||||
gControllers[0].controllerData->button &= VALID_BUTTONS;
|
||||
gPlayer1Controller->controllerData->button &= VALID_BUTTONS;
|
||||
|
||||
// Check if a demo inputs list exists and if so,
|
||||
// run the active demo input list.
|
||||
if (gCurrDemoInput != NULL) {
|
||||
// Clear player 2's inputs if they exist. Player 2's controller
|
||||
// cannot be used to influence a demo. At some point, Nintendo
|
||||
// may have planned for there to be a demo where 2 players moved
|
||||
// around instead of just one, so clearing player 2's influence from
|
||||
// the demo had to have been necessary to perform this. Co-op mode, perhaps?
|
||||
if (gControllers[1].controllerData != NULL) {
|
||||
gControllers[1].controllerData->stick_x = 0;
|
||||
gControllers[1].controllerData->stick_y = 0;
|
||||
gControllers[1].controllerData->button = 0;
|
||||
}
|
||||
|
||||
// The timer variable being 0 at the current input means the demo is over.
|
||||
// Set the button to the END_DEMO mask to end the demo.
|
||||
if (gCurrDemoInput->timer == 0) {
|
||||
gControllers[0].controllerData->stick_x = 0;
|
||||
gControllers[0].controllerData->stick_y = 0;
|
||||
gControllers[0].controllerData->button = END_DEMO;
|
||||
gPlayer1Controller->controllerData->stick_x = 0;
|
||||
gPlayer1Controller->controllerData->stick_y = 0;
|
||||
gPlayer1Controller->controllerData->button = END_DEMO;
|
||||
} else {
|
||||
// Backup the start button if it is pressed, since we don't want the
|
||||
// demo input to override the mask where start may have been pressed.
|
||||
u16 startPushed = gControllers[0].controllerData->button & START_BUTTON;
|
||||
u16 startPushed = (gPlayer1Controller->controllerData->button & START_BUTTON);
|
||||
|
||||
// Perform the demo inputs by assigning the current button mask and the stick inputs.
|
||||
gControllers[0].controllerData->stick_x = gCurrDemoInput->rawStickX;
|
||||
gControllers[0].controllerData->stick_y = gCurrDemoInput->rawStickY;
|
||||
gPlayer1Controller->controllerData->stick_x = gCurrDemoInput->rawStickX;
|
||||
gPlayer1Controller->controllerData->stick_y = gCurrDemoInput->rawStickY;
|
||||
|
||||
// To assign the demo input, the button information is stored in
|
||||
// an 8-bit mask rather than a 16-bit mask. this is because only
|
||||
@@ -530,11 +518,11 @@ void run_demo_inputs(void) {
|
||||
// upper 4 bits (A, B, Z, and Start) and shift then left by 8 to
|
||||
// match the correct input mask. We then add this to the masked
|
||||
// lower 4 bits to get the correct button mask.
|
||||
gControllers[0].controllerData->button =
|
||||
gPlayer1Controller->controllerData->button =
|
||||
((gCurrDemoInput->buttonMask & 0xF0) << 8) + ((gCurrDemoInput->buttonMask & 0xF));
|
||||
|
||||
// If start was pushed, put it into the demo sequence being input to end the demo.
|
||||
gControllers[0].controllerData->button |= startPushed;
|
||||
gPlayer1Controller->controllerData->button |= startPushed;
|
||||
|
||||
// Run the current demo input's timer down. if it hits 0, advance the demo input list.
|
||||
if (--gCurrDemoInput->timer == 0) {
|
||||
@@ -604,38 +592,39 @@ void read_controller_inputs(s32 threadID) {
|
||||
run_demo_inputs();
|
||||
#endif
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct Controller *controller = &gControllers[i];
|
||||
for (i = 0; i < MAX_NUM_PLAYERS; i++) {
|
||||
struct Controller* controller = &gControllers[i];
|
||||
OSContPadEx* controllerData = controller->controllerData;
|
||||
// if we're receiving inputs, update the controller struct with the new button info.
|
||||
if (controller->controllerData != NULL) {
|
||||
// HackerSM64: Swaps Z and L, only on console, and only when playing with a GameCube controller.
|
||||
if (gIsConsole && i == gGamecubeControllerPort) {
|
||||
u32 oldButton = controller->controllerData->button;
|
||||
if (__osControllerTypes[controller->port] == CONT_TYPE_GCN) {
|
||||
u32 oldButton = controllerData->button;
|
||||
u32 newButton = oldButton & ~(Z_TRIG | L_TRIG);
|
||||
if (oldButton & Z_TRIG) {
|
||||
newButton |= L_TRIG;
|
||||
}
|
||||
if (controller->controllerData->l_trig > 85) { // How far the player has to press the L trigger for it to be considered a Z press. 64 is about 25%. 127 would be about 50%.
|
||||
if (controllerData->l_trig > 85) { // How far the player has to press the L trigger for it to be considered a Z press. 64 is about 25%. 127 would be about 50%.
|
||||
newButton |= Z_TRIG;
|
||||
}
|
||||
controller->controllerData->button = newButton;
|
||||
controllerData->button = newButton;
|
||||
}
|
||||
controller->rawStickX = controller->controllerData->stick_x;
|
||||
controller->rawStickY = controller->controllerData->stick_y;
|
||||
controller->buttonPressed = ~controller->buttonDown & controller->controllerData->button;
|
||||
controller->buttonReleased = ~controller->controllerData->button & controller->buttonDown;
|
||||
controller->rawStickX = controllerData->stick_x;
|
||||
controller->rawStickY = controllerData->stick_y;
|
||||
controller->buttonPressed = (~controller->buttonDown & controllerData->button);
|
||||
controller->buttonReleased = (~controllerData->button & controller->buttonDown);
|
||||
// 0.5x A presses are a good meme
|
||||
controller->buttonDown = controller->controllerData->button;
|
||||
controller->buttonDown = controllerData->button;
|
||||
adjust_analog_stick(controller);
|
||||
} else { // otherwise, if the controllerData is NULL, 0 out all of the inputs.
|
||||
controller->rawStickX = 0;
|
||||
controller->rawStickY = 0;
|
||||
controller->buttonPressed = 0;
|
||||
controller->buttonReleased = 0;
|
||||
controller->buttonDown = 0;
|
||||
controller->stickX = 0;
|
||||
controller->stickY = 0;
|
||||
controller->stickMag = 0;
|
||||
controller->rawStickX = 0x0000;
|
||||
controller->rawStickY = 0x0000;
|
||||
controller->buttonPressed = 0x0000;
|
||||
controller->buttonReleased = 0x0000;
|
||||
controller->buttonDown = 0x0000;
|
||||
controller->stickX = 0.0f;
|
||||
controller->stickY = 0.0f;
|
||||
controller->stickMag = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -644,7 +633,9 @@ void read_controller_inputs(s32 threadID) {
|
||||
* Initialize the controller structs to point at the OSCont information.
|
||||
*/
|
||||
void init_controllers(void) {
|
||||
s16 port, cont;
|
||||
struct Controller* controller = NULL;
|
||||
int port, cont = 0;
|
||||
int lastUsedPort = -1;
|
||||
|
||||
// Set controller 1 to point to the set of status/pads for input 1 and
|
||||
// init the controllers.
|
||||
@@ -664,29 +655,43 @@ void init_controllers(void) {
|
||||
#endif
|
||||
|
||||
// Loop over the 4 ports and link the controller structs to the appropriate status and pad.
|
||||
for (cont = 0, port = 0; port < 4 && cont < 4; port++) {
|
||||
for (port = 0; port < MAXCONTROLLERS; port++) {
|
||||
if (cont >= MAX_NUM_PLAYERS) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Is controller plugged in?
|
||||
if (gControllerBits & (1 << port)) {
|
||||
// The game allows you to have just 1 controller plugged
|
||||
// into any port in order to play the game. this was probably
|
||||
// so if any of the ports didn't work, you can have controllers
|
||||
// plugged into any of them and it will work.
|
||||
#if ENABLE_RUMBLE
|
||||
gControllers[cont].port = port;
|
||||
controller = &gControllers[cont];
|
||||
controller->statusData = &gControllerStatuses[port];
|
||||
controller->controllerData = &gControllerPads[port];
|
||||
controller->port = port;
|
||||
|
||||
lastUsedPort = port;
|
||||
|
||||
cont++;
|
||||
}
|
||||
}
|
||||
|
||||
#if (MAX_NUM_PLAYERS >= 2)
|
||||
//! Some flashcarts (eg. ED64p) don't let you start a ROM with a GameCube controller in port 1,
|
||||
// so if port 1 is an N64 controller and port 2 is a GC controller, swap them.
|
||||
if (gIsConsole) {
|
||||
if (__osControllerTypes[0] == CONT_TYPE_N64
|
||||
&& __osControllerTypes[1] == CONT_TYPE_GCN) {
|
||||
struct Controller temp = gControllers[0];
|
||||
gControllers[0] = gControllers[1];
|
||||
gControllers[1] = temp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
gControllers[cont].statusData = &gControllerStatuses[port];
|
||||
gControllers[cont++].controllerData = &gControllerPads[port];
|
||||
}
|
||||
}
|
||||
if ((__osControllerTypes[1] == CONT_TYPE_GCN) && (gIsConsole)) {
|
||||
gGamecubeControllerPort = 1;
|
||||
gPlayer1Controller = &gControllers[1];
|
||||
} else {
|
||||
if (__osControllerTypes[0] == CONT_TYPE_GCN) {
|
||||
gGamecubeControllerPort = 0;
|
||||
}
|
||||
gPlayer1Controller = &gControllers[0];
|
||||
}
|
||||
|
||||
// Disable the ports after the last used one.
|
||||
osContSetCh(lastUsedPort + 1);
|
||||
}
|
||||
|
||||
// Game thread core
|
||||
|
||||
@@ -30,9 +30,9 @@ enum ZBmodes {
|
||||
CLEAR_ZBUFFER = 1,
|
||||
};
|
||||
|
||||
extern struct Controller gControllers[4];
|
||||
extern OSContStatus gControllerStatuses[4];
|
||||
extern OSContPadEx gControllerPads[4];
|
||||
extern struct Controller gControllers[MAX_NUM_PLAYERS];
|
||||
extern OSContStatus gControllerStatuses[MAXCONTROLLERS];
|
||||
extern OSContPadEx gControllerPads[MAXCONTROLLERS];
|
||||
extern OSMesgQueue gGameVblankQueue;
|
||||
extern OSMesgQueue gGfxVblankQueue;
|
||||
extern OSMesg gGameMesgBuf[1];
|
||||
@@ -47,7 +47,6 @@ extern Gfx *gDisplayListHead;
|
||||
extern u8 *gGfxPoolEnd;
|
||||
extern struct GfxPool *gGfxPool;
|
||||
extern u8 gControllerBits;
|
||||
extern s8 gGamecubeControllerPort;
|
||||
extern u8 gIsConsole;
|
||||
extern u8 gCacheEmulated;
|
||||
extern u8 gBorderHeight;
|
||||
@@ -64,10 +63,10 @@ extern s8 gSramProbe;
|
||||
#endif
|
||||
|
||||
extern void (*gGoddardVblankCallback)(void);
|
||||
extern struct Controller *gPlayer1Controller;
|
||||
extern struct Controller *gPlayer2Controller;
|
||||
extern struct Controller *gPlayer3Controller;
|
||||
extern struct Controller *gPlayer4Controller;
|
||||
extern struct Controller* const gPlayer1Controller;
|
||||
extern struct Controller* const gPlayer2Controller;
|
||||
extern struct Controller* const gPlayer3Controller;
|
||||
extern struct Controller* const gPlayer4Controller;
|
||||
extern struct DemoInput *gCurrDemoInput;
|
||||
extern u16 gDemoInputListID;
|
||||
extern struct DemoInput gRecordedDemoInput;
|
||||
|
||||
@@ -1873,12 +1873,8 @@ void init_mario_from_save_file(void) {
|
||||
gMarioState->spawnInfo = &gPlayerSpawnInfos[0];
|
||||
gMarioState->statusForCamera = &gPlayerCameraState[0];
|
||||
gMarioState->marioBodyState = &gBodyStates[0];
|
||||
gMarioState->controller = &gControllers[0];
|
||||
gMarioState->animList = &gMarioAnimsBuf;
|
||||
if (gIsConsole && __osControllerTypes[1] == CONT_TYPE_GCN) {
|
||||
gMarioState->controller = &gControllers[1];
|
||||
} else {
|
||||
gMarioState->controller = &gControllers[0];
|
||||
}
|
||||
|
||||
gMarioState->numCoins = 0;
|
||||
gMarioState->numStars = save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1);
|
||||
|
||||
Reference in New Issue
Block a user