Document swdrv

This commit is contained in:
Seeky 2023-01-04 18:37:46 +00:00
parent 69824de48e
commit e71e807789
4 changed files with 89 additions and 87 deletions

View File

@ -265,15 +265,15 @@ global:
0x800381a4: _swClear 0x800381a4: _swClear
0x800381e4: _swByteSet 0x800381e4: _swByteSet
0x800381f4: _swByteGet 0x800381f4: _swByteGet
# 0x80038204 0x80038204: swGetCoinId
# 0x800383a0 0x800383a0: swCoinSet
# 0x80038478 0x80038478: swCoinClear
# 0x80038550 0x80038550: swCoinGet
# 0x8003863c 0x8003863c: swResetCoinId
# 0x8003864c 0x8003864c: swResetGameCoinId
# 0x8003865c 0x8003865c: swGetGameCoinId
# 0x8003875c 0x8003875c: swGameCoinGet
# 0x800387d8 0x800387d8: swGameCoinSet
# windowdrv.c # windowdrv.c
0x800388b4: windowInit 0x800388b4: windowInit
@ -5642,6 +5642,7 @@ relF.rel:
src/swdrv.c: src/swdrv.c:
# .rodata # .rodata
0x80325cb8: gameCoinGswMap
0x80326178: assign_tbl 0x80326178: assign_tbl
# .bss # .bss
0x8050a118: work 0x8050a118: work

View File

@ -6,23 +6,17 @@
#pragma once #pragma once
#include <common.h> #include <common.h>
#include <spm/swdrv.h>
#include <wii/os.h> #include <wii/os.h>
#include <wii/mtx.h> #include <wii/mtx.h>
CPP_WRAPPER(spm::spmario) CPP_WRAPPER(spm::spmario)
USING(spm::swdrv::SwCoinEntry)
USING(wii::os::OSThread) USING(wii::os::OSThread)
USING(wii::os::OSTime) USING(wii::os::OSTime)
USING(wii::mtx::Vec3) USING(wii::mtx::Vec3)
typedef struct
{
/* 0x00 */ char mapName[8];
/* 0x08 */ u32 coinFlags[1]; // TODO: longer
/* 0x0C */ u8 _C[0x48-0xc];
} CoinThing;
SIZE_ASSERT(CoinThing, 0x48)
typedef struct typedef struct
{ {
/* 0x0000 */ u32 flags; /* 0x0000 */ u32 flags;
@ -56,7 +50,7 @@ typedef struct
/* 0x0544 */ s8 gsw[2048]; // index 0 used in favour of gsw0 /* 0x0544 */ s8 gsw[2048]; // index 0 used in favour of gsw0
/* 0x0D44 */ u32 lswf[16]; // 512 flags /* 0x0D44 */ u32 lswf[16]; // 512 flags
/* 0x0D84 */ u8 lsw[1024]; /* 0x0D84 */ u8 lsw[1024];
/* 0x1184 */ CoinThing coinThings[32]; // coin related? /* 0x1184 */ SwCoinEntry coinEntries[32];
/* 0x1A84 */ u8 unknown_0x1a84[0x1b00 - 0x1a84]; /* 0x1A84 */ u8 unknown_0x1a84[0x1b00 - 0x1a84];
/* 0x1B00 */ bool disableRumble[4]; // overrides to force off wpadmgr's enableRumble, /* 0x1B00 */ bool disableRumble[4]; // overrides to force off wpadmgr's enableRumble,
// index controller id // index controller id

View File

@ -15,6 +15,13 @@ CPP_WRAPPER(spm::swdrv)
#define MAX_COIN_MAP 32 #define MAX_COIN_MAP 32
#define MAX_COIN_BIT 0x200 #define MAX_COIN_BIT 0x200
typedef struct
{
/* 0x00 */ char mapName[8];
/* 0x08 */ u32 coinFlags[16];
} SwCoinEntry;
SIZE_ASSERT(SwCoinEntry, 0x48)
typedef struct typedef struct
{ {
/* 0x0 */ const char * mapName; /* 0x0 */ const char * mapName;
@ -29,6 +36,7 @@ typedef struct
} SwWork; } SwWork;
SIZE_ASSERT(SwWork, 0x8) SIZE_ASSERT(SwWork, 0x8)
DECOMP_STATIC(s32 swdrv_gameCoinGswMap[])
DECOMP_STATIC(AssignTblEntry swdrv_assign_tbl[]) DECOMP_STATIC(AssignTblEntry swdrv_assign_tbl[])
DECOMP_STATIC(SwWork swdrv_work) DECOMP_STATIC(SwWork swdrv_work)
DECOMP_STATIC(SwWork * swdrv_wp) DECOMP_STATIC(SwWork * swdrv_wp)
@ -101,15 +109,14 @@ void _swByteSet(s32 id, u8 num);
*/ */
s32 _swByteGet(s32 id); s32 _swByteGet(s32 id);
// New to SPM so no symbols: s32 swGetCoinId();
s32 func_80038204(); void swCoinSet(s32 id);
void func_800383a0(s32 id); void swCoinClear(s32 id);
void func_80038478(s32 id); bool swCoinGet(s32 id);
bool func_80038550(s32 id); void swResetCoinId();
void func_8003863c(); void swResetGameCoinId();
void func_8003864c(); s32 swGetGameCoinId();
s32 func_8003865c(); bool swGameCoinGet(s32 id);
bool func_8003875c(s32 id); void swGameCoinSet(s32 id);
void func_800387d8(s32 id);
CPP_WRAPPER_END() CPP_WRAPPER_END()

View File

@ -7,8 +7,7 @@
#include <spm/system.h> #include <spm/system.h>
#include <msl/string.h> #include <msl/string.h>
// .rodata static const s32 gameCoinGswMap[] = {
static const s32 lbl_80325cb8[] = {
GSW(153), GSW(154), GSW(155), GSW(156), GSW(157), GSW(158), GSW(159), GSW(160), GSW(153), GSW(154), GSW(155), GSW(156), GSW(157), GSW(158), GSW(159), GSW(160),
GSW(161), GSW(162), GSW(163), GSW(164), GSW(165), GSW(166), GSW(167), GSW(168), GSW(161), GSW(162), GSW(163), GSW(164), GSW(165), GSW(166), GSW(167), GSW(168),
GSW(169), GSW(170), GSW(171), GSW(172), GSW(173), GSW(174), GSW(175), GSW(176), GSW(169), GSW(170), GSW(171), GSW(172), GSW(173), GSW(174), GSW(175), GSW(176),
@ -52,10 +51,7 @@ static const AssignTblEntry assign_tbl[] = {
{"ta1_07", 10}, {"ta2_01", 34}, {"ta3_02", 3}, {"ta3_05", 48} {"ta1_07", 10}, {"ta2_01", 34}, {"ta3_02", 3}, {"ta3_05", 48}
}; };
// .bss
static SwWork work; static SwWork work;
// .sdata
static SwWork * wp = &work; static SwWork * wp = &work;
void swInit() void swInit()
@ -65,7 +61,7 @@ void swInit()
memset(gp->lswf, 0, sizeof(gp->lswf)); memset(gp->lswf, 0, sizeof(gp->lswf));
memset(gp->lsw, 0, sizeof(gp->lsw)); memset(gp->lsw, 0, sizeof(gp->lsw));
memset(gp->coinThings, 0, sizeof(gp->coinThings)); memset(gp->coinEntries, 0, sizeof(gp->coinEntries));
wp->coinId = 0; wp->coinId = 0;
wp->gameCoinId = 0; wp->gameCoinId = 0;
@ -78,7 +74,7 @@ void swReInit()
memset(gp->lswf, 0, sizeof(gp->lswf)); memset(gp->lswf, 0, sizeof(gp->lswf));
memset(gp->lsw, 0, sizeof(gp->lsw)); memset(gp->lsw, 0, sizeof(gp->lsw));
memset(gp->coinThings, 0, sizeof(gp->coinThings)); memset(gp->coinEntries, 0, sizeof(gp->coinEntries));
wp->coinId = 0; wp->coinId = 0;
} }
@ -150,50 +146,50 @@ s32 _swByteGet(s32 id)
return gp->lsw[id]; return gp->lsw[id];
} }
s32 func_80038204() s32 swGetCoinId()
{ {
s32 id; s32 id;
s32 i; s32 i;
CoinThing * coinThing; SwCoinEntry * entry;
coinThing = gp->coinThings; entry = gp->coinEntries;
// Skip if in wrong sequence // Skip if in wrong sequence
if (seqGetSeq() != SEQ_MAPCHANGE) if (seqGetSeq() != SEQ_MAPCHANGE)
return -1; return -1;
// Try find CoinThing for this map // Try find coin entry for this map
for (i = 0; i < MAX_COIN_MAP; i++, coinThing++) for (i = 0; i < MAX_COIN_MAP; i++, entry++)
{ {
if (strcmp(gp->mapName, coinThing->mapName) == 0) if (strcmp(gp->mapName, entry->mapName) == 0)
break; break;
} }
// Allocate CoinThing for this map // Allocate coin entry for this map if needed
if (i >= MAX_COIN_MAP) if (i >= MAX_COIN_MAP)
{ {
// Wipe if changing area // Wipe if changing area
coinThing = gp->coinThings; entry = gp->coinEntries;
if (strncmp(gp->mapName, coinThing->mapName, 3) != 0 && if (strncmp(gp->mapName, entry->mapName, 3) != 0 &&
strncmp(gp->mapName, "bos", 3) != 0) strncmp(gp->mapName, "bos", 3) != 0)
{ {
memset(gp->coinThings, 0, sizeof(gp->coinThings)); memset(gp->coinEntries, 0, sizeof(gp->coinEntries));
wp->coinId = 0; wp->coinId = 0;
} }
// Find free CoinThing // Find free coin entry
coinThing = gp->coinThings; entry = gp->coinEntries;
for (i = 0; i < MAX_COIN_MAP; i++, coinThing++) for (i = 0; i < MAX_COIN_MAP; i++, entry++)
{ {
if (strcmp(coinThing->mapName, "") == 0) if (strcmp(entry->mapName, "") == 0)
break; break;
} }
// "Can't find location for coin flag" // "Can't find location for coin flag"
assert(245, i < MAX_COIN_MAP, "コインフラグの保存場所がみつかりません"); assert(245, i < MAX_COIN_MAP, "コインフラグの保存場所がみつかりません");
// Init CoinThing // Init coin entry
strcpy(coinThing->mapName, gp->mapName); strcpy(entry->mapName, gp->mapName);
wp->coinId = 0; wp->coinId = 0;
} }
@ -207,21 +203,21 @@ s32 func_80038204()
return id; return id;
} }
void func_800383a0(s32 id) void swCoinSet(s32 id)
{ {
s32 i; s32 i;
CoinThing * coinThing; SwCoinEntry * entry;
coinThing = gp->coinThings; entry = gp->coinEntries;
// Skip if bad id // Skip if bad id
if (id == -1) if (id == -1)
return; return;
// Try find CoinThing for this map // Try find coin entry for this map
for (i = 0; i < MAX_COIN_MAP; i++, coinThing++) for (i = 0; i < MAX_COIN_MAP; i++, entry++)
{ {
if (strcmp(gp->mapName, coinThing->mapName) == 0) if (strcmp(gp->mapName, entry->mapName) == 0)
break; break;
} }
@ -229,24 +225,24 @@ void func_800383a0(s32 id)
assert(269, i < MAX_COIN_MAP, "フラグがエントリされていません"); assert(269, i < MAX_COIN_MAP, "フラグがエントリされていません");
// Turn on bitflag // Turn on bitflag
coinThing->coinFlags[id / 32] |= 1 << (id % 32); entry->coinFlags[id / 32] |= 1 << (id % 32);
} }
void func_80038478(s32 id) void swCoinClear(s32 id)
{ {
s32 i; s32 i;
CoinThing * coinThing; SwCoinEntry * entry;
coinThing = gp->coinThings; entry = gp->coinEntries;
// Skip if bad id // Skip if bad id
if (id == -1) if (id == -1)
return; return;
// Try find CoinThing for this map // Try find coin entry for this map
for (i = 0; i < MAX_COIN_MAP; i++, coinThing++) for (i = 0; i < MAX_COIN_MAP; i++, entry++)
{ {
if (strcmp(gp->mapName, coinThing->mapName) == 0) if (strcmp(gp->mapName, entry->mapName) == 0)
break; break;
} }
@ -254,24 +250,24 @@ void func_80038478(s32 id)
assert(286, i < MAX_COIN_MAP, "フラグがエントリされていません"); assert(286, i < MAX_COIN_MAP, "フラグがエントリされていません");
// Turn off bitflag // Turn off bitflag
coinThing->coinFlags[id / 32] &= ~(1 << (id % 32)); entry->coinFlags[id / 32] &= ~(1 << (id % 32));
} }
bool func_80038550(s32 id) bool swCoinGet(s32 id)
{ {
s32 i; s32 i;
CoinThing * coinThing; SwCoinEntry * entry;
coinThing = gp->coinThings; entry = gp->coinEntries;
// Skip if bad id // Skip if bad id
if (id == -1) if (id == -1)
return false; return false;
// Try find CoinThing for this map // Try find coin entry for this map
for (i = 0; i < MAX_COIN_MAP; i++, coinThing++) for (i = 0; i < MAX_COIN_MAP; i++, entry++)
{ {
if (strcmp(gp->mapName, coinThing->mapName) == 0) if (strcmp(gp->mapName, entry->mapName) == 0)
break; break;
} }
@ -279,51 +275,55 @@ bool func_80038550(s32 id)
assert(303, i < MAX_COIN_MAP, "フラグがエントリされていません"); assert(303, i < MAX_COIN_MAP, "フラグがエントリされていません");
// Check bitflag // Check bitflag
if ((coinThing->coinFlags[id / 32] & 1 << (id % 32)) != 0) if ((entry->coinFlags[id / 32] & 1 << (id % 32)) != 0)
return true; return true;
else else
return false; return false;
} }
void func_8003863c() void swResetCoinId()
{ {
wp->coinId = 0; wp->coinId = 0;
} }
void func_8003864c() void swResetGameCoinId()
{ {
wp->gameCoinId = 0; wp->gameCoinId = 0;
} }
s32 func_8003865c(void) s32 swGetGameCoinId()
{ {
char *mapName;
u32 i; u32 i;
s32 output = 0; s32 id;
id = 0;
// Skip if in wrong sequence
if (seqGetSeq() != SEQ_MAPCHANGE) if (seqGetSeq() != SEQ_MAPCHANGE)
return -1; return -1;
mapName = gp->mapName; // Try find assign_tbl entry for this map
for (i = 0; i < MAX_COIN_MAP; i++) for (i = 0; i < MAX_COIN_MAP; i++)
{ {
if (strcmp(mapName, assign_tbl[i].mapName) == 0) if (strcmp(gp->mapName, assign_tbl[i].mapName) == 0)
break; break;
output += assign_tbl[i].num; id += assign_tbl[i].num;
} }
// Skip if not found
if (i >= MAX_COIN_MAP) if (i >= MAX_COIN_MAP)
return -1; return -1;
output += wp->gameCoinId++; // Increment game coin id
id += wp->gameCoinId++;
// "Coin flags have overflowed" // "Coin flags have overflowed"
assert(505, (wp->gameCoinId-1) < assign_tbl[i].num, "コインのフラグが溢れました"); assert(505, (wp->gameCoinId-1) < assign_tbl[i].num, "コインのフラグが溢れました");
return output;
return id;
} }
bool func_8003875c(s32 id) bool swGameCoinGet(s32 id)
{ {
s32 idx; s32 idx;
s32 bit; s32 bit;
@ -339,7 +339,7 @@ bool func_8003875c(s32 id)
bit = id % 8; bit = id % 8;
// Map id to GSW // Map id to GSW
var = lbl_80325cb8[idx] - GSW(0); var = gameCoinGswMap[idx] - GSW(0);
if (var == 0) if (var == 0)
val = gp->gsw0; val = gp->gsw0;
else else
@ -349,7 +349,7 @@ bool func_8003875c(s32 id)
return ((val & (1 << bit)) != 0); return ((val & (1 << bit)) != 0);
} }
void func_800387d8(s32 id) void swGameCoinSet(s32 id)
{ {
s32 idx; s32 idx;
s32 num; s32 num;
@ -366,7 +366,7 @@ void func_800387d8(s32 id)
bit = id % 8; bit = id % 8;
// Map id to GSW // Map id to GSW
var = lbl_80325cb8[idx] - GSW(0); var = gameCoinGswMap[idx] - GSW(0);
if (var == 0) if (var == 0)
temp = gp->gsw0; temp = gp->gsw0;
else else