388 lines
8.9 KiB
C
388 lines
8.9 KiB
C
#include <ultra64.h>
|
|
#include "constants.h"
|
|
#include "constants.h"
|
|
#include "game/camdraw.h"
|
|
#include "game/cheats.h"
|
|
#include "game/player.h"
|
|
#include "game/savebuffer.h"
|
|
#include "game/filelist.h"
|
|
#include "game/bg.h"
|
|
#include "game/challenge.h"
|
|
#include "game/training.h"
|
|
#include "game/gamefile.h"
|
|
#include "game/mplayer/mplayer.h"
|
|
#include "game/pak.h"
|
|
#include "game/options.h"
|
|
#include "game/utils.h"
|
|
#include "bss.h"
|
|
#include "lib/fault.h"
|
|
#include "lib/joy.h"
|
|
#include "lib/snd.h"
|
|
#include "lib/mema.h"
|
|
#include "data.h"
|
|
#include "types.h"
|
|
|
|
s32 var800a2330[5];
|
|
|
|
struct filelist *g_FileLists[MAX_PLAYERS] = { NULL };
|
|
bool var80075bd0[] = { true, true, true, true };
|
|
bool var80075be0[] = { false, false, false, false };
|
|
u32 var80075bf0 = false;
|
|
|
|
void func0f110bf0(void)
|
|
{
|
|
// empty
|
|
}
|
|
|
|
void func0f110bf8(void)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i < ARRAYCOUNT(g_FileLists); i++) {
|
|
if (g_FileLists[i] != NULL) {
|
|
memaFree(g_FileLists[i], align16(sizeof(struct filelist)));
|
|
g_FileLists[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Allocate and build a file list.
|
|
*/
|
|
void filelistCreate(s32 listnum, u8 filetype)
|
|
{
|
|
if (g_FileLists[listnum] == NULL) {
|
|
bgGarbageCollectRooms(align16(sizeof(struct filelist)), 1);
|
|
g_FileLists[listnum] = memaAlloc(align16(sizeof(struct filelist)));
|
|
}
|
|
|
|
g_FileLists[listnum]->timeuntilupdate = 1;
|
|
g_FileLists[listnum]->filetype = filetype;
|
|
|
|
if (var80062944 == 0) {
|
|
joy0001398c(3);
|
|
}
|
|
|
|
var80062944 = 1;
|
|
}
|
|
|
|
s32 filelistFindOrCreate(u8 filetype)
|
|
{
|
|
s32 bestindex = -1;
|
|
s32 i;
|
|
|
|
for (i = 0; i < ARRAYCOUNT(g_FileLists); i++) {
|
|
if (g_FileLists[i]) {
|
|
if (g_FileLists[i]->filetype == filetype) {
|
|
return i;
|
|
}
|
|
} else {
|
|
if (bestindex == -1) {
|
|
bestindex = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bestindex >= 0) {
|
|
filelistCreate(bestindex, filetype);
|
|
return bestindex;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
void func0f110d90(s32 device)
|
|
{
|
|
var800a2330[device] = -1;
|
|
}
|
|
#endif
|
|
|
|
void filelistsTick(void)
|
|
{
|
|
u32 updateall;
|
|
u32 update;
|
|
s32 i;
|
|
static bool var80075bf4 = false;
|
|
|
|
if (!var80075bf4) {
|
|
for (i = 0; i < ARRAYCOUNT(var800a2330); i++) {
|
|
var800a2330[i] = -1;
|
|
}
|
|
|
|
var80075bf4 = true;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
for (i = 0, updateall = false; i < ARRAYCOUNT(var800a2330); i++) {
|
|
if (pak0f1167d8(i) && var800a2330[i] != pakGetUnk264(i)) {
|
|
updateall = true;
|
|
var800a2330[i] = pakGetUnk264(i);
|
|
}
|
|
}
|
|
#else
|
|
for (i = 0, updateall = false; i < ARRAYCOUNT(var800a2330); i++) {
|
|
s32 tmp = pakGetUnk264(i);
|
|
|
|
pak0f11698c(i);
|
|
|
|
if (pak0f1167d8(i)) {
|
|
tmp = 0;
|
|
}
|
|
|
|
if (var800a2330[i] != tmp) {
|
|
updateall = true;
|
|
var800a2330[i] = tmp;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
for (i = 0; i < ARRAYCOUNT(g_FileLists); i++) {
|
|
if (g_FileLists[i] != NULL) {
|
|
g_FileLists[i]->updatedthisframe = false;
|
|
|
|
update = updateall;
|
|
|
|
if (g_FileLists[i]->timeuntilupdate > 0) {
|
|
g_FileLists[i]->timeuntilupdate--;
|
|
|
|
if (g_FileLists[i]->timeuntilupdate == 0) {
|
|
update = true;
|
|
}
|
|
}
|
|
|
|
if (var80075bd0[g_FileLists[i]->filetype]) {
|
|
update = true;
|
|
}
|
|
|
|
if (update) {
|
|
osSyncPrintf("Rebuilding pakWad %d:\n", i);
|
|
filelistUpdate(g_FileLists[i]);
|
|
g_FileLists[i]->updatedthisframe = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < ARRAYCOUNT(var80075bd0); i++) {
|
|
var80075bd0[i] = false;
|
|
}
|
|
}
|
|
|
|
void filelistUpdate(struct filelist *list)
|
|
{
|
|
const u32 sp3a88[] = {
|
|
PAKFILETYPE_GAME,
|
|
PAKFILETYPE_MPSETUP,
|
|
PAKFILETYPE_MPPLAYER,
|
|
PAKFILETYPE_CAMERA,
|
|
};
|
|
|
|
s32 sp1288[2560];
|
|
u32 spa88[512];
|
|
s8 filedevices[2560];
|
|
s32 i;
|
|
s32 j;
|
|
s32 ret;
|
|
s32 len;
|
|
|
|
// Display order means game pak then controller paks
|
|
// Device order means controller paks then game pak (ie. SAVEDEVICE constant order)
|
|
|
|
// Mapping of display order to device order
|
|
const s8 dis2dev[] = {
|
|
SAVEDEVICE_GAMEPAK,
|
|
SAVEDEVICE_CONTROLLERPAK1,
|
|
SAVEDEVICE_CONTROLLERPAK2,
|
|
SAVEDEVICE_CONTROLLERPAK3,
|
|
SAVEDEVICE_CONTROLLERPAK4,
|
|
};
|
|
|
|
// Mapping of device order to display order
|
|
const s8 dev2dis[] = { 1, 2, 3, 4, /* game pak */ 0 };
|
|
|
|
list->numdevices = 0;
|
|
|
|
// Iterating in display order (game pak then controller paks)
|
|
for (i = 0, len = 0; i < ARRAYCOUNT(dis2dev); i++) {
|
|
list->unk305[dis2dev[i]] = 0;
|
|
list->devicestartindexes[i] = -1;
|
|
|
|
ret = pakGetFileIdsByType(dis2dev[i], sp3a88[list->filetype], spa88);
|
|
|
|
if (ret == 0) {
|
|
// No error
|
|
for (j = 0; spa88[j] != 0; j++) {
|
|
sp1288[len] = spa88[j];
|
|
filedevices[len] = dis2dev[i];
|
|
len++;
|
|
}
|
|
|
|
list->spacesfree[dis2dev[i]] = 0;
|
|
|
|
if (list->filetype == FILETYPE_CAMERA) {
|
|
list->spacesfree[dis2dev[i]] = pakGetNumFreeCameraSpacesInPak(dis2dev[i]);
|
|
}
|
|
|
|
list->deviceguids[dis2dev[i]].fileid = 0;
|
|
list->deviceguids[dis2dev[i]].deviceserial = pakGetSerial(dis2dev[i]);
|
|
} else {
|
|
// PFS error?
|
|
list->spacesfree[dis2dev[i]] = -1;
|
|
|
|
if (ret == 13) {
|
|
list->timeuntilupdate = 5;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (len);
|
|
|
|
list->numfiles = 0;
|
|
|
|
// Iterating files
|
|
for (i = 0; i < len; i++) {
|
|
struct filelistfile *file = &list->files[list->numfiles];
|
|
s32 ret = pakReadBodyAtGuid(filedevices[i], sp1288[i], file->name, sizeof(file->name));
|
|
|
|
if (ret);
|
|
|
|
if (ret == 0) {
|
|
// No error
|
|
if (list->devicestartindexes[dev2dis[filedevices[i]]] == -1) {
|
|
list->numdevices++;
|
|
list->devicestartindexes[dev2dis[filedevices[i]]] = list->numfiles;
|
|
}
|
|
|
|
file->deviceserial = pakGetSerial(filedevices[i]);
|
|
file->fileid = sp1288[i];
|
|
|
|
list->numfiles++;
|
|
} else if (ret == 10) {
|
|
// PFS_ERR_ID_FATAL?
|
|
list->unk305[filedevices[i]]++;
|
|
|
|
if (list->unk305[filedevices[i]] >= 2) {
|
|
list->spacesfree[filedevices[i]]++;
|
|
|
|
if (list->deviceguids[filedevices[i]].fileid == 0) {
|
|
list->deviceguids[filedevices[i]].fileid = sp1288[i];
|
|
list->deviceguids[filedevices[i]].deviceserial = pakGetSerial(filedevices[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void pheadAllocateTextures(s32 playernum, struct perfectheadtexturelist *textures)
|
|
{
|
|
s32 i;
|
|
s32 j;
|
|
s32 k;
|
|
|
|
if (g_Menus[playernum].fm.headtextures == NULL) {
|
|
if (textures == NULL) {
|
|
g_Menus[playernum].fm.unke40_01 = true;
|
|
bgGarbageCollectRooms(align16(sizeof(struct perfectheadtexturelist)), 1);
|
|
g_Menus[playernum].fm.headtextures = memaAlloc(align16(sizeof(struct perfectheadtexturelist)));
|
|
} else {
|
|
g_Menus[playernum].fm.headtextures = textures;
|
|
g_Menus[playernum].fm.unke40_01 = false;
|
|
}
|
|
}
|
|
|
|
if (g_Menus[playernum].fm.headtextures == NULL) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
faultAssert("tc != NULL", "gamefile.c", 458);
|
|
#else
|
|
faultAssert("tc != NULL", "gamefile.c", 450);
|
|
#endif
|
|
}
|
|
|
|
for (i = 0; i != ARRAYCOUNT(g_Menus[playernum].fm.headtextures->fileguids); i++) {
|
|
g_Menus[playernum].fm.headtextures->fileguids[i].fileid = 0;
|
|
g_Menus[playernum].fm.headtextures->fileguids[i].deviceserial = 0;
|
|
}
|
|
|
|
g_Menus[playernum].fm.headtextures->lastupdated240 = 0;
|
|
|
|
g_Menus[playernum].fm.headtextures->selectedtexture.width = 16;
|
|
g_Menus[playernum].fm.headtextures->selectedtexture.height = 16;
|
|
g_Menus[playernum].fm.headtextures->selectedtexture.level = 0;
|
|
g_Menus[playernum].fm.headtextures->selectedtexture.format = G_IM_FMT_I;
|
|
g_Menus[playernum].fm.headtextures->selectedtexture.depth = 0;
|
|
g_Menus[playernum].fm.headtextures->selectedtexture.s = 0;
|
|
g_Menus[playernum].fm.headtextures->selectedtexture.t = 1;
|
|
g_Menus[playernum].fm.headtextures->selectedtexture.unk0b = 0;
|
|
|
|
for (j = 0; j < 16; j++) {
|
|
for (k = 0; k < 0x80; k++) {
|
|
g_Menus[playernum].fm.headtextures->unk000[j][k] = k & 0xff;
|
|
}
|
|
}
|
|
}
|
|
|
|
void pheadFreeTextures(s32 playernum)
|
|
{
|
|
if (g_Menus[playernum].fm.headtextures != NULL) {
|
|
if (g_Menus[playernum].fm.unke40_01) {
|
|
memaFree(g_Menus[playernum].fm.headtextures, align16(sizeof(struct perfectheadtexturelist)));
|
|
}
|
|
|
|
g_Menus[playernum].fm.headtextures = NULL;
|
|
}
|
|
}
|
|
|
|
struct textureconfig *pheadGetTexture(s32 playernum, s32 fileid, u16 deviceserial)
|
|
{
|
|
s32 i;
|
|
s32 freeslot = -1;
|
|
s32 indextouse = -1;
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
if (g_Menus[playernum].fm.headtextures->fileguids[i].fileid == fileid
|
|
&& g_Menus[playernum].fm.headtextures->fileguids[i].deviceserial == deviceserial) {
|
|
indextouse = i;
|
|
break;
|
|
}
|
|
|
|
if (g_Menus[playernum].fm.headtextures->fileguids[i].fileid == 0) {
|
|
if (g_Menus[playernum].fm.headtextures->fileguids[i].deviceserial == 0) {
|
|
freeslot = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (indextouse == -1) {
|
|
s8 device = pakFindBySerial(deviceserial);
|
|
|
|
if (device < 0) {
|
|
return NULL;
|
|
}
|
|
|
|
if (freeslot == -1) {
|
|
return NULL;
|
|
}
|
|
|
|
if (g_Vars.thisframestart240 - g_Menus[playernum].fm.headtextures->lastupdated240 < 20) {
|
|
return NULL;
|
|
}
|
|
|
|
g_Menus[playernum].fm.headtextures->lastupdated240 = g_Vars.thisframestart240;
|
|
|
|
func0f15015c(device, fileid, g_Menus[playernum].fm.headtextures->unk000[freeslot]);
|
|
|
|
g_Menus[playernum].fm.headtextures->fileguids[freeslot].fileid = fileid;
|
|
g_Menus[playernum].fm.headtextures->fileguids[freeslot].deviceserial = deviceserial;
|
|
|
|
indextouse = freeslot;
|
|
}
|
|
|
|
if (indextouse == -1) {
|
|
return NULL;
|
|
}
|
|
|
|
g_Menus[playernum].fm.headtextures->selectedtexture.textureptr = g_Menus[playernum].fm.headtextures->unk000[indextouse];
|
|
|
|
return &g_Menus[playernum].fm.headtextures->selectedtexture;
|
|
}
|