2378 lines
68 KiB
C
2378 lines
68 KiB
C
#include "menuman.h"
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
|
||
#include "common.h"
|
||
#include "game/game.h"
|
||
#include "menu/radio.h"
|
||
#include "linkvar.h"
|
||
#include "libdg/libdg.h"
|
||
#include "libgv/libgv.h"
|
||
#include "libgcl/libgcl.h"
|
||
#include "memcard/memcard.h"
|
||
#include "mts/mts.h"
|
||
#include "mts/taskid.h"
|
||
#include "sd/g_sound.h"
|
||
|
||
//------------------------------------------------------------------------------
|
||
// gp
|
||
int SECTION(".sbss") dword_800ABB44;
|
||
int SECTION(".sbss") dword_800ABB48;
|
||
DATA_INFO *SECTION(".sbss") data_info;
|
||
void *SECTION(".sbss") stack_800ABB50;
|
||
int SECTION(".sbss") dword_800ABB54;
|
||
int SECTION(".sbss") dword_800ABB58;
|
||
int SECTION(".sbss") dword_800ABB5C;
|
||
int SECTION(".sbss") mcd_last_check_800ABB60[2];
|
||
MEM_CARD *SECTION(".sbss") mcd_last_file_800ABB68[2];
|
||
SELECT_INFO *SECTION(".sbss") dword_800ABB70;
|
||
SELECT_INFO *SECTION(".sbss") dword_800ABB74;
|
||
SELECT_INFO *SECTION(".sbss") dword_800ABB78;
|
||
RadioFileModeStru_800ABB7C *SECTION(".sbss") stru_800ABB7C;
|
||
int SECTION(".sbss") dword_800ABB80;
|
||
int SECTION(".sbss") dword_800ABB84;
|
||
SELECT_INFO *SECTION(".sbss") dword_800ABB88;
|
||
int SECTION(".sbss") dword_800ABB8C;
|
||
int SECTION(".sbss") dword_800ABB90;
|
||
int SECTION(".sbss") dword_800ABB94;
|
||
//------------------------------------------------------------------------------
|
||
|
||
extern char *MGS_MemoryCardName; /* in main.c */
|
||
|
||
extern char aRequestX[];
|
||
extern char aResultX[];
|
||
|
||
int clutsAndIcons_8009E774[6][40] = {
|
||
{
|
||
// CLUT for icon 1 (8 * 4 bytes = 32 bytes)
|
||
0x24A51421, 0x45AD3529, 0x88A5631, 0x217414EF, 0x363929D6, 0x10750C13, 0x195A14D8, 0xEEB19BC,
|
||
// Icon 1 (32 * 4 bytes = 128 bytes): Snake
|
||
0x12211, 0xEA00310, 0x20000000, 0xEC00331, 0x23210012, 0xEB20243, 0x33332213, 0xEA10134,
|
||
0x44422233, 0xEA10123, 0x34322343, 0xED11212, 0x24444443, 0xEE02221, 0x24444343, 0xEE30132,
|
||
0x23444233, 0xEE00133, 0x22334301, 0xEB00123, 0x21224420, 0xD000113, 0x22100100, 0xA100202,
|
||
0x32112344, 0x1100201, 0x23233200, 0x1000200, 0x2212222, 0x1000220, 0, 0,
|
||
},
|
||
{
|
||
// CLUT for icon 2
|
||
0x24A51421, 0x45AD3529, 0x88A5631, 0x217414EF, 0x363929D6, 0x10750C13, 0x195A14D8, 0xEEB19BC,
|
||
// Icon 2: Meryl
|
||
0x11124444, 0x2221131, 0x21000134, 0x2210222, 0x1114, 0x1230, 0x10000124, 0x241,
|
||
0x11123234, 0x20234, 0x43334444, 0x10234, 0x44444444, 0x221233, 0x44444444, 0x1011133,
|
||
0x34444444, 0x2100123, 0x34444334, 0x1110023, 0x33444421, 0x1000012, 0x33433443, 0x100002,
|
||
0x23320211, 0xB001001, 0x13333233, 0xAC10000, 0x1333322, 0xCB10100, 0, 0,
|
||
},
|
||
{
|
||
// CLUT for icon 3
|
||
0x24A51421, 0x45AD3529, 0x88A5631, 0x217414EF, 0x363929D6, 0x10750C13, 0x195A14D8, 0xEEB19BC,
|
||
// Icon 3: Otacon
|
||
0x1343023, 0x1102021, 0x13444312, 0x1001020, 0x3444301, 0x120, 0x22343113, 0x10021,
|
||
0x32211213, 0x10012, 0x33334433, 0x21002, 0x24444433, 0x1002002, 0x24444334, 0x2210001,
|
||
0x23444314, 0xB100010, 0x12444302, 0xDA10011, 0x22344421, 0xEBA0002, 0x22212333, 0xEEC1001,
|
||
0x21310100, 0xEC10100, 0x12132344, 0xC312200, 0x2112222, 0x4233101, 0, 0,
|
||
},
|
||
{
|
||
// CLUT for icon 4
|
||
0x2CA51C21, 0x456B3908, 0x5E3151CE, 0x217414EF, 0x363929D6, 0x10550C13, 0x151814B7, 0x19BC195A,
|
||
// Icon 4: Ninja
|
||
0x34455555, 0xFA12022, 0x255300, 0xFA12300, 0x241CD, 0xFA12240, 0x21000BDA, 0xFA11234,
|
||
0x445521CD, 0xFB11223, 0x34455300, 0xFDA1123, 0x33445552, 0xFFA1122, 0x33445551, 0xFFA1112,
|
||
0x12344551, 0xFFB1221, 0x31344551, 0xFFDA122, 0x31334451, 0xFFFA112, 0x22014451, 0xFFFB012,
|
||
0x24213451, 0xFFFB111, 0x22313441, 0xFFFB201, 0x22312341, 0xFFFA310, 0, 0,
|
||
},
|
||
{
|
||
// CLUT for icon 5
|
||
0x14A90425, 0x35B1252D, 0x88A4635, 0x217414EF, 0x363929D6, 0x49035844, 0x2A4139A2, 0x1E8316E0,
|
||
// Icon 5: Mei Ling
|
||
0x10013444, 0xE021020, 0x12221234, 0xA010031, 0x12224, 0x32, 0x10001224, 0x200030,
|
||
0x10022324, 0x410332, 0x32233434, 0x210333, 0x44444444, 0x110233, 0x44444444, 0xA010133,
|
||
0x44444434, 0xCA10133, 0x34444432, 0xECBA023, 0x34433443, 0xEEDD013, 0x33421211, 0xEEED102,
|
||
0x23333222, 0xEEEC101, 0x12334310, 0xEED0100, 0x1233444, 0xEEA1002, 0, 0,
|
||
},
|
||
{
|
||
// CLUT for icon 6
|
||
0x14A90425, 0x35B1252D, 0x88A4635, 0x217414EF, 0x363929D6, 0x44693427, 0x60CD508B, 0x64896CEF,
|
||
// Icon 6: Campbell
|
||
0x11001123, 0xED00210, 0x10000003, 0xEB01100, 0x11201013, 0xB200210, 0x12212124, 0xB020221,
|
||
0x22322234, 0xC211123, 0x44322144, 0xDB10123, 0x33321234, 0xEC01012, 0x23211023, 0xEEB0112,
|
||
0x22122102, 0xEED1121, 0x21222332, 0xEED2122, 0x10121100, 0xEEC0122, 0x10123433, 0xEEA0021,
|
||
0x12222100, 0xEC00021, 0x1221111, 0xEA00102, 0x22222333, 0xB000301, 0, 0
|
||
}
|
||
};
|
||
|
||
extern MenuWork gMenuWork_800BD360;
|
||
|
||
extern const int dword_800120B4[];
|
||
extern const int dword_800120CC[];
|
||
extern const int dword_800120E4[];
|
||
|
||
extern char memoryCardFileName[];
|
||
char memoryCardFileName[] = "BISLPM-99999 ";
|
||
|
||
STATIC int dword_800AB6EC = 0;
|
||
STATIC int dword_800AB6F0 = -1;
|
||
STATIC int dword_800AB6F4 = 0;
|
||
|
||
static inline KCB* GET_KCB( MenuWork *work )
|
||
{
|
||
return work->field_214_font;
|
||
}
|
||
|
||
STATIC int saveFile_8004983C(struct MEM_CARD *pMemcard)
|
||
{
|
||
int size;
|
||
int hours, minutes;
|
||
int c99;
|
||
int file;
|
||
char *buffer, *buffer_copy;
|
||
int success;
|
||
int retries;
|
||
int difficulty;
|
||
int flags1, flags2;
|
||
int i, idx;
|
||
|
||
GM_PadResetDisable = TRUE;
|
||
|
||
size = data_info->blocks_count * MC_BLOCK_SIZE;
|
||
buffer = GV_AllocMemory(GV_PACKET_MEMORY0, size);
|
||
if (!buffer)
|
||
{
|
||
printf("NO MEMORY FOR FILE BODY\n");
|
||
}
|
||
|
||
GV_ZeroMemory(buffer, size);
|
||
|
||
buffer[0] = 'S';
|
||
buffer[1] = 'C';
|
||
buffer[2] = 0x11; // static icon
|
||
buffer[3] = data_info->blocks_count;
|
||
|
||
idx = data_info->field_0[1];
|
||
buffer_copy = buffer;
|
||
c99 = 99;
|
||
|
||
if (idx == 0)
|
||
{
|
||
idx = GM_BonusItemsFlag;
|
||
flags1 = GM_BonusItemsFlag;
|
||
|
||
if (flags1 >= 4)
|
||
{
|
||
idx = 3;
|
||
if (flags1 == 6)
|
||
{
|
||
idx = 0;
|
||
}
|
||
}
|
||
|
||
flags2 = flags1 | ((GM_CurrentDiskFlag - 1) * 8);
|
||
}
|
||
else
|
||
{
|
||
flags2 = idx;
|
||
}
|
||
|
||
// 96: start position (offset) of CLUT.
|
||
// 160 = 32 + 128 = CLUT + icon
|
||
// The save data title, which comes before the CLUT, is set few lines below.
|
||
memcpy(buffer_copy + 96, clutsAndIcons_8009E774[idx], 160);
|
||
|
||
hours = GM_TotalHours;
|
||
minutes = GM_TotalSeconds / 60;
|
||
if (hours > 99)
|
||
{
|
||
minutes = hours = c99;
|
||
}
|
||
|
||
// 4: start position (offset) of save data title.
|
||
data_info->make_title(buffer_copy + 4, pMemcard, hours, minutes); // Calls makeTitle_8004D008()
|
||
strcpy(memoryCardFileName, MGS_MemoryCardName);
|
||
|
||
// 12: start position (offset) of the public part of the memory card file name.
|
||
memoryCardFileName[12] = data_info->field_0[0];
|
||
memoryCardFileName[13] = (hours / 10) + '0';
|
||
memoryCardFileName[14] = (hours % 10) + '0';
|
||
|
||
if (data_info->field_0[0] == 71)
|
||
{
|
||
difficulty = GM_DifficultyFlag;
|
||
}
|
||
else
|
||
{
|
||
difficulty = 0;
|
||
}
|
||
|
||
if (difficulty < 0)
|
||
{
|
||
difficulty = 0;
|
||
memoryCardFileName[13] |= 0x40;
|
||
}
|
||
|
||
memoryCardFileName[15] = ((minutes / 10) + '0') + ((difficulty & 2) << 5);
|
||
memoryCardFileName[16] = ((minutes % 10) + '0') + ((difficulty & 1) << 6);
|
||
memoryCardFileName[17] = flags2 + '@';
|
||
memoryCardFileName[18] = data_info->field_2 + '@';
|
||
|
||
if (data_info->field_0[0] == 71 && data_info->field_2 == 1)
|
||
{
|
||
memoryCardFileName[13] &= 0x40;
|
||
memoryCardFileName[13] |= 0x3A;
|
||
memoryCardFileName[14] = GM_LastResultFlag + '@';
|
||
}
|
||
|
||
for (i = 0; i < 16; i++)
|
||
{
|
||
flags1 = 0;
|
||
memoryCardFileName[19] = 'A' + i;
|
||
for (file = 0; file < pMemcard->file_count; file++)
|
||
{
|
||
if (!strcmp(pMemcard->files[file].name, memoryCardFileName))
|
||
{
|
||
flags1 = 1;
|
||
}
|
||
}
|
||
|
||
if (!flags1)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 256: start position (offset) of game data (as there is only one icon).
|
||
data_info->make_game_data(buffer_copy + 256); // Calls writeGameData()
|
||
|
||
// Now try to physically write to the memory card.
|
||
success = 0;
|
||
for (retries = 4; retries > 0; retries--)
|
||
{
|
||
memcard_write(pMemcard->card_idx, memoryCardFileName, 0, buffer, size);
|
||
while ((flags2 = memcard_get_status()) > 0)
|
||
{
|
||
mts_wait_vbl(2);
|
||
}
|
||
|
||
if (memcard_get_status() == 0)
|
||
{
|
||
// Mark successful write and stop retrying.
|
||
success = 1;
|
||
break;
|
||
}
|
||
}
|
||
|
||
GV_FreeMemory(GV_PACKET_MEMORY0, buffer);
|
||
GM_PadResetDisable = FALSE;
|
||
return success;
|
||
}
|
||
|
||
const char *saveCaptions_8009EB4C[] = {
|
||
"\x00", // Different from the other empty strings used below for some reason
|
||
// セーブが完了しました。 (Save completed.)
|
||
"\x82\x1b\xd0\x06\x82\x36\x81\x0c\x91\x07\x91\x08\x81\x17\x81\x3e\x81\x17\x81\x1f\xd0\x03",
|
||
// セーブできませんでした。 (Could not save.)
|
||
"\x82\x1b\xd0\x06\x82\x36\x81\x27\x81\x0d\x81\x3e\x81\x1b\x81\x53\x81\x27\x81\x17\x81\x1f\xd0\x03",
|
||
// エラーが発生しました。 (An error occurred.)
|
||
"\x82\x08\x82\x49\xd0\x06\x81\x0c\x90\x7e\x90\xca\x81\x17\x81\x3e\x81\x17\x81\x1f\xd0\x03",
|
||
// 空きブロックがたりません。 (Not enough empty blocks.)
|
||
"\x90\x92\x81\x0d\x82\x36\x82\x4d\xc2\x23\x82\x0f\x81\x0c\x81\x1f\x81\x4a\x81\x3e\x81\x1b\x81\x53\xd0\x03",
|
||
// メモリーカードが初期化されていません。 (Memory card is not initialized.)
|
||
"\x82\x41\x82\x42\x82\x4a\xd0\x06\x82\x0b\xd0\x06\x82\x29\x81\x0c\x91\x10\x91\x11\x90\x64\x81\x15\x81\x4c\x81\x26\x81\x04\x81\x3e\x81\x1b\x81\x53\xd0\x03",
|
||
// セーブしました。 (Saved.)
|
||
"\x82\x1b\xd0\x06\x82\x36\x81\x17\x81\x3e\x81\x17\x81\x1f\xd0\x03",
|
||
// フォーマットに失敗しました。 (Failed to format.)
|
||
"\x82\x35\xc2\x09\xd0\x06\x82\x3e\xc2\x23\x82\x28\x81\x2b\x91\x09\x91\x0a\x81\x17\x81\x3e\x81\x17\x81\x1f\xd0\x03",
|
||
// メモリーカードがさされていません。 (Memory card is not inserted.)
|
||
"\x82\x41\x82\x42\x82\x4a\xd0\x06\x82\x0b\xd0\x06\x82\x29\x81\x0c\x81\x15\x81\x15\x81\x4c\x81\x26\x81\x04\x81\x3e\x81\x1b\x81\x53\xd0\x03",
|
||
// セーブ中です。 (Saving.)
|
||
"\x82\x1b\xd0\x06\x82\x36\x90\xcd\x81\x27\x81\x19\xd0\x03",
|
||
// メモリーカードをチェックしています。 (Checking memory card.)
|
||
"\x82\x41\x82\x42\x82\x4a\xd0\x06\x82\x0b\xd0\x06\x82\x29\x81\x52\x82\x21\xc2\x07\xc2\x23\x82\x0f\x81\x17\x81\x26\x81\x04\x81\x3e\x81\x19\xd0\x03",
|
||
// フォーマットしています。 (Formatting.)
|
||
"\x82\x35\xc2\x09\xd0\x06\x82\x3e\xc2\x23\x82\x28\x81\x17\x81\x26\x81\x04\x81\x3e\x81\x19\xd0\x03",
|
||
};
|
||
|
||
const char *loadCaptions_8009EB7C[] = {
|
||
"\x00", // Different from the other empty strings used below for some reason
|
||
// ロードが完了しました。 (Load completed.)
|
||
"\x82\x4d\xd0\x06\x82\x29\x81\x0c\x91\x07\x91\x08\x81\x17\x81\x3e\x81\x17\x81\x1f\xd0\x03",
|
||
// ロードできませんでした。 (Could not load.)
|
||
"\x82\x4d\xd0\x06\x82\x29\x81\x27\x81\x0d\x81\x3e\x81\x1b\x81\x53\x81\x27\x81\x17\x81\x1f\xd0\x03",
|
||
// エラーが発生しました。 (An error occurred.)
|
||
"\x82\x08\x82\x49\xd0\x06\x81\x0c\x90\x7e\x90\xca\x81\x17\x81\x3e\x81\x17\x81\x1f\xd0\x03",
|
||
// セーブファイルがありません。 (There is no save file.)
|
||
"\x82\x1b\xd0\x06\x82\x36\x82\x35\xc2\x01\x82\x04\x82\x4b\x81\x0c\x81\x02\x81\x4a\x81\x3e\x81\x1b\x81\x53\xd0\x03",
|
||
// メモリーカードが初期化されていません。 (Memory card is not initialized.)
|
||
"\x82\x41\x82\x42\x82\x4a\xd0\x06\x82\x0b\xd0\x06\x82\x29\x81\x0c\x91\x10\x91\x11\x90\x64\x81\x15\x81\x4c\x81\x26\x81\x04\x81\x3e\x81\x1b\x81\x53\xd0\x03",
|
||
// ロードしました。 (Loaded.)
|
||
"\x82\x4d\xd0\x06\x82\x29\x81\x17\x81\x3e\x81\x17\x81\x1f\xd0\x03",
|
||
// フォーマットに失敗しました。 (Failed to format.)
|
||
"\x82\x35\xc2\x09\xd0\x06\x82\x3e\xc2\x23\x82\x28\x81\x2b\x91\x09\x91\x0a\x81\x17\x81\x3e\x81\x17\x81\x1f\xd0\x03",
|
||
// メモリーカードがさされていません。 (Memory card is not inserted.)
|
||
"\x82\x41\x82\x42\x82\x4a\xd0\x06\x82\x0b\xd0\x06\x82\x29\x81\x0c\x81\x15\x81\x15\x81\x4c\x81\x26\x81\x04\x81\x3e\x81\x1b\x81\x53\xd0\x03",
|
||
// ロード中です。 (Loading.)
|
||
"\x82\x4d\xd0\x06\x82\x29\x90\xcd\x81\x27\x81\x19\xd0\x03",
|
||
// メモリーカードをチェックしています。 (Checking memory card.)
|
||
"\x82\x41\x82\x42\x82\x4a\xd0\x06\x82\x0b\xd0\x06\x82\x29\x81\x52\x82\x21\xc2\x07\xc2\x23\x82\x0f\x81\x17\x81\x26\x81\x04\x81\x3e\x81\x19\xd0\x03",
|
||
// フォーマットしています。 (Formatting.)
|
||
"\x82\x35\xc2\x09\xd0\x06\x82\x3e\xc2\x23\x82\x28\x81\x17\x81\x26\x81\x04\x81\x3e\x81\x19\xd0\x03",
|
||
};
|
||
|
||
STATIC int loadFile_80049CE8(MEM_CARD *pMemcard, int idx)
|
||
{
|
||
int success;
|
||
int optionFlag;
|
||
short optionFlagTmp;
|
||
int retries;
|
||
void *buf;
|
||
|
||
GM_PadResetDisable = TRUE;
|
||
buf = GV_AllocMemory(GV_PACKET_MEMORY0, MC_BLOCK_SIZE);
|
||
if (buf == NULL)
|
||
{
|
||
printf("NO MEMORY FOR FILE BODY\n");
|
||
}
|
||
|
||
success = 0;
|
||
for (retries = 4; retries > 0; retries--)
|
||
{
|
||
memcard_read(pMemcard->card_idx, pMemcard->files[idx].name, 0, buf, MC_BLOCK_SIZE);
|
||
|
||
while (memcard_get_status() > 0)
|
||
{
|
||
mts_wait_vbl(2);
|
||
}
|
||
|
||
if (memcard_get_status() == 0)
|
||
{
|
||
optionFlagTmp = GM_OptionFlag & ~OPTION_RADAR_OFF;
|
||
optionFlag = optionFlagTmp;
|
||
// 256: start position (offset) of game data (as there is only one icon).
|
||
if (GCL_SetLoadFile(buf + 256) != 0)
|
||
{
|
||
success = 1;
|
||
if (optionFlag & OPTION_UNKNOWN_0010)
|
||
{
|
||
// 0xE100 == OPTION_ENGLISH | 0x2000 | OPTION_CAPTION_OFF | OPTION_SOUND_MONO
|
||
GM_OptionFlag = (GM_OptionFlag & ~0xE100) | (optionFlag & 0xE100);
|
||
}
|
||
if (optionFlag & OPTION_UNKNOWN_0008)
|
||
{
|
||
// 0x1007 == OPTION_SHUKAN_REVERSE | OPTION_BUTTON_MASK
|
||
GM_OptionFlag = (GM_OptionFlag & ~0x1007) | (optionFlag & 0x1007);
|
||
}
|
||
GM_OptionFlag &= ~(OPTION_UNKNOWN_0008 | OPTION_UNKNOWN_0010);
|
||
GCL_SaveLinkVar(&GM_OptionFlag);
|
||
if (GM_OptionFlag & OPTION_SOUND_MONO)
|
||
{
|
||
GM_SetSound(0xff000005, SD_ASYNC);
|
||
}
|
||
else
|
||
{
|
||
GM_SetSound(0xff000006, SD_ASYNC);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
GV_FreeMemory(GV_PACKET_MEMORY0, buf);
|
||
GM_PadResetDisable = FALSE;
|
||
return success;
|
||
}
|
||
|
||
const char *save_prompt_msg_jp_8009EBAC[] = {
|
||
// 上書きしてよろしいですか?
|
||
"\x91\x0b\x90\x27\x81\x0d\x81\x17\x81\x26\x81\x48\x81\x4d\x81\x17\x81\x04\x81\x27\x81\x19\x81\x0b\xc0\x3f",
|
||
// フォーマットしますか?
|
||
"\x82\x35\xc2\x09\xd0\x06\x82\x3e\xc2\x23\x82\x28\x81\x17\x81\x3e\x81\x19\x81\x0b\xc0\x3f",
|
||
};
|
||
|
||
const char *save_prompt_msg_en_8009EBB4[] = {"OVERWRITE OK?", "FORMAT OK?"};
|
||
|
||
STATIC int init_file_mode_helper_helper_helper3_80049E94(int param_1)
|
||
{
|
||
dword_800ABB58 = param_1;
|
||
printf("REQUEST %X\n", param_1);
|
||
mts_slp_tsk();
|
||
printf("RESULT %X\n", dword_800ABB5C);
|
||
return dword_800ABB5C;
|
||
}
|
||
|
||
STATIC int dword_800AB6FC = -1;
|
||
STATIC int dword_800AB700 = 0;
|
||
|
||
STATIC void init_file_mode_helper_helper_80049EDC(void)
|
||
{
|
||
int temp_a0;
|
||
int temp_a0_2;
|
||
int temp_s0;
|
||
int err;
|
||
int temp_v0;
|
||
int temp_v0_2;
|
||
int fidx;
|
||
int temp_v1;
|
||
int temp_v1_2;
|
||
int port;
|
||
int var_s2;
|
||
MEM_CARD *pMemcard;
|
||
int negone;
|
||
int one;
|
||
|
||
mts_set_vsync_task();
|
||
dword_800ABB54 = 1;
|
||
|
||
loop_3:
|
||
init_file_mode_helper_helper_helper3_80049E94(0x100000A);
|
||
|
||
temp_a0 = dword_800AB6FC;
|
||
var_s2 = 0;
|
||
|
||
if (temp_a0 == -1)
|
||
{
|
||
int mask;
|
||
dword_800AB700 = 0;
|
||
|
||
for (port = 0; port < 2; port++)
|
||
{
|
||
mask = 0x1000000;
|
||
temp_v0 = memcard_check(port);
|
||
temp_v1 = temp_v0 & 0xFF;
|
||
mcd_last_check_800ABB60[port] = temp_v1;
|
||
|
||
if ((temp_v0 & mask) && dword_800AB6F0 == port)
|
||
{
|
||
dword_800AB6F0 = -1;
|
||
}
|
||
|
||
if (temp_v1 != 3)
|
||
{
|
||
var_s2 += 1;
|
||
dword_800AB700 |= 1 << port;
|
||
}
|
||
}
|
||
|
||
if (var_s2 == 0)
|
||
{
|
||
init_file_mode_helper_helper_helper3_80049E94(0x41000008);
|
||
|
||
for (port = 0; port < 2; port++)
|
||
{
|
||
if ((memcard_check(port) & 0xFF) != 3)
|
||
{
|
||
dword_800ABB54 = 1;
|
||
goto loop_3;
|
||
}
|
||
}
|
||
|
||
dword_800ABB54 = 2;
|
||
dword_800AB6F0 = -1;
|
||
goto block_73;
|
||
}
|
||
|
||
dword_800ABB5C = -2;
|
||
dword_800ABB58 = 0x20000001;
|
||
dword_800AB700 &= ~0x80;
|
||
one = 1;
|
||
negone = -1;
|
||
|
||
loop_18:
|
||
for (port = 0; port < 2; port++)
|
||
{
|
||
temp_a0_2 = memcard_check(port) & 0xFF;
|
||
if (temp_a0_2 != mcd_last_check_800ABB60[port])
|
||
{
|
||
mcd_last_check_800ABB60[port] = temp_a0_2;
|
||
if (temp_a0_2 == 3)
|
||
{
|
||
dword_800AB700 &= ~(one << port);
|
||
if (dword_800AB6F0 == port)
|
||
{
|
||
dword_800AB6F0 = negone;
|
||
}
|
||
}
|
||
else if (temp_a0_2 != 0x80000000)
|
||
{
|
||
dword_800AB700 |= (one << port);
|
||
}
|
||
dword_800ABB54 = one;
|
||
dword_800AB700 |= 0x80;
|
||
}
|
||
}
|
||
|
||
temp_v1_2 = dword_800ABB5C;
|
||
|
||
if (temp_v1_2 >= 0)
|
||
{
|
||
if ((dword_800AB700 == 0) || !(dword_800AB700 & (one << temp_v1_2)))
|
||
{
|
||
dword_800AB6FC = negone;
|
||
dword_800AB6F0 = negone;
|
||
dword_800ABB54 = 1;
|
||
goto loop_3;
|
||
}
|
||
dword_800AB6FC = temp_v1_2;
|
||
if (dword_800AB6F0 != temp_v1_2)
|
||
{
|
||
dword_800AB6EC = negone;
|
||
}
|
||
dword_800AB6F0 = temp_v1_2;
|
||
goto block_34;
|
||
}
|
||
|
||
if (temp_v1_2 != negone)
|
||
{
|
||
block_34:
|
||
port = 0;
|
||
if (dword_800ABB5C == -2)
|
||
{
|
||
goto loop_18;
|
||
}
|
||
|
||
goto block_40;
|
||
}
|
||
init_file_mode_helper_helper_helper3_80049E94(0x80000000);
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
temp_v0_2 = memcard_check(temp_a0);
|
||
if (temp_v0_2 & 0x1000000)
|
||
{
|
||
dword_800AB6EC = -1;
|
||
}
|
||
temp_v0_2 &= 0xFF;
|
||
|
||
mcd_last_check_800ABB60[dword_800AB6FC] = temp_v0_2;
|
||
if (mcd_last_check_800ABB60[dword_800AB6FC] == 3)
|
||
{
|
||
dword_800AB6FC = -1;
|
||
dword_800AB6EC = -1;
|
||
goto loop_3;
|
||
}
|
||
|
||
block_40:
|
||
temp_s0 = mcd_last_check_800ABB60[dword_800AB6FC];
|
||
if (temp_s0 != 0x80000000)
|
||
{
|
||
if (temp_s0 == 1)
|
||
{
|
||
init_file_mode_helper_helper_helper3_80049E94(0x43000005);
|
||
if (dword_800ABB48 == 0)
|
||
{
|
||
if (init_file_mode_helper_helper_helper3_80049E94(0x10000001) == 0)
|
||
{
|
||
err = memcard_check(dword_800AB6FC) & 0xFF;
|
||
if (err != temp_s0)
|
||
{
|
||
init_file_mode_helper_helper_helper3_80049E94(0x45000003);
|
||
goto loop_3;
|
||
}
|
||
|
||
init_file_mode_helper_helper_helper3_80049E94(0x0100000B);
|
||
|
||
if (!memcard_format(dword_800AB6FC))
|
||
{
|
||
dword_800AB6FC = -1;
|
||
init_file_mode_helper_helper_helper3_80049E94(0x45000007);
|
||
goto block_72;
|
||
}
|
||
|
||
mcd_last_check_800ABB60[dword_800AB6FC] = memcard_check(dword_800AB6FC) & 0xFF;
|
||
|
||
if (mcd_last_check_800ABB60[dword_800AB6FC] == 0)
|
||
{
|
||
dword_800AB6F4 = err;
|
||
goto block_51;
|
||
}
|
||
else
|
||
{
|
||
init_file_mode_helper_helper_helper3_80049E94(0x45000003);
|
||
goto block_72;
|
||
}
|
||
}
|
||
|
||
dword_800ABB54 = 4;
|
||
dword_800AB6FC = -1;
|
||
goto loop_3;
|
||
}
|
||
else
|
||
{
|
||
dword_800ABB54 = 4;
|
||
dword_800AB6FC = -1;
|
||
goto loop_3;
|
||
}
|
||
}
|
||
block_51:
|
||
pMemcard = memcard_get_files(dword_800AB6FC);
|
||
mcd_last_file_800ABB68[dword_800AB6FC] = pMemcard;
|
||
|
||
if (pMemcard == NULL)
|
||
{
|
||
init_file_mode_helper_helper_helper3_80049E94(0x45000003);
|
||
goto loop_3;
|
||
}
|
||
|
||
loop_52:
|
||
fidx = init_file_mode_helper_helper_helper3_80049E94(0x20000000);
|
||
|
||
if (fidx < 0)
|
||
{
|
||
dword_800AB6FC = -1;
|
||
goto loop_3;
|
||
}
|
||
|
||
if (memcard_check(dword_800AB6FC) != 0)
|
||
{
|
||
init_file_mode_helper_helper_helper3_80049E94(0x45000003);
|
||
goto loop_3;
|
||
}
|
||
|
||
if (dword_800ABB48 == 0)
|
||
{
|
||
if (fidx < 16)
|
||
{
|
||
if (init_file_mode_helper_helper_helper3_80049E94(0x10000000) != 0)
|
||
{
|
||
goto loop_52;
|
||
}
|
||
|
||
if (memcard_check(dword_800AB6FC) != 0)
|
||
{
|
||
init_file_mode_helper_helper_helper3_80049E94(0x45000003);
|
||
goto loop_3;
|
||
}
|
||
|
||
if (memcard_delete(dword_800AB6FC, pMemcard->files[fidx].name) == 0)
|
||
{
|
||
init_file_mode_helper_helper_helper3_80049E94(0x45000003);
|
||
goto block_72;
|
||
}
|
||
|
||
pMemcard = memcard_get_files(dword_800AB6FC);
|
||
mcd_last_file_800ABB68[dword_800AB6FC] = pMemcard;
|
||
}
|
||
|
||
if (pMemcard->free_blocks == 0)
|
||
{
|
||
init_file_mode_helper_helper_helper3_80049E94(0x43200004);
|
||
goto block_72;
|
||
}
|
||
|
||
init_file_mode_helper_helper_helper3_80049E94(0x01000009);
|
||
|
||
if (saveFile_8004983C(pMemcard) != 0)
|
||
{
|
||
goto block_75;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
init_file_mode_helper_helper_helper3_80049E94(0x01000009);
|
||
|
||
if (loadFile_80049CE8(pMemcard, fidx) != 0)
|
||
{
|
||
goto block_69;
|
||
}
|
||
}
|
||
}
|
||
|
||
init_file_mode_helper_helper_helper3_80049E94(0x45000003);
|
||
goto block_72;
|
||
|
||
block_69:
|
||
dword_800ABB48 = 2;
|
||
block_75:
|
||
dword_800ABB54 = 0;
|
||
init_file_mode_helper_helper_helper3_80049E94(0xC1000001);
|
||
return;
|
||
|
||
block_72:
|
||
dword_800ABB54 = 5;
|
||
|
||
block_73:
|
||
init_file_mode_helper_helper_helper3_80049E94(0xC5000002);
|
||
}
|
||
}
|
||
|
||
STATIC void init_file_mode_helper_8004A424(int param_1)
|
||
{
|
||
int size = 2048;
|
||
|
||
stack_800ABB50 = GV_AllocMemory(GV_PACKET_MEMORY0, size);
|
||
|
||
if (!stack_800ABB50)
|
||
{
|
||
printf("NO MEMORY FOR STACK\n");
|
||
}
|
||
|
||
dword_800ABB48 = param_1;
|
||
mts_start_task(MTSID_MEMORY_CARD, init_file_mode_helper_helper_80049EDC, stack_800ABB50 + size, size);
|
||
}
|
||
|
||
const char *dword_8009EBBC[] = {
|
||
NULL,
|
||
NULL,
|
||
"COMPLETE",
|
||
NULL,
|
||
"ERROR"
|
||
};
|
||
|
||
// The small triangle above the files list suggesting that there are more entries.
|
||
Menu_Triangle upperTriangle_8009EBD0 = {155, 79, 160, 74, 165, 79, 0x80808080};
|
||
// The small triangle below the files list suggesting that there are more entries.
|
||
Menu_Triangle lowerTriangle_8009EBE0 = {156, 184, 160, 188, 164, 184, 0x80808080};
|
||
|
||
void move_coord(int *arr, int len)
|
||
{
|
||
int i;
|
||
|
||
for (i = 0; i < len; i++, arr += 2) {
|
||
arr[0] += arr[1];
|
||
}
|
||
}
|
||
|
||
STATIC void menu_radio_do_file_mode_helper2_helper_8004A4C4(MenuPrim *pGlue, RadioFileModeStruElem *pElem)
|
||
{
|
||
RadioFileModeUnk1 *pUnk;
|
||
TextConfig textConfig;
|
||
|
||
pUnk = pElem->field_C_unk1;
|
||
if (pElem->field_0 == 1)
|
||
{
|
||
move_coord(&pUnk->field_8, 2);
|
||
pUnk->field_18 = 0x3d482e;
|
||
}
|
||
textConfig.xpos = pUnk->field_8 >> 16;
|
||
textConfig.ypos = pUnk->field_10 >> 16; // pUnk->field_10 / 65536 wouldn't match
|
||
textConfig.flags = 0x12;
|
||
textConfig.colour = pUnk->field_18 | 0x66000000;
|
||
|
||
_menu_number_draw_string2(pGlue, &textConfig, (char *)pUnk->field_4); // TODO: Fix cast
|
||
}
|
||
|
||
STATIC void menu_radio_do_file_mode_helper4_helper_8004A54C(MenuPrim *pGlue, RadioFileModeStruElem *pElem)
|
||
{
|
||
LINE_F2 *pPrim;
|
||
RadioFileModeUnk1 *pUnk;
|
||
|
||
pUnk = pElem->field_C_unk1;
|
||
if (pElem->field_0 == 1)
|
||
{
|
||
move_coord(&pUnk->field_4, 4);
|
||
}
|
||
|
||
if (pUnk->field_4 != pUnk->field_14 || pUnk->field_C != pUnk->field_1C)
|
||
{
|
||
_NEW_PRIM(pPrim, pGlue);
|
||
|
||
LSTORE(pUnk->field_24, &pPrim->r0);
|
||
pPrim->x0 = pUnk->field_4 >> 16;
|
||
pPrim->y0 = pUnk->field_C >> 16;
|
||
pPrim->x1 = pUnk->field_14 >> 16;
|
||
pPrim->y1 = pUnk->field_1C >> 16; // pUnk->field_1C / 65536 wouldn't match
|
||
setLineF2(pPrim);
|
||
addPrim(pGlue->mPrimBuf.mOt, pPrim);
|
||
}
|
||
}
|
||
|
||
STATIC void sub_8004A648(MenuPrim *pGlue, RadioFileModeStruElem *pElem)
|
||
{
|
||
RadioFileModeUnk1 *pUnk;
|
||
int x, y, w, h;
|
||
TILE *pTile;
|
||
|
||
pUnk = pElem->field_C_unk1;
|
||
if (pElem->field_0 == 1)
|
||
{
|
||
move_coord(&pUnk->field_4, 4);
|
||
}
|
||
x = (pUnk->field_4 >> 16);
|
||
y = (pUnk->field_C >> 16);
|
||
w = pUnk->field_14 >> 16;
|
||
h = pUnk->field_1C >> 16;
|
||
x -= w / 2;
|
||
y -= h / 2;
|
||
|
||
_NEW_PRIM(pTile, pGlue);
|
||
|
||
LSTORE(0x72A452, &pTile->r0);
|
||
setTile(pTile);
|
||
pTile->x0 = x;
|
||
pTile->y0 = y;
|
||
pTile->w = w;
|
||
pTile->h = h;
|
||
setSemiTrans(pTile, 0);
|
||
addPrim(pGlue->mPrimBuf.mOt, pTile);
|
||
|
||
radio_draw_face_frame(pGlue, x, y, w, h);
|
||
radio_draw_face_frame(pGlue, x, y, w, h);
|
||
}
|
||
|
||
STATIC void menu_radio_do_file_mode_helper16_8004C164(MenuPrim *pGlue, SELECT_INFO *info);
|
||
|
||
STATIC void menu_radio_do_file_mode_helper3_helper_8004A790(MenuPrim *pGlue, RadioFileModeStruElem *pElem)
|
||
{
|
||
RadioFileModeUnk1 *pUnk;
|
||
|
||
pUnk = pElem->field_C_unk1;
|
||
if (pElem->field_0 == 1)
|
||
{
|
||
move_coord(&pUnk->field_4, 2);
|
||
}
|
||
|
||
*(short *)pUnk->field_14 = pUnk->field_4 >> 16; // TODO: Fix type of field_14
|
||
*(short *)(pUnk->field_14 + 2) = pUnk->field_C >> 16; // pUnk->field_C / 65536 wouldn't match
|
||
menu_radio_do_file_mode_helper16_8004C164(pGlue, (SELECT_INFO *)pUnk->field_14);
|
||
}
|
||
|
||
//file may be split here
|
||
|
||
STATIC void init_file_mode_helper2_8004A800(void)
|
||
{
|
||
int i;
|
||
|
||
stru_800ABB7C = (RadioFileModeStru_800ABB7C *)GV_AllocMemory(GV_PACKET_MEMORY0, sizeof(RadioFileModeStru_800ABB7C));
|
||
if (stru_800ABB7C == NULL)
|
||
{
|
||
printf("NO MEMORY FOR OBJ\n");
|
||
}
|
||
|
||
for (i = 0; i < 12; i++)
|
||
{
|
||
stru_800ABB7C->field_0_array[i].field_0 = 0;
|
||
}
|
||
}
|
||
|
||
STATIC void menu_radio_do_file_mode_helper_8004A858(void)
|
||
{
|
||
GV_FreeMemory(GV_PACKET_MEMORY0, stru_800ABB7C);
|
||
}
|
||
|
||
STATIC void menu_radio_do_file_mode_helper2_8004A87C(int idx, int param_2, int param_3, int divisor, int idx2)
|
||
{
|
||
RadioFileModeStruElem *pElem;
|
||
RadioFileModeUnk2 *pUnk;
|
||
|
||
pUnk = &stru_800ABB7C->field_c0_array[idx];
|
||
pElem = &stru_800ABB7C->field_0_array[idx];
|
||
|
||
// Callers call this function with: idx2 = -1 ... 4
|
||
pUnk->field_4 = dword_8009EBBC[idx2];
|
||
|
||
pElem->field_8_pFn = menu_radio_do_file_mode_helper2_helper_8004A4C4;
|
||
pElem->field_C_unk1 = (RadioFileModeUnk1 *)pUnk; // TODO: Fix cast
|
||
|
||
if (idx2 < 0)
|
||
{
|
||
pElem->field_0 = 0;
|
||
return;
|
||
}
|
||
|
||
if (divisor <= 0)
|
||
{
|
||
pUnk->field_8 = param_2 * 65536;
|
||
pUnk->field_10 = param_3 * 65536;
|
||
pElem->field_0 = 2;
|
||
}
|
||
else
|
||
{
|
||
pUnk->field_C = (param_2 * 65536 - pUnk->field_8) / divisor;
|
||
pUnk->field_14 = (param_3 * 65536 - pUnk->field_10) / divisor;
|
||
pElem->field_0 = 1;
|
||
}
|
||
|
||
pUnk->field_18 = 0x748956;
|
||
pElem->field_4 = divisor;
|
||
}
|
||
|
||
STATIC void menu_radio_do_file_mode_helper3_8004A994(int idx, int param_2, int param_3, int divisor, SELECT_INFO *field_14)
|
||
{
|
||
RadioFileModeUnk1 *pUnk;
|
||
RadioFileModeStruElem *pElem;
|
||
|
||
pElem = &stru_800ABB7C->field_0_array[idx];
|
||
pUnk = &stru_800ABB7C->field_220_unk1;
|
||
|
||
pElem->field_8_pFn = menu_radio_do_file_mode_helper3_helper_8004A790;
|
||
pElem->field_C_unk1 = pUnk;
|
||
|
||
if (divisor <= 0)
|
||
{
|
||
pUnk->field_4 = param_2 * 65536;
|
||
pUnk->field_C = param_3 * 65536;
|
||
pElem->field_0 = 2;
|
||
}
|
||
else
|
||
{
|
||
pUnk->field_8 = (param_2 * 65536 - pUnk->field_4) / divisor;
|
||
pUnk->field_10 = (param_3 * 65536 - pUnk->field_C) / divisor;
|
||
pElem->field_0 = 1;
|
||
}
|
||
|
||
pUnk->field_14 = (int)field_14;
|
||
pElem->field_4 = divisor;
|
||
}
|
||
|
||
STATIC void menu_radio_do_file_mode_helper4_8004AA68(int idx, int param_2, int param_3, int param_4, int param_5, int divisor)
|
||
{
|
||
RadioFileModeUnk1 *pUnk;
|
||
RadioFileModeStruElem *pElem;
|
||
|
||
pElem = &stru_800ABB7C->field_0_array[idx];
|
||
|
||
// callers to this function use idx in range 5..8
|
||
pUnk = &stru_800ABB7C->field_130_array[idx - 5]; // TODO: really -5?
|
||
|
||
pElem->field_8_pFn = menu_radio_do_file_mode_helper4_helper_8004A54C;
|
||
pElem->field_C_unk1 = pUnk;
|
||
if (divisor <= 0)
|
||
{
|
||
pUnk->field_4 = param_2 * 65536;
|
||
pUnk->field_C = param_3 * 65536;
|
||
pUnk->field_14 = param_4 * 65536;
|
||
pUnk->field_1C = param_5 * 65536;
|
||
pElem->field_0 = 2;
|
||
}
|
||
else
|
||
{
|
||
pUnk->field_8 = (param_2 * 65536 - pUnk->field_4) / divisor;
|
||
pUnk->field_10 = (param_3 * 65536 - pUnk->field_C) / divisor;
|
||
pUnk->field_18 = (param_4 * 65536 - pUnk->field_14) / divisor;
|
||
pUnk->field_20 = (param_5 * 65536 - pUnk->field_1C) / divisor;
|
||
pElem->field_0 = 1;
|
||
}
|
||
|
||
pUnk->field_24 = 0x3d482e;
|
||
pElem->field_4 = divisor;
|
||
}
|
||
|
||
STATIC int *menu_radio_do_file_mode_helper5_8004ABDC(int idx)
|
||
{
|
||
int *result;
|
||
|
||
result = &stru_800ABB7C->field_0_array[idx].field_0;
|
||
*result = 0;
|
||
return result;
|
||
}
|
||
|
||
STATIC void sub_8004ABF0(int param_1, int param_2, int param_3, int param_4, int divisor)
|
||
{
|
||
RadioFileModeStruElem *pElem = &stru_800ABB7C->field_0_array[11];
|
||
|
||
// TODO: WTF??? Why is it reinterpreting a middle of RadioFileModeUnk1 as another RadioFileModeUnk1,
|
||
// going past the memory of original RadioFileModeUnk1?
|
||
RadioFileModeUnk1 *pUnk = (RadioFileModeUnk1 *)&(stru_800ABB7C->field_220_unk1).field_18;
|
||
|
||
pElem->field_8_pFn = sub_8004A648;
|
||
pElem->field_C_unk1 = pUnk;
|
||
|
||
if (divisor <= 0)
|
||
{
|
||
pUnk->field_4 = param_1 * 65536;
|
||
pUnk->field_C = param_2 * 65536;
|
||
pUnk->field_14 = param_3 * 65536;
|
||
pUnk->field_1C = param_4 * 65536;
|
||
pElem->field_0 = 2;
|
||
}
|
||
else
|
||
{
|
||
pUnk->field_8 = (param_1 * 65536 - pUnk->field_4) / divisor;
|
||
pUnk->field_10 = (param_2 * 65536 - pUnk->field_C) / divisor;
|
||
pUnk->field_18 = (param_3 * 65536 - pUnk->field_14) / divisor;
|
||
pUnk->field_20 = (param_4 * 65536 - pUnk->field_1C) / divisor;
|
||
pElem->field_0 = 1;
|
||
}
|
||
|
||
pElem->field_4 = divisor;
|
||
}
|
||
|
||
STATIC void menu_radio_do_file_mode_helper6_8004AD40(MenuPrim *pGlue)
|
||
{
|
||
int i;
|
||
RadioFileModeStruElem *pElem;
|
||
|
||
pElem = stru_800ABB7C->field_0_array;
|
||
for (i = 0; i < 12; i++, pElem++)
|
||
{
|
||
if (pElem->field_0 != 0)
|
||
{
|
||
if (pElem->field_4 < 0)
|
||
{
|
||
pElem->field_4++;
|
||
}
|
||
else
|
||
{
|
||
pElem->field_8_pFn(pGlue, pElem);
|
||
if (pElem->field_0 == 1 && --pElem->field_4 == 0)
|
||
{
|
||
pElem->field_0 = 2;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#define setRGB0_Fast(prim, rgbExtra) *(unsigned int *)&prim->r0 = rgbExtra
|
||
|
||
static void set_sprt_default(SPRT *sprt)
|
||
{
|
||
setRGB0_Fast(sprt, 0x80808080);
|
||
setSprt(sprt);
|
||
sprt->clut = 32700;
|
||
}
|
||
|
||
// See also drawCaption_800C5EB4() in camera.c
|
||
STATIC void drawCaption_8004AE3C(MenuWork *menuWork, const char *caption)
|
||
{
|
||
int height;
|
||
KCB *kcb;
|
||
|
||
kcb = menuWork->field_214_font;
|
||
|
||
height = kcb->height_info;
|
||
kcb->height_info = 14;
|
||
font_clear(kcb);
|
||
kcb->height_info = height;
|
||
|
||
font_draw_string(kcb, 0, 0, caption, 0);
|
||
font_update(kcb);
|
||
}
|
||
|
||
#define FONT_SIZE 14
|
||
|
||
STATIC void sub_8004AEA8(SELECT_INFO *info)
|
||
{
|
||
int top;
|
||
int i, y;
|
||
int count;
|
||
int x, val2;
|
||
KCB *kcb;
|
||
char mes[32]; // Uses MGS custom encoding.
|
||
char *base;
|
||
|
||
kcb = info->field_1C_kcb;
|
||
x = 0;
|
||
font_clear(kcb);
|
||
|
||
val2 = 14;
|
||
y = val2;
|
||
count = info->max_num - info->top;
|
||
if (count > 6)
|
||
{
|
||
count = 6;
|
||
}
|
||
|
||
top = info->top;
|
||
|
||
for (i = 0; i < count; i++, y += FONT_SIZE)
|
||
{
|
||
if (i == 4)
|
||
{
|
||
x = 128;
|
||
y = val2;
|
||
}
|
||
|
||
// clang-format off
|
||
base = info->menu[ i + top ].mes;
|
||
if( base[ 0 ] != '\0' ){
|
||
//long c;
|
||
data_info->make_menu( mes, base );
|
||
font_draw_string( kcb, x, y, mes, 2 );
|
||
}
|
||
//y += FONT_SIZE;
|
||
}
|
||
|
||
font_draw_string( kcb, 0, 0, info->message, 0 );
|
||
|
||
font_update( kcb );
|
||
}
|
||
|
||
#define SAVE_MES_X 160
|
||
#define SAVE_MES_Y 200
|
||
|
||
static void show_message( MenuWork *work, unsigned long *ot, SELECT_INFO *info )
|
||
{
|
||
SPRT *sprt;
|
||
KCB *kcb;
|
||
|
||
kcb = GET_KCB( work );
|
||
|
||
/* メッセージ本体の描画 */
|
||
|
||
NEW_PRIM( sprt, work );
|
||
|
||
set_sprt_default( sprt );
|
||
setXY0( sprt, SAVE_MES_X - kcb->max_width / 2, SAVE_MES_Y );
|
||
setUV0( sprt, 0, 4 );
|
||
setWH( sprt, 252, 14 );
|
||
addPrim( ot, sprt );
|
||
}
|
||
// clang-format on
|
||
|
||
STATIC void menu_radio_do_file_mode_save_memcard_8004B0A0(MenuWork *work, char *pOt, SELECT_INFO *info)
|
||
{
|
||
TextConfig config;
|
||
|
||
char saveid[16];
|
||
char discnum[16];
|
||
char newfile[32];
|
||
char freeBlocksText[32];
|
||
|
||
LINE_F2 *pLine;
|
||
SPRT *pSprt;
|
||
TILE *pTile;
|
||
POLY_FT4 *pPoly;
|
||
DR_TPAGE *pTpage;
|
||
|
||
int sp88;
|
||
int freeBlocksCount;
|
||
int difficulty;
|
||
int sp8C;
|
||
int sp90;
|
||
int sp94;
|
||
int sp98;
|
||
int sp9C;
|
||
int spA0;
|
||
MENU_CURPOS *pos;
|
||
MenuPrim *prim;
|
||
|
||
int var_a2;
|
||
int var_s5;
|
||
int i;
|
||
int var_s0;
|
||
int var_t0;
|
||
|
||
int mult;
|
||
int mult2;
|
||
|
||
unsigned int s8;
|
||
unsigned int s6;
|
||
|
||
int new_var;
|
||
int new_var2, new_var3;
|
||
|
||
do
|
||
{
|
||
} while (0);
|
||
|
||
prim = work->field_20_otBuf;
|
||
s8 = 0;
|
||
|
||
if (info->max_num == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
sp90 = info->top;
|
||
sp8C = info->max_num - info->top;
|
||
|
||
s6 = 200;
|
||
if (sp8C > 6)
|
||
{
|
||
sp8C = 6;
|
||
}
|
||
sp94 = 0;
|
||
sp98 = 274;
|
||
|
||
var_s5 = 80;
|
||
|
||
mult = 52;
|
||
mult2 = 18;
|
||
|
||
new_var2 = 18;
|
||
if (info->open_count > 0)
|
||
{
|
||
if (--info->open_count >= 5)
|
||
{
|
||
return;
|
||
}
|
||
|
||
sp9C = (4 - info->open_count) * mult;
|
||
}
|
||
else
|
||
{
|
||
sp9C = s6 + 10;
|
||
}
|
||
|
||
if (info->field_18 > 0)
|
||
{
|
||
spA0 = --info->field_18 * (mult2 / 4);
|
||
}
|
||
else if (info->field_18 == 0)
|
||
{
|
||
spA0 = 0;
|
||
}
|
||
else
|
||
{
|
||
spA0 = 18;
|
||
}
|
||
|
||
new_var3 = 210;
|
||
for (sp88 = 0; sp88 < sp8C; sp88++)
|
||
{
|
||
new_var = 'A' - 1;
|
||
|
||
_NEW_PRIM(pTile, prim);
|
||
LSTORE(0, &pTile->r0);
|
||
|
||
setXY0(pTile, s8, s6);
|
||
setWH(pTile, new_var3, new_var2);
|
||
|
||
setTile(pTile);
|
||
addPrim(prim->mPrimBuf.mOt, pTile);
|
||
|
||
var_a2 = 293;
|
||
if (GV_Clock == 0)
|
||
{
|
||
var_a2 = 288;
|
||
}
|
||
|
||
_NEW_PRIM(pPoly, prim);
|
||
LSTORE(0x80808080, &pPoly->r0);
|
||
|
||
if ((sp90 + sp88) == info->current_index)
|
||
{
|
||
var_s0 = 18;
|
||
}
|
||
else
|
||
{
|
||
var_s0 = spA0;
|
||
}
|
||
|
||
pPoly->x0 = 160 - (sp9C / 2);
|
||
pPoly->y0 = var_s5;
|
||
|
||
pPoly->x1 = 160 - (sp9C / 2) + sp9C;
|
||
pPoly->y1 = var_s5;
|
||
|
||
pPoly->x2 = 160 - (sp9C / 2);
|
||
pPoly->y2 = var_s5 + var_s0;
|
||
|
||
pPoly->x3 = 160 - (sp9C / 2) + sp9C;
|
||
pPoly->y3 = var_s5 + var_s0;
|
||
|
||
setUVWH(pPoly, s8, s6, 210, 18);
|
||
|
||
pPoly->tpage = var_a2;
|
||
|
||
setPolyFT4(pPoly);
|
||
setSemiTrans(pPoly, 1);
|
||
|
||
addPrim(prim->mPrimBuf.mOt, pPoly);
|
||
|
||
if (((sp90 + sp88) == info->current_index) && (info->field_14 != 0))
|
||
{
|
||
do
|
||
{
|
||
sub_8004ABF0(160, var_s5 + 9, info->field_12, 16, 2);
|
||
} while (0);
|
||
}
|
||
|
||
config.colour = 0x66748956;
|
||
config.flags = 0;
|
||
var_s5 += var_s0;
|
||
|
||
if ((info->menu[sp90 + sp88].field_20 >= 0) && (info->menu[sp90 + sp88].field_20 < 16))
|
||
{
|
||
pos = &info->menu[sp90 + sp88];
|
||
|
||
if (pos->mes[0] == 'G')
|
||
{
|
||
config.xpos = s8 + 178;
|
||
config.ypos = s6 + 3;
|
||
sprintf(discnum, "DISC %d", ((pos->mes[5] - new_var) >> 3) + 1);
|
||
_menu_number_draw_string(prim, &config, discnum);
|
||
}
|
||
else
|
||
{
|
||
config.xpos = s8 + 178;
|
||
config.ypos = s6 + 3;
|
||
_menu_number_draw_string(prim, &config, "TIME");
|
||
}
|
||
|
||
if (pos->mes[0] == 'G')
|
||
{
|
||
static const char *difficulty_str_8009EBF0[] = {"EZ", "NM", "HD", "EX"};
|
||
difficulty = ((pos->mes[3] & 0x40) >> 5) | ((pos->mes[4] & 0x40) >> 6);
|
||
|
||
config.xpos = s8 + 164;
|
||
config.ypos = s6 + 10;
|
||
|
||
if (pos->mes[1] & 0x40)
|
||
{
|
||
_menu_number_draw_string(prim, &config, "VE");
|
||
}
|
||
else
|
||
{
|
||
_menu_number_draw_string(prim, &config, difficulty_str_8009EBF0[difficulty]);
|
||
}
|
||
}
|
||
|
||
config.xpos = s8 + 180;
|
||
config.ypos = s6 + 10;
|
||
|
||
saveid[0] = pos->mes[1];
|
||
saveid[1] = pos->mes[2];
|
||
saveid[2] = ':';
|
||
saveid[3] = pos->mes[3] & 0x3F;
|
||
saveid[4] = pos->mes[4] & 0x3F;
|
||
|
||
saveid[0] = saveid[0] & 0x3F;
|
||
|
||
if (saveid[0] == ':')
|
||
{
|
||
memcpy(saveid, "CLEAR", 6);
|
||
}
|
||
|
||
saveid[5] = 0;
|
||
_menu_number_draw_string(prim, &config, saveid);
|
||
}
|
||
else
|
||
{
|
||
char *msg;
|
||
char *dst = newfile;
|
||
char *plural;
|
||
unsigned char blocksCount;
|
||
long blocksCount_long; // Why?
|
||
config.ypos = s6 + 8;
|
||
config.flags = 0x2;
|
||
config.xpos = s8 + (sp9C / 2);
|
||
msg = "NEW FILE [ NEED %d BLOCK%s ]";
|
||
blocksCount = data_info->blocks_count;
|
||
blocksCount_long = blocksCount;
|
||
if (blocksCount_long >= 2)
|
||
plural = "S";
|
||
else
|
||
plural = "";
|
||
|
||
sprintf(dst, msg, blocksCount, plural);
|
||
|
||
_menu_number_draw_string2(prim, &config, newfile);
|
||
}
|
||
|
||
if (sp88 == 4)
|
||
{
|
||
sp94 = 128;
|
||
sp98 = 274;
|
||
}
|
||
|
||
_NEW_PRIM(pSprt, prim);
|
||
set_sprt_default(pSprt);
|
||
|
||
pSprt->u0 = sp94;
|
||
pSprt->v0 = sp98;
|
||
|
||
pSprt->w = 128;
|
||
pSprt->h = 14;
|
||
pSprt->x0 = s8;
|
||
pSprt->y0 = s6 + 2;
|
||
|
||
addPrim(pOt, pSprt);
|
||
|
||
_NEW_PRIM(pTpage, prim);
|
||
setDrawTPage(pTpage, 0, 1, getTPage(0, 1, 960, 256));
|
||
addPrim(prim->mPrimBuf.mOt, pTpage);
|
||
|
||
sp98 += 14;
|
||
}
|
||
|
||
var_t0 = -(sp9C + 10) / 2;
|
||
|
||
for (i = 0; i < 2; i++)
|
||
{
|
||
_NEW_PRIM(pLine, prim);
|
||
|
||
pLine->x0 = pLine->x1 = var_t0 + 160;
|
||
pLine->y0 = 78;
|
||
pLine->y1 = var_s5 + 4;
|
||
|
||
LSTORE(0x748956, &pLine->r0);
|
||
|
||
setLineF2(pLine);
|
||
setSemiTrans(pLine, 1);
|
||
addPrim(prim->mPrimBuf.mOt, pLine);
|
||
|
||
var_t0 += 10 + sp9C;
|
||
}
|
||
|
||
if (info->field_18 >= 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
freeBlocksCount = mcd_last_file_800ABB68[dword_800AB6FC]->free_blocks;
|
||
|
||
if (dword_800ABB74->max_num == 1)
|
||
{
|
||
config.xpos = 160;
|
||
}
|
||
else if (dword_800AB6FC == 0)
|
||
{
|
||
config.xpos = 96;
|
||
}
|
||
else
|
||
{
|
||
config.xpos = 224;
|
||
}
|
||
|
||
config.ypos = 68;
|
||
config.flags = 0x2;
|
||
config.colour = 0x66748956;
|
||
|
||
sprintf(freeBlocksText, "FREE: %d BLOCK%s", freeBlocksCount, (freeBlocksCount > 1) ? "S" : "");
|
||
_menu_number_draw_string2(prim, &config, freeBlocksText);
|
||
|
||
// Blinking effect.
|
||
if ((GV_Time % 32) > 10)
|
||
{
|
||
// If the list scrolled up at least once, it means there are more
|
||
// entries above the visible ones, so show the upper triangle.
|
||
if (sp90 > 0)
|
||
{
|
||
menu_draw_triangle(work->field_20_otBuf, &upperTriangle_8009EBD0);
|
||
}
|
||
|
||
// If there are more entries below the visible ones
|
||
// (which are always six), show the lower triangle.
|
||
if ((sp90 + 6) < info->max_num)
|
||
{
|
||
menu_draw_triangle(work->field_20_otBuf, &lowerTriangle_8009EBE0);
|
||
}
|
||
}
|
||
}
|
||
|
||
STATIC void menu_radio_do_file_mode_helper12_helper_8004B8FC(char *param_1, char *param_2)
|
||
{
|
||
strcpy(param_1, param_2 + 0xc);
|
||
}
|
||
|
||
STATIC void freeMemoryForSelectInfo(SELECT_INFO *selectInfo)
|
||
{
|
||
printf("close info\n");
|
||
if (selectInfo)
|
||
{
|
||
GV_FreeMemory(GV_PACKET_MEMORY0, selectInfo);
|
||
}
|
||
}
|
||
|
||
STATIC void allocMemoryForSelectInfo(SELECT_INFO **selectInfo, int num)
|
||
{
|
||
if (!*selectInfo)
|
||
{
|
||
*selectInfo = GV_AllocMemory(GV_PACKET_MEMORY0, (sizeof(MENU_CURPOS) * num) + sizeof(SELECT_INFO));
|
||
|
||
if (!*selectInfo)
|
||
{
|
||
printf("NO MEMORY FOR INFO\n");
|
||
}
|
||
|
||
printf("alloc info %X\n", (unsigned int)*selectInfo);
|
||
}
|
||
}
|
||
|
||
// See also updateCurrentEntry_800C6984() in camera.c
|
||
STATIC void updateCurrentEntry_8004B9C4(SELECT_INFO *info, int dir)
|
||
{
|
||
short top;
|
||
short newIndex;
|
||
int previousIndex;
|
||
|
||
previousIndex = info->current_index;
|
||
newIndex = info->current_index + dir;
|
||
info->current_index = newIndex;
|
||
if (newIndex < 0)
|
||
{
|
||
info->current_index = 0;
|
||
}
|
||
else if (newIndex >= info->max_num)
|
||
{
|
||
info->current_index = info->max_num - 1;
|
||
}
|
||
else
|
||
{
|
||
top = info->top;
|
||
if (newIndex < top)
|
||
{
|
||
info->top = newIndex;
|
||
}
|
||
else if (newIndex >= (top + 6))
|
||
{
|
||
info->top = newIndex - 5;
|
||
}
|
||
}
|
||
if (info->current_index != previousIndex)
|
||
{
|
||
GM_SeSet2(0, 0x3F, SE_MENU_CURSOR);
|
||
}
|
||
sub_8004AEA8(info);
|
||
}
|
||
|
||
|
||
STATIC int menu_radio_do_file_mode_helper12_8004BA80(MenuWork *work, MEM_CARD *pMemcard, const char *param_3,
|
||
SELECT_INFO *info)
|
||
{
|
||
MENU_CURPOS *pIter;
|
||
MEM_CARD_FILE *pMcFile;
|
||
int i;
|
||
|
||
pIter = info->menu;
|
||
|
||
strcpy(memoryCardFileName, MGS_MemoryCardName);
|
||
memoryCardFileName[12] = data_info->field_0[0];
|
||
|
||
for (i = 0; i < pMemcard->file_count; i++)
|
||
{
|
||
pMcFile = &pMemcard->files[i];
|
||
printf("FILE %s\n", pMcFile->name);
|
||
|
||
if (strncmp(pMcFile->name, memoryCardFileName, 13) == 0)
|
||
{
|
||
menu_radio_do_file_mode_helper12_helper_8004B8FC(pIter->mes, pMcFile->name);
|
||
pIter->field_20 = i;
|
||
pIter++;
|
||
}
|
||
}
|
||
|
||
if (dword_800ABB48 == 0 && pMemcard->free_blocks >= data_info->blocks_count)
|
||
{
|
||
memcpy(pIter->mes, "", 1);
|
||
pIter->field_20 = 16;
|
||
pIter++;
|
||
}
|
||
|
||
info->field_1C_kcb = work->field_214_font;
|
||
info->max_num = pIter - info->menu;
|
||
|
||
if (data_info->field_0[0] != 71)
|
||
{
|
||
if (info->max_num && pIter[-1].field_20 == 16)
|
||
{
|
||
info->current_index = info->max_num - 1;
|
||
}
|
||
else
|
||
{
|
||
info->current_index = 0;
|
||
}
|
||
}
|
||
else if (dword_800AB6EC == -1 || dword_800AB6EC >= info->max_num)
|
||
{
|
||
if (dword_800ABB48 == 0 && info->max_num && pIter[-1].field_20 == 16)
|
||
{
|
||
info->current_index = info->max_num - 1;
|
||
}
|
||
else
|
||
{
|
||
info->current_index = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
info->current_index = dword_800AB6EC;
|
||
}
|
||
|
||
info->top = 0;
|
||
info->message = param_3;
|
||
info->field_E = -1;
|
||
info->field_0_xpos = 40;
|
||
info->field_2_ypos = 40;
|
||
info->open_count = 8;
|
||
info->current_dir = 0;
|
||
info->field_18 = -1;
|
||
info->field_12 = 240;
|
||
info->field_14 = 1;
|
||
updateCurrentEntry_8004B9C4(info, 0);
|
||
return info->max_num != 0;
|
||
}
|
||
|
||
// See also SelectAct_800C32D8() in select.c
|
||
STATIC int menu_radio_do_file_mode_helper13_8004BCF8(GV_PAD *pPad, int *pOut, SELECT_INFO *info)
|
||
{
|
||
int newDir;
|
||
int field_20;
|
||
int press;
|
||
int status;
|
||
|
||
if (dword_800AB6F4 != 0)
|
||
{
|
||
dword_800AB6F4 = 0;
|
||
pPad->press |= PAD_CIRCLE;
|
||
}
|
||
else
|
||
{
|
||
status = pPad->status;
|
||
if (info->max_num != 0)
|
||
{
|
||
if (status & (PAD_DOWN | PAD_UP))
|
||
{
|
||
newDir = 1;
|
||
if (status & PAD_UP)
|
||
{
|
||
newDir = -1;
|
||
}
|
||
if (info->current_dir == newDir)
|
||
{
|
||
if (--info->scroll_delay < 0)
|
||
{
|
||
updateCurrentEntry_8004B9C4(info, newDir);
|
||
info->scroll_delay = 2;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
updateCurrentEntry_8004B9C4(info, newDir);
|
||
info->scroll_delay = 10;
|
||
info->current_dir = newDir;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
info->current_dir = 0;
|
||
}
|
||
}
|
||
}
|
||
press = pPad->press;
|
||
if (press & PAD_CIRCLE)
|
||
{
|
||
GM_SeSet2(0, 0x3F, SE_MENU_SELECT);
|
||
if (info->max_num == 0)
|
||
{
|
||
*pOut = -1;
|
||
return 1;
|
||
}
|
||
field_20 = info->menu[info->current_index].field_20;
|
||
*pOut = field_20;
|
||
if (data_info->field_0[0] == 71)
|
||
{
|
||
if (field_20 < 16)
|
||
{
|
||
dword_800AB6EC = info->current_index;
|
||
}
|
||
else
|
||
{
|
||
dword_800AB6EC = -1;
|
||
}
|
||
}
|
||
return 1;
|
||
}
|
||
if (press & PAD_CROSS)
|
||
{
|
||
GM_SeSet2(0, 0x3F, SE_MENU_EXIT);
|
||
*pOut = info->field_E;
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
STATIC const char *gMemoryCardNames_8009EC00[] = {
|
||
"MEMORY CARD 1", // 0
|
||
"MEMORY CARD 2" // 1
|
||
};
|
||
|
||
STATIC void menu_radio_do_file_mode_helper14_8004BE98(MenuWork *work, char *param_2, SELECT_INFO *info)
|
||
{
|
||
MENU_CURPOS *infoChild;
|
||
int idx, idx_copy;
|
||
int memoryCardNo;
|
||
int bit;
|
||
int minusOne;
|
||
|
||
infoChild = info->menu;
|
||
idx = -1;
|
||
for (memoryCardNo = 0; memoryCardNo < 2; memoryCardNo++)
|
||
{
|
||
bit = 1;
|
||
bit <<= memoryCardNo;
|
||
|
||
if (dword_800AB700 & bit)
|
||
{
|
||
strcpy(infoChild->mes, gMemoryCardNames_8009EC00[memoryCardNo]);
|
||
infoChild->field_20 = memoryCardNo;
|
||
if (memoryCardNo == dword_800AB6F0)
|
||
{
|
||
idx = infoChild - info->menu;
|
||
}
|
||
infoChild++;
|
||
}
|
||
}
|
||
|
||
idx_copy = idx;
|
||
if (infoChild == info->menu)
|
||
{
|
||
memcpy(&info->menu[0].mes, "NO CARD", 8);
|
||
infoChild->field_20 = 2;
|
||
infoChild = &info->menu[1];
|
||
}
|
||
|
||
info->field_1C_kcb = work->field_214_font;
|
||
info->max_num = infoChild - info->menu;
|
||
|
||
if (idx_copy < 0)
|
||
{
|
||
idx_copy = 0;
|
||
}
|
||
|
||
minusOne = -1;
|
||
do {} while (0);
|
||
|
||
info->field_0_xpos = 160;
|
||
info->field_2_ypos = 100;
|
||
info->current_index = idx_copy;
|
||
info->top = 0;
|
||
info->message = param_2;
|
||
info->field_E = minusOne;
|
||
info->field_10 = 128;
|
||
info->field_18 = minusOne;
|
||
info->open_count = 4;
|
||
info->field_12 = 128;
|
||
info->field_14 = 1;
|
||
info->current_dir = 0;
|
||
}
|
||
|
||
STATIC void menu_radio_do_file_mode_helper15_8004C04C(MenuWork *work, const char **srcs, int cnt, int index, const char *field_20,
|
||
SELECT_INFO *info)
|
||
{
|
||
KCB *kcb;
|
||
const char *src;
|
||
int i;
|
||
MENU_CURPOS *dest;
|
||
|
||
dest = info->menu;
|
||
for (i = 0; i < cnt; i++, dest++)
|
||
{
|
||
src = srcs[i];
|
||
strcpy(dest->mes, src);
|
||
dest->field_20 = i;
|
||
}
|
||
|
||
kcb = work->field_214_font;
|
||
|
||
info->max_num = dest - info->menu;
|
||
info->current_index = index;
|
||
info->top = 0;
|
||
info->message = field_20;
|
||
info->field_E = 1;
|
||
info->field_0_xpos = 160;
|
||
info->current_dir = 0;
|
||
info->field_14 = 1;
|
||
info->field_2_ypos = 128;
|
||
info->field_10 = 64;
|
||
info->field_12 = 32;
|
||
info->open_count = 4;
|
||
info->field_1C_kcb = kcb;
|
||
}
|
||
|
||
STATIC void menu_radio_do_file_mode_helper16_8004C164(MenuPrim *pGlue, SELECT_INFO *info)
|
||
{
|
||
int i;
|
||
int xpos, ypos;
|
||
TextConfig textConfig;
|
||
|
||
textConfig.flags = 0x12;
|
||
if (info->field_14 != 0)
|
||
{
|
||
textConfig.colour = 0x66748956;
|
||
}
|
||
else
|
||
{
|
||
textConfig.colour = 0x663d482e;
|
||
}
|
||
textConfig.xpos = info->field_0_xpos;
|
||
textConfig.ypos = info->field_2_ypos;
|
||
_menu_number_draw_string2(pGlue, &textConfig, info->message);
|
||
if (info->max_num == 1)
|
||
{
|
||
xpos = info->field_0_xpos;
|
||
}
|
||
else
|
||
{
|
||
xpos = info->field_0_xpos - info->field_10 / 2;
|
||
}
|
||
for (i = 0; i < info->max_num; i++, xpos += info->field_10)
|
||
{
|
||
textConfig.xpos = xpos;
|
||
ypos = info->field_2_ypos;
|
||
textConfig.ypos = ypos + 12;
|
||
|
||
if (i == info->current_index)
|
||
{
|
||
textConfig.colour = 0x66748956;
|
||
if (info->field_14 != 0)
|
||
{
|
||
ypos += 16;
|
||
sub_8004ABF0(textConfig.xpos, ypos, info->field_12, 12, 2);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
textConfig.colour = 0x663d482e;
|
||
}
|
||
_menu_number_draw_string2(pGlue, &textConfig, info->menu[i].mes);
|
||
}
|
||
}
|
||
|
||
STATIC int menu_radio_do_file_mode_helper17_8004C2E4(GV_PAD *pPad, int *outParam, SELECT_INFO *info)
|
||
{
|
||
short status;
|
||
|
||
if (info->open_count > 0)
|
||
{
|
||
info->open_count--;
|
||
return 0;
|
||
}
|
||
|
||
status = pPad->status;
|
||
if (info->max_num >= 2)
|
||
{
|
||
if (status & PAD_LEFT)
|
||
{
|
||
if (info->current_index != 0)
|
||
{
|
||
GM_SeSet2(0, 0x3F, SE_MENU_CURSOR);
|
||
info->current_index = 0;
|
||
}
|
||
}
|
||
else if ((status & PAD_RIGHT) && info->current_index == 0)
|
||
{
|
||
GM_SeSet2(0, 0x3F, SE_MENU_CURSOR);
|
||
info->current_index = 1;
|
||
}
|
||
}
|
||
if (pPad->press & PAD_CIRCLE)
|
||
{
|
||
*outParam = info->menu[info->current_index].field_20;
|
||
GM_SeSet2(0, 0x3F, SE_MENU_SELECT);
|
||
return 1;
|
||
}
|
||
if (pPad->press & PAD_CROSS)
|
||
{
|
||
GM_SeSet2(0, 0x3F, SE_MENU_EXIT);
|
||
*outParam = info->field_E;
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int menu_radio_do_file_mode(MenuWork *work, GV_PAD *pPad)
|
||
{
|
||
TextConfig textConfig1, textConfig2;
|
||
int res1, res2, res3;
|
||
char **captions;
|
||
SELECT_INFO *info;
|
||
int xpos;
|
||
int divisor;
|
||
int var_v0_2; // ypos?
|
||
unsigned int flags;
|
||
DR_TPAGE *tpage;
|
||
unsigned char *mOt;
|
||
int flagsExtracted;
|
||
|
||
mOt = work->field_20_otBuf->mPrimBuf.mOt;
|
||
if (dword_800ABB48 == 0)
|
||
{
|
||
captions = (char **)saveCaptions_8009EB4C;
|
||
dword_8009EBBC[0] = data_info->field_4_name;
|
||
dword_8009EBBC[1] = "SAVING...";
|
||
dword_8009EBBC[3] = "NO SPACE";
|
||
}
|
||
else
|
||
{
|
||
captions = (char **)loadCaptions_8009EB7C;
|
||
dword_8009EBBC[0] = "LOAD DATA";
|
||
dword_8009EBBC[1] = "LOADING...";
|
||
dword_8009EBBC[3] = "NO FILE";
|
||
}
|
||
switch (dword_800ABB80)
|
||
{
|
||
case 0:
|
||
sub_80048124();
|
||
dword_800ABB84 = 0;
|
||
font_set_color(work->field_214_font, 1, 0x19F2, 0);
|
||
font_clut_update(work->field_214_font);
|
||
dword_800ABB80 = 1;
|
||
dword_800ABB88 = NULL;
|
||
dword_800ABB78 = NULL;
|
||
dword_800ABB74 = NULL;
|
||
dword_800ABB70 = NULL;
|
||
menu_radio_do_file_mode_helper2_8004A87C(0, 160, 100, 0, 0);
|
||
sub_8004ABF0(160, 0x67, 0x60, 0xC, 0);
|
||
GM_SeSet2(0, 0x3F, SE_MENU_SELECT);
|
||
dword_800AB6F4 = 0;
|
||
dword_800AB6FC = -1;
|
||
break;
|
||
case 1:
|
||
menu_radio_do_file_mode_helper2_8004A87C(3, 160, 0x80, 0, -1);
|
||
flags = dword_800ABB58;
|
||
if (flags == 0)
|
||
{
|
||
break;
|
||
}
|
||
if (flags == 0xC1000001)
|
||
{
|
||
if (dword_800ABB48 == 0)
|
||
{
|
||
strcpy(dword_800ABB70->menu[dword_800ABB70->current_index].mes, memoryCardFileName + 0xc);
|
||
dword_800ABB70->menu[dword_800ABB70->current_index].field_20 = 0;
|
||
sub_8004AEA8(dword_800ABB70);
|
||
}
|
||
menu_radio_do_file_mode_helper2_8004A87C(2, 160, 0x80, 0, 2);
|
||
}
|
||
if (flags == 0x1000009)
|
||
{
|
||
menu_radio_do_file_mode_helper2_8004A87C(2, 160, 0x80, 0, 1);
|
||
menu_radio_do_file_mode_helper4_8004AA68(8, 160, 0x6E, 160, 0x7A, 0);
|
||
sub_8004ABF0(160, 0x83, 0x60, 0xC, 4);
|
||
}
|
||
if (flags & 0x04000000)
|
||
{
|
||
menu_radio_do_file_mode_helper2_8004A87C(2, 160, 0x80, 0, 4);
|
||
sub_8004ABF0(160, 0x83, 0x60, 0xC, 4);
|
||
}
|
||
if (flags & 0x01000000)
|
||
{
|
||
drawCaption_8004AE3C(work, captions[(unsigned char)dword_800ABB58]);
|
||
dword_800ABB84 = 0xF;
|
||
}
|
||
if (flags & 0x40000000)
|
||
{
|
||
dword_800ABB80 = 2;
|
||
dword_800ABB84 = 1;
|
||
}
|
||
else if (flags & 0x20000000)
|
||
{
|
||
dword_800ABB84 = 0;
|
||
switch ((unsigned char)dword_800ABB58)
|
||
{
|
||
case 0:
|
||
dword_800ABB80 = 4;
|
||
allocMemoryForSelectInfo(&dword_800ABB70, 0x11);
|
||
dword_800ABB88 = dword_800ABB70;
|
||
if (menu_radio_do_file_mode_helper12_8004BA80(work, mcd_last_file_800ABB68[dword_800AB6FC], "", dword_800ABB70) == 0)
|
||
{
|
||
drawCaption_8004AE3C(work, captions[4]);
|
||
dword_800ABB84 = 1;
|
||
menu_radio_do_file_mode_helper2_8004A87C(3, 160, 0x80, 0, 3);
|
||
sub_8004ABF0(160, 0x83, 0x60, 0xC, 4);
|
||
dword_800ABB54 = 3;
|
||
}
|
||
if (dword_800ABB74 == NULL)
|
||
{
|
||
allocMemoryForSelectInfo(&dword_800ABB74, 3);
|
||
menu_radio_do_file_mode_helper14_8004BE98(work, "SELECT MEMORY CARD", dword_800ABB74);
|
||
divisor = -4;
|
||
dword_800ABB74->field_14 = 0;
|
||
}
|
||
else
|
||
{
|
||
divisor = 4;
|
||
}
|
||
menu_radio_do_file_mode_helper2_8004A87C(0, 0x40, 0x18, 4, 0);
|
||
menu_radio_do_file_mode_helper3_8004A994(4, 160, 0x28, divisor, dword_800ABB74);
|
||
menu_radio_do_file_mode_helper4_8004AA68(5, 0x6C, 0x1A, 160, 0x1A, divisor);
|
||
menu_radio_do_file_mode_helper4_8004AA68(6, 160, 0x1A, 160, 0x24, divisor);
|
||
info = dword_800ABB74;
|
||
if (dword_800ABB74->max_num == 1)
|
||
{
|
||
xpos = info->field_0_xpos;
|
||
}
|
||
else
|
||
{
|
||
xpos = info->field_0_xpos - info->field_10 / 2;
|
||
if (info->current_index == 1)
|
||
{
|
||
xpos += info->field_10;
|
||
}
|
||
}
|
||
|
||
if (dword_800ABB88->max_num == 0)
|
||
{
|
||
xpos = info->field_0_xpos;
|
||
var_v0_2 = 0x7A;
|
||
}
|
||
else
|
||
{
|
||
var_v0_2 = 0x40;
|
||
}
|
||
menu_radio_do_file_mode_helper4_8004AA68(7, xpos, 0x3C, xpos, var_v0_2, -4);
|
||
menu_radio_do_file_mode_helper5_8004ABDC(8);
|
||
break;
|
||
case 1:
|
||
if (dword_800ABB74 != NULL)
|
||
{
|
||
divisor = 4;
|
||
}
|
||
else
|
||
{
|
||
divisor = -4;
|
||
}
|
||
if (dword_800ABB70 != NULL)
|
||
{
|
||
freeMemoryForSelectInfo(dword_800ABB70);
|
||
dword_800ABB70 = NULL;
|
||
}
|
||
allocMemoryForSelectInfo(&dword_800ABB74, 3);
|
||
dword_800ABB88 = dword_800ABB74;
|
||
menu_radio_do_file_mode_helper14_8004BE98(work, "SELECT MEMORY CARD", dword_800ABB74);
|
||
dword_800ABB80 = 3;
|
||
menu_radio_do_file_mode_helper2_8004A87C(0, 160, 0x18, 4, 0);
|
||
menu_radio_do_file_mode_helper3_8004A994(4, 160, 100, divisor, dword_800ABB74);
|
||
menu_radio_do_file_mode_helper4_8004AA68(5, 160, 0x1A, 160, 0x1A, divisor);
|
||
menu_radio_do_file_mode_helper4_8004AA68(6, 160, 0x20, 160, 0x60, divisor);
|
||
menu_radio_do_file_mode_helper5_8004ABDC(7);
|
||
menu_radio_do_file_mode_helper5_8004ABDC(8);
|
||
break;
|
||
}
|
||
}
|
||
else if (flags & 0x10000000)
|
||
{
|
||
static const char *off_8009EC08[] = {"YES", "NO"};
|
||
|
||
flagsExtracted = ((flags >> 20) ^ 1);
|
||
flagsExtracted &= 1;
|
||
dword_800ABB80 = 5;
|
||
allocMemoryForSelectInfo(&dword_800ABB78, 2);
|
||
dword_800ABB88 = dword_800ABB78;
|
||
menu_radio_do_file_mode_helper15_8004C04C(work, off_8009EC08, 2, flagsExtracted,
|
||
save_prompt_msg_en_8009EBB4[(unsigned char)dword_800ABB58], dword_800ABB78);
|
||
drawCaption_8004AE3C(work, save_prompt_msg_jp_8009EBAC[(unsigned char)dword_800ABB58]);
|
||
dword_800ABB84 = 1;
|
||
}
|
||
else if ((int)flags < 0)
|
||
{
|
||
dword_800ABB80 = 6;
|
||
dword_800ABB58 = 0;
|
||
mts_wup_tsk(MTSID_MEMORY_CARD);
|
||
}
|
||
else
|
||
{
|
||
dword_800ABB80 = 1;
|
||
dword_800ABB58 = 0;
|
||
mts_wup_tsk(MTSID_MEMORY_CARD);
|
||
}
|
||
break;
|
||
case 2:
|
||
if (pPad->press & (PAD_TRIANGLE | PAD_CROSS | PAD_SQUARE | PAD_CIRCLE))
|
||
{
|
||
dword_800ABB84 = 0;
|
||
if (dword_800ABB58 < 0)
|
||
{
|
||
dword_800ABB80 = 6;
|
||
dword_800ABB58 = 0;
|
||
}
|
||
else
|
||
{
|
||
dword_800ABB80 = 1;
|
||
dword_800ABB58 = 0;
|
||
}
|
||
mts_wup_tsk(MTSID_MEMORY_CARD);
|
||
menu_radio_do_file_mode_helper2_8004A87C(3, 160, 0x80, 0, -1);
|
||
menu_radio_do_file_mode_helper2_8004A87C(2, 160, 0x80, 0, -1);
|
||
}
|
||
else
|
||
{
|
||
draw_radio_wait_mark(work, mOt);
|
||
}
|
||
break;
|
||
case 3:
|
||
if (dword_800AB700 & 0x80)
|
||
{
|
||
menu_radio_do_file_mode_helper14_8004BE98(work, "SELECT MEMORY CARD", dword_800ABB74);
|
||
dword_800AB700 &= ~0x80;
|
||
}
|
||
textConfig1.xpos = 160;
|
||
textConfig1.ypos = 0xC8;
|
||
textConfig1.flags = 0x12;
|
||
textConfig1.colour = 0x66748956;
|
||
_menu_number_draw_string2(work->field_20_otBuf, &textConfig1, "PRESS * TO EXIT");
|
||
if (menu_radio_do_file_mode_helper17_8004C2E4(pPad, &res1, dword_800ABB74) != 0)
|
||
{
|
||
printf("Res %d\n", res1);
|
||
dword_800ABB58 = 0;
|
||
dword_800ABB80 = 1;
|
||
dword_800ABB84 = 0;
|
||
dword_800ABB74->field_14 = 0;
|
||
dword_800ABB5C = res1;
|
||
}
|
||
break;
|
||
case 5:
|
||
if (menu_radio_do_file_mode_helper17_8004C2E4(pPad, &res2, dword_800ABB78) != 0)
|
||
{
|
||
printf("Res %d\n", res2);
|
||
dword_800ABB78->field_14 = 0;
|
||
if (res2 == -1)
|
||
{
|
||
menu_radio_do_file_mode_helper5_8004ABDC(8);
|
||
}
|
||
dword_800ABB58 = 0;
|
||
dword_800ABB5C = res2;
|
||
mts_wup_tsk(MTSID_MEMORY_CARD);
|
||
dword_800ABB80 = 1;
|
||
dword_800ABB84 = 0;
|
||
}
|
||
else
|
||
{
|
||
menu_radio_do_file_mode_helper16_8004C164(work->field_20_otBuf, dword_800ABB88);
|
||
if (dword_800ABB70 != NULL)
|
||
{
|
||
menu_radio_do_file_mode_helper4_8004AA68(8, 160, 0x6E, 160, 0x7A, 0);
|
||
}
|
||
}
|
||
break;
|
||
case 4:
|
||
if (dword_800ABB70->max_num != 0)
|
||
{
|
||
textConfig2.xpos = 160;
|
||
textConfig2.ypos = 0xC8;
|
||
textConfig2.flags = 0x12;
|
||
textConfig2.colour = 0x66748956;
|
||
_menu_number_draw_string2(work->field_20_otBuf, &textConfig2, "PRESS * TO SELECT MEMORY CARD");
|
||
}
|
||
if (menu_radio_do_file_mode_helper13_8004BCF8(pPad, &res3, dword_800ABB70) != 0)
|
||
{
|
||
printf("Res %d\n", res3);
|
||
dword_800ABB70->field_14 = 0;
|
||
if (res3 == -1)
|
||
{
|
||
freeMemoryForSelectInfo(dword_800ABB70);
|
||
dword_800ABB70 = NULL;
|
||
}
|
||
else
|
||
{
|
||
dword_800ABB70->field_18 = 4;
|
||
}
|
||
dword_800ABB5C = res3;
|
||
if (dword_800ABB80 == 4)
|
||
{
|
||
dword_800ABB58 = 0;
|
||
mts_wup_tsk(MTSID_MEMORY_CARD);
|
||
}
|
||
dword_800ABB80 = 1;
|
||
dword_800ABB84 = 0;
|
||
}
|
||
break;
|
||
case 6:
|
||
if (mts_get_task_status(MTSID_MEMORY_CARD) == 0)
|
||
{
|
||
printf("END SAVE MODE\n");
|
||
freeMemoryForSelectInfo(dword_800ABB70);
|
||
freeMemoryForSelectInfo(dword_800ABB74);
|
||
freeMemoryForSelectInfo(dword_800ABB78);
|
||
menu_radio_do_file_mode_helper_8004A858();
|
||
GV_FreeMemory(GV_PACKET_MEMORY0, stack_800ABB50);
|
||
GM_LastResultFlag = dword_800ABB54;
|
||
printf("END STATE %d\n", GM_LastResultFlag);
|
||
if (dword_800ABB48 != 2)
|
||
{
|
||
font_set_color(work->field_214_font, 1, 0x3BEF, 0);
|
||
return 1;
|
||
}
|
||
return 2;
|
||
}
|
||
break;
|
||
}
|
||
if (dword_800ABB84 >= 2)
|
||
{
|
||
dword_800ABB84--;
|
||
}
|
||
else if (dword_800ABB84 > 0)
|
||
{
|
||
show_message(work, (u_long *)mOt, dword_800ABB88);
|
||
}
|
||
NEW_PRIM(tpage, work);
|
||
setDrawTPage(tpage, 0, 1, getTPage(0, 1, 960, 256));
|
||
addPrim(mOt, tpage);
|
||
if (dword_800ABB70 != NULL)
|
||
{
|
||
menu_radio_do_file_mode_save_memcard_8004B0A0(work, mOt, dword_800ABB70);
|
||
}
|
||
menu_radio_do_file_mode_helper6_8004AD40(work->field_20_otBuf);
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
pAreaNameForMenu uses MGS custom encoding.
|
||
pAreaNameForSaveData uses Shift-JIS encoding.
|
||
|
||
Example for "Heliport":
|
||
MGS : 80 48 80 65 80 6C 80 69 80 70 80 6F 80 72 80 74
|
||
Shift-JIS: 82 67 82 85 82 8C 82 89 82 90 82 8F 82 92 82 94
|
||
H e l i p o r t
|
||
*/
|
||
STATIC void getAreaName_8004CF20(int code, char **pAreaNameForMenu, char **pAreaNameForSaveData)
|
||
{
|
||
int i;
|
||
|
||
if (code == 0)
|
||
{
|
||
*pAreaNameForMenu = "NO PLACE";
|
||
*pAreaNameForSaveData = "\x81\x40";
|
||
}
|
||
GCL_SetArgTop((char *)dword_800ABB8C);
|
||
printf("code %d\n", code);
|
||
for (i = 0; i < code; i++) {
|
||
if (GCL_GetParamResult() == 0)
|
||
{
|
||
return;
|
||
}
|
||
*pAreaNameForMenu = GCL_ReadString(GCL_GetParamResult());
|
||
if (dword_800ABB90 > 0 && dword_800ABB48 == 0)
|
||
{
|
||
*pAreaNameForSaveData = GCL_ReadString(GCL_GetParamResult());
|
||
}
|
||
}
|
||
}
|
||
|
||
extern char dword_800122F4[];
|
||
|
||
char dockAreaName_8009EC10[] = { "\x82\x63\x82\x8F\x82\x83\x82\x8B" }; // Dock
|
||
|
||
const char *diff_names_8009EC1C[] = {
|
||
"\x81\x6D\x82\x75\x82\x64\x81\x6E", /* [VE] */
|
||
"\x81\x6D\x82\x64\x82\x79\x81\x6E", /* [EZ] */
|
||
"\x81\x6D\x82\x6D\x82\x6C\x81\x6E", /* [NM] */
|
||
"\x81\x6D\x82\x67\x82\x63\x81\x6E", /* [HD] */
|
||
"\x81\x6D\x82\x64\x82\x77\x81\x6E" /* [EX] */
|
||
};
|
||
|
||
// Called by data_info->make_title
|
||
STATIC void makeTitle_8004D008(char *title, MEM_CARD *pUnused, int hours, int minutes)
|
||
{
|
||
char playTime[11];
|
||
char *discard;
|
||
char *areaName;
|
||
|
||
// 0x824F is the '0' Shift-JIS character.
|
||
playTime[0] = 0x82;
|
||
playTime[1] = (hours / 10) + 0x4f;
|
||
playTime[2] = 0x82;
|
||
playTime[3] = (hours % 10) + 0x4f;
|
||
playTime[4] = 0x81;
|
||
playTime[5] = 0x46;
|
||
playTime[6] = 0x82;
|
||
playTime[7] = (minutes / 10) + 0x4f;
|
||
playTime[8] = 0x82;
|
||
playTime[9] = (minutes % 10) + 0x4f;
|
||
playTime[10] = '\0';
|
||
if (dword_800ABB90 == 0)
|
||
{
|
||
getAreaName_8004CF20(1, &discard, &areaName);
|
||
areaName = dockAreaName_8009EC10;
|
||
}
|
||
else
|
||
{
|
||
getAreaName_8004CF20(dword_800ABB90, &discard, &areaName);
|
||
}
|
||
|
||
/* MGS∫ */
|
||
sprintf(title, "%s%s%s%s%s%s", "\x82\x6C\x82\x66\x82\x72\x81\xE7", diff_names_8009EC1C[GM_DifficultyFlag + 1], "\x81\x40", playTime, "\x81\x40", areaName);
|
||
}
|
||
|
||
// Called by data_info->make_menu
|
||
STATIC void getAreaNameForMenu_8004D14C(char *areaNameForMenu, char *param_2)
|
||
{
|
||
char *areaName;
|
||
char *discard;
|
||
int val;
|
||
|
||
getAreaName_8004CF20(param_2[6] - 0x40, &areaName, &discard);
|
||
|
||
val = (param_2[5] - 0x40) & 7;
|
||
if (val == 0)
|
||
{
|
||
val = 2;
|
||
}
|
||
else if (val < 3)
|
||
{
|
||
val = 1;
|
||
}
|
||
else
|
||
{
|
||
val = 3;
|
||
}
|
||
sprintf(areaNameForMenu, "\f%c%s", val | 0x30, areaName);
|
||
}
|
||
|
||
// Called by data_info->make_game_data
|
||
STATIC void writeGameData(char *saveBuf)
|
||
{
|
||
int currentOffset;
|
||
int size;
|
||
char *saveBufIter;
|
||
|
||
currentOffset = 0x100;
|
||
saveBufIter = saveBuf;
|
||
// Note: the counter is incremented here, but the memory card
|
||
// has not been written yet. If a write error occurs and
|
||
// then you save again (this time successfully), the
|
||
// counter is wrong because it is never decremented.
|
||
GM_TotalSaves++;
|
||
for (;;)
|
||
{
|
||
size = GCL_MakeSaveFile(saveBufIter);
|
||
currentOffset += size;
|
||
|
||
if (currentOffset + size > MC_BLOCK_SIZE)
|
||
{
|
||
break;
|
||
}
|
||
|
||
saveBufIter += size;
|
||
printf("*");
|
||
}
|
||
}
|
||
|
||
void init_file_mode(DATA_INFO *pSaveMode, int param_2)
|
||
{
|
||
dword_800ABB80 = 0;
|
||
data_info = pSaveMode;
|
||
init_file_mode_helper2_8004A800();
|
||
init_file_mode_helper_8004A424(param_2);
|
||
}
|
||
|
||
DATA_INFO dataInfo_8009EC30 = {
|
||
{0x47, 0}, // field_0
|
||
0, // field_2
|
||
1, // blocks_count
|
||
"SAVE DATA", // field_4_name
|
||
(void *)makeTitle_8004D008, // make_title
|
||
(void *)getAreaNameForMenu_8004D14C, // make_menu
|
||
(void *)writeGameData // make_game_data
|
||
};
|
||
|
||
void menu_radio_init_save_mode(int param_1, int param_2)
|
||
{
|
||
dataInfo_8009EC30.field_0[1] = 0;
|
||
if (param_2 == 0)
|
||
{
|
||
dataInfo_8009EC30.field_2 = 1;
|
||
}
|
||
else
|
||
{
|
||
dataInfo_8009EC30.field_2 = param_2;
|
||
}
|
||
dword_800ABB8C = param_1;
|
||
dword_800ABB90 = param_2;
|
||
init_file_mode(&dataInfo_8009EC30, 0);
|
||
}
|
||
|
||
void menu_radio_update_helper4_8004D2D0(int param_1)
|
||
{
|
||
dword_800ABB8C = param_1;
|
||
init_file_mode(&dataInfo_8009EC30, 1);
|
||
}
|
||
|
||
void menu_radio_8004D2FC(DATA_INFO *pSaveMode)
|
||
{
|
||
init_radio_message_board_80040F74(&gMenuWork_800BD360);
|
||
init_file_mode(pSaveMode, 0);
|
||
}
|
||
|
||
int menu_radio_8004D334(GV_PAD *pPad)
|
||
{
|
||
return menu_radio_do_file_mode(&gMenuWork_800BD360, pPad);
|
||
}
|
||
|
||
void menu_radio_8004D35C(void)
|
||
{
|
||
sub_8004124C(&gMenuWork_800BD360);
|
||
}
|