Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
*
*/
#define ENABLE_CUSTOM_COURSE_ENGINE 0
#define ENABLE_RUMBLE 0
#endif
23 changes: 23 additions & 0 deletions mk64.ld
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

OUTPUT_ARCH (mips)

#include "config.h"

#define LINKER_MAIN 0x80000400

#define LINKER_ENDING 0x80280000
Expand Down Expand Up @@ -55,6 +57,9 @@ SECTIONS
BUILD_DIR/src/cpu_vehicles_camera_path.jp.o(.text*);
BUILD_DIR/src/camera.o(.text*);
BUILD_DIR/src/render_player.o(.text*);
#if ENABLE_RUMBLE
BUILD_DIR/src/rumble_init.o(.text*);
#endif
BUILD_DIR/src/kart_dma.o(.text*);
BUILD_DIR/src/player_controller.o(.text*);
BUILD_DIR/src/spawn_players.o(.text*);
Expand Down Expand Up @@ -129,6 +134,9 @@ SECTIONS
BUILD_DIR/src/os/guOrthoF.o(.text*);
BUILD_DIR/src/os/osSetTime.o(.text*);
BUILD_DIR/src/os/osEepromProbe.o(.text*);
#if ENABLE_RUMBLE
BUILD_DIR/src/os/motor.o(.text);
#endif
BUILD_DIR/src/os/osPfsIsPlug.o(.text*);
BUILD_DIR/src/os/osPfsInit.o(.text*);
BUILD_DIR/src/os/osPfsNumFiles.o(.text*);
Expand Down Expand Up @@ -222,6 +230,9 @@ SECTIONS
BUILD_DIR/src/data/path_spawn_metadata.o(.data*);
BUILD_DIR/src/camera.o(.data*);
BUILD_DIR/src/render_player.o(.data*);
#if ENABLE_RUMBLE
BUILD_DIR/src/rumble_init.o(.data*);
#endif
BUILD_DIR/src/kart_dma.o(.data*);
BUILD_DIR/src/data/kart_attributes.o(.data*);
BUILD_DIR/src/player_controller.o(.data*);
Expand Down Expand Up @@ -256,6 +267,9 @@ SECTIONS
BUILD_DIR/src/os/osViTable.o(.data*);
BUILD_DIR/src/os/osCreatePiManager.o(.data*);
BUILD_DIR/src/os/osContInit.o(.data*);
#if ENABLE_RUMBLE
BUILD_DIR/src/os/motor.o(.data*);
#endif
BUILD_DIR/src/os/osAiSetNextBuffer.o(.data*);
BUILD_DIR/src/os/__osSetHWIntrRoutine.o(.data*);
BUILD_DIR/src/os/__osDequeueThread.o(.data*);
Expand All @@ -272,6 +286,9 @@ SECTIONS
BUILD_DIR/src/cpu_vehicles_camera_path.jp.o(.rodata*);
BUILD_DIR/src/camera.o(.rodata*);
BUILD_DIR/src/render_player.o(.rodata*);
#if ENABLE_RUMBLE
BUILD_DIR/src/rumble_init.o(.rodata*);
#endif
BUILD_DIR/src/player_controller.o(.rodata*);
BUILD_DIR/src/spawn_players.o(.rodata*);
BUILD_DIR/src/code_8003DC40.o(.rodata*);
Expand Down Expand Up @@ -331,6 +348,9 @@ SECTIONS
BUILD_DIR/src/cpu_vehicles_camera_path.jp.o(.bss*);
BUILD_DIR/src/camera.o(.bss*);
BUILD_DIR/src/render_player.o(.bss*);
#if ENABLE_RUMBLE
BUILD_DIR/src/rumble_init.o(.bss*);
#endif
BUILD_DIR/src/spawn_players.o(.bss*);
BUILD_DIR/src/code_80057C60.o(.bss*);
BUILD_DIR/src/code_80057C60_var.o(.bss*);
Expand All @@ -355,6 +375,9 @@ SECTIONS
BUILD_DIR/src/os/osSpTaskLoadGo.o(.bss*);
BUILD_DIR/src/os/osContStartReadData.o(.bss*);
BUILD_DIR/src/os/osContInit.o(.bss*);
#if ENABLE_RUMBLE
BUILD_DIR/src/os/motor.o(.bss*);
#endif
BUILD_DIR/src/os/osPfsIsPlug.o(.bss*);
BUILD_DIR/src/os/guRotateF.o(.bss*);
BUILD_DIR/src/os/__osLeoInterrupt.o(.bss*);
Expand Down
23 changes: 23 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <debug.h>
#include "crash_screen.h"
#include "buffers/gfx_output_buffer.h"
#include "rumble_init.h"

void func_80091B78(void);
void audio_init(void);
Expand Down Expand Up @@ -155,6 +156,9 @@ OSThread gAudioThread;
ALIGNED8 u8 gAudioThreadStack[STACKSIZE];
UNUSED OSThread D_8015CD30;
UNUSED ALIGNED8 u8 D_8015CD30_Stack[STACKSIZE / 2];
#if ENABLE_RUMBLE
ALIGNED8 u8 gRumbleThreadStack[STACKSIZE];
#endif

ALIGNED8 u8 gGfxSPTaskYieldBuffer[4352];
ALIGNED8 u32 gGfxSPTaskStack[256];
Expand Down Expand Up @@ -348,9 +352,15 @@ void update_controller(s32 index) {
void read_controllers(void) {
OSMesg msg;

#if ENABLE_RUMBLE
block_until_rumble_pak_free();
#endif
osContStartReadData(&gSIEventMesgQueue);
osRecvMesg(&gSIEventMesgQueue, &msg, OS_MESG_BLOCK);
osContGetReadData(gControllerPads);
#if ENABLE_RUMBLE
release_rumble_pak_control();
#endif
update_controller(0);
update_controller(1);
update_controller(2);
Expand Down Expand Up @@ -1171,11 +1181,20 @@ void update_gamestate(void) {
void thread5_game_loop(UNUSED void* arg) {
osCreateMesgQueue(&gGfxVblankQueue, gGfxMesgBuf, 1);
osCreateMesgQueue(&gGameVblankQueue, &gGameMesgBuf, 1);

#if ENABLE_RUMBLE
init_rumble_pak_scheduler_queue();
#endif

init_controllers();
if (!wasSoftReset) {
clear_nmi_buffer();
}

#if ENABLE_RUMBLE
create_thread_6();
#endif

set_vblank_handler(2, &gGameVblankHandler, &gGameVblankQueue, (OSMesg) OS_EVENT_SW2);
// These variables track stats such as player wins.
// In the event of a console reset, it remembers them.
Expand All @@ -1192,6 +1211,10 @@ void thread5_game_loop(UNUSED void* arg) {
func_800C5CB8();

while (true) {
#if ENABLE_RUMBLE
//block_until_rumble_pak_free();
#endif

func_800CB2C4();

// Update the gamestate if it has changed (racing, menus, credits, etc.).
Expand Down
3 changes: 3 additions & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ extern OSThread gGameLoopThread;
extern u8 gGameLoopThreadStack[];
extern OSThread gAudioThread;
extern u8 gAudioThreadStack[];
#if ENABLE_RUMBLE
extern u8 gRumbleThreadStack[];
#endif

extern u8 gGfxSPTaskYieldBuffer[];
extern u32 gGfxSPTaskStack[];
Expand Down
10 changes: 10 additions & 0 deletions src/menus.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <sounds.h>
#include "spawn_players.h"
#include "seq_ids.h"
#include "rumble_init.h"

#if ENABLE_DEBUG_MODE
#define DEBUG_MODE_TOGGLE true
Expand Down Expand Up @@ -1448,6 +1449,9 @@ void main_menu_act(struct Controller* controller, u16 controllerIdx) {
gMenuTimingCounter++;
if ((gMenuTimingCounter == 60) || !(gMenuTimingCounter % 300)) {
play_sound2(SOUND_MENU_OK);
#if ENABLE_RUMBLE
queue_rumble_data(0, 5, 80);
#endif
}
}
if (btnAndStick & B_BUTTON) {
Expand Down Expand Up @@ -1653,6 +1657,9 @@ void player_select_menu_act(struct Controller* controller, u16 controllerIdx) {
gMenuTimingCounter++;
if (gMenuTimingCounter == 0x3C || !(gMenuTimingCounter % 300)) {
play_sound2(SOUND_MENU_OK);
#if ENABLE_RUMBLE
queue_rumble_data(0, 5, 80);
#endif
}
}
if (btnAndStick & B_BUTTON) {
Expand Down Expand Up @@ -1758,6 +1765,9 @@ void course_select_menu_act(struct Controller* arg0, u16 controllerIdx) {
if ((controllerIdx == PLAYER_ONE) &&
((++gMenuTimingCounter == 0x3C) || ((gMenuTimingCounter % 300) == 0))) {
play_sound2(SOUND_MENU_OK);
#if ENABLE_RUMBLE
queue_rumble_data(0, 5, 80);
#endif
}

if ((btnAndStick & B_BUTTON) != 0) {
Expand Down
179 changes: 179 additions & 0 deletions src/os/motor.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
#include "PR/os_message.h"
#include "PR/os_pi.h"
#include "libultra_internal.h"
#include "controller.h"
#include "macros.h"

void _MakeMotorData(int channel, u16 address, u8 *buffer, OSPifRam *mdata);
u32 __osMotorinitialized[MAXCONTROLLERS] = { 0, 0, 0, 0 };
OSPifRam _MotorStopData[MAXCONTROLLERS];
OSPifRam _MotorStartData[MAXCONTROLLERS];
u8 _motorstopbuf[32];
u8 _motorstartbuf[32];

s32 osMotorStop(OSPfs *pfs) {
int i;
s32 ret;
u8 *ptr;
__OSContRamReadFormat ramreadformat;
ptr = (u8 *) &__osPfsPifRam;

if (!__osMotorinitialized[pfs->channel]) {
return PFS_ERR_INVALID;
}
__osSiGetAccess();

__osContLastCmd = CONT_CMD_WRITE_MEMPACK;
__osSiRawStartDma(OS_WRITE, &_MotorStopData[pfs->channel]);
osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK);
ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK);
ptr = (u8 *) &__osPfsPifRam;

if (pfs->channel != 0) {
for (i = 0; i < pfs->channel; i++) {
ptr++;
}
}

ramreadformat = *(__OSContRamReadFormat *) ptr;
ret = CHNL_ERR(ramreadformat);
if (ret == 0 && ramreadformat.datacrc != __osContDataCrc((u8 *) &_motorstopbuf)) {
ret = PFS_ERR_CONTRFAIL;
}
__osSiRelAccess();
return ret;
}

s32 osMotorStart(OSPfs *pfs) {
int i;
s32 ret;
u8 *ptr;
__OSContRamReadFormat ramreadformat;

ptr = (u8 *) &__osPfsPifRam;

if (!__osMotorinitialized[pfs->channel]) {
return PFS_ERR_INVALID;
}

__osSiGetAccess();

__osContLastCmd = CONT_CMD_WRITE_MEMPACK;
__osSiRawStartDma(OS_WRITE, &_MotorStartData[pfs->channel]);
osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK);
ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK);
ptr = (u8 *) &__osPfsPifRam;

if (pfs->channel != 0) {
for (i = 0; i < pfs->channel; i++) {
ptr++;
}
}

ramreadformat = *(__OSContRamReadFormat *) ptr;
ret = CHNL_ERR(ramreadformat);
if (ret == 0 && ramreadformat.datacrc != __osContDataCrc((u8 *) &_motorstartbuf)) {
ret = PFS_ERR_CONTRFAIL;
}
__osSiRelAccess();
return ret;
}

void _MakeMotorData(int channel, u16 address, u8 *buffer, OSPifRam *mdata) {
u8 *ptr;
__OSContRamReadFormat ramreadformat;
int i;

ptr = (u8 *) mdata->ramarray;
for (i = 0; i < ARRAY_COUNT(mdata->ramarray); i++) {
mdata->ramarray[i] = 0;
}
mdata->pifstatus = CONT_CMD_EXE;
ramreadformat.dummy = CONT_CMD_NOP;
ramreadformat.txsize = CONT_CMD_WRITE_MEMPACK_TX;
ramreadformat.rxsize = CONT_CMD_WRITE_MEMPACK_RX;
ramreadformat.cmd = CONT_CMD_WRITE_MEMPACK;

ramreadformat.address = (address << 0x5) | __osContAddressCrc(address);
ramreadformat.datacrc = CONT_CMD_NOP;
for (i = 0; i < ARRAY_COUNT(ramreadformat.data); i++) {
ramreadformat.data[i] = *buffer++;
}
if (channel != 0) {
for (i = 0; i < channel; i++) {
*ptr++ = 0;
}
}
*(__OSContRamReadFormat *) ptr = ramreadformat;
ptr += sizeof(__OSContRamReadFormat);
ptr[0] = CONT_CMD_END;
}

s32 osMotorInit(OSMesgQueue *mq, OSPfs *pfs, int channel) {
int i;
s32 ret;
u8 temp[32];
pfs->queue = mq;
pfs->channel = channel;
pfs->status = 0;
pfs->activebank = 128;

for (i = 0; i < ARRAY_COUNT(temp); i++) {
temp[i] = 254;
}

ret = __osContRamWrite(mq, channel, 1024, temp, false);
if (ret == 2) { // TODO: remove magic constant
ret = __osContRamWrite(mq, channel, 1024, temp, false);
}
if (ret != 0) {
return ret;
}

ret = __osContRamRead(mq, channel, 1024, temp);
if (ret == 2) {
ret = PFS_ERR_CONTRFAIL; // is this right?
}
if (ret != 0) {
return ret;
}
if (temp[31] == 254) {
return PFS_ERR_DEVICE;
}

for (i = 0; i < ARRAY_COUNT(temp); i++) {
temp[i] = 128;
}

ret = __osContRamWrite(mq, channel, 1024, temp, false);
if (ret == 2) {
ret = __osContRamWrite(mq, channel, 1024, temp, false);
}
if (ret != 0) {
return ret;
}

ret = __osContRamRead(mq, channel, 1024, temp);
if (ret == 2) {
ret = PFS_ERR_CONTRFAIL;
}
if (ret != 0) {
return ret;
}
if (temp[31] != 128) {
return PFS_ERR_DEVICE;
}

if (!__osMotorinitialized[channel]) {
for (i = 0; i < ARRAY_COUNT(_motorstartbuf); i++) {
_motorstartbuf[i] = 1;
_motorstopbuf[i] = 0;
}
_MakeMotorData(channel, 1536, _motorstartbuf, &_MotorStartData[channel]);
_MakeMotorData(channel, 1536, _motorstopbuf, &_MotorStopData[channel]);
__osMotorinitialized[channel] = 1;
}
return 0;
}
Loading