Refactor FEMAIN.C

- [PC] Fix flickering bugs

- [PC] Move button drawing logic to DrawScreen

- [PC] Better game names lookup system

- Fixed bugs in high score table

- Other misc changes/fixes
This commit is contained in:
Fireboyd78 2020-11-18 18:42:38 -08:00
parent 7d78fc45e6
commit f4e3e303c4

View File

@ -109,73 +109,161 @@ char* CutSceneNames[28] =
"Credits", "Credits",
}; };
#ifndef PSX
static char* gameNames[64] = { char *areaNames[4][8] = {
"Downtown", {
"Wrigleyville", "Downtown",
"Necropolis De Colon", "Wrigleyville",
"Capitolio", "Greektown",
"Downtown", "Grant Park",
"Upper Strip", "Meigs Field",
"Centro", "Ukrainian Village",
"Copacabana", "River North",
"Greektown", "Cabrini Green",
"Grant Park", },
"Necropolis de Colon", {
"Old Havana", "Necropolis de Colon",
"Lakeside", "Capitolio",
"Mid Strip", "Old Havana",
"Copacabana", "The Docks",
"Santa Tereza", "Vedado",
"Downtown", "Plaza",
"Meigs Field", "Plaza de la Revolucion",
"The Docks", NULL,
"Old Havana", },
"North Vegas", {
"Lakeside", "Downtown",
"Lagoa Rodrigo de Freitas", "Upper Strip",
"Praca da Bandeira", "Lakeside",
"Grant Park", "Mid Strip",
"Downtown", "North Vegas",
"Old Havana", "Lakes",
"Vedado", "Ghost Town",
"Downtown", NULL,
"Upper Strip", },
"Leblon", {
"Praca da Bandeira", "Centro",
"Ukrainian Village", "Copacabana",
"Downtown", "Santa Tereza",
"Vedado", "Lagoa Rodrigo de Freitas",
"Necropolis de Colon", "Praca da Bandeira",
"Mid Strip", "Leblon",
"Downtown", "Flamengo",
"Copacabana", NULL,
"Centro", },
"Cabrini Green",
"River North",
"Old Havana",
"Plaza",
"Lakes",
"Ghost Town",
"Flamengo",
"Centro",
"River North",
"Cabrini Green",
"Plaza",
"Old Havana",
"Downtown",
"Lakes",
"Centro",
"Flamengo",
"River North",
"Cabrini Green",
"Old Havana",
"Plaza de la Revolucion",
"Ghost Town",
"North Vegas",
"Centro",
}; };
static char gameAreas[64] = {
// Getaway (0-6)
0, 1, // Downtown, Wrigleyville
0, 1, // Necropolis De Colon, Capitolio
0, 1, // Downtown, Upper Strip
0, 1, // Centro, Copacabana
// Gate race (8-14)
2, 3, // Greektown, Grant Park
0, 2, // Necropolis de Colon, Old Havana
2, 3, // Lakeside, Mid Strip
1, 2, // Copacabana, Santa Tereza
// Checkpoint (16-22)
0, 4, // Downtown, Meigs Field
3, 2, // The Docks, Old Havana
4, 2, // North Vegas, Lakeside
3, 4, // Lagoa Rodrigo de Freitas, Praca da Bandeira
// Trailblazer (24-30)
3, 0, // Grant Park, Downtown
2, 4, // Old Havana, Vedado
0, 1, // Downtown, Upper Strip
5, 4, // Leblon, Praca da Bandeira
// [MP] Cops 'n Robbers (32-38)
5, 0, // Ukrainian Village, Downtown
4, 0, // Vedado, Necropolis de Colon
3, 0, // Mid Strip, Downtown
1, 0, // Copacabana, Centro
// [MP] Capture the Flag (40-46)
7, 6, // Cabrini Green, River North
2, 5, // Old Havana, Plaza
5, 6, // Lakes, Ghost Town
6, 0, // Flamengo, Centro
// [MP] Take a Ride (48-54)
6, 7, // River North, Cabrini Green
5, 2, // Plaza, Old Havana
0, 5, // Downtown, Lakes
0, 6, // Centro, Flamengo
// [MP] Checkpoint (56-62)
6, 7, // River North, Cabrini Green
2, 6, // Old Havana, Plaza de la Revolucion
6, 4, // Ghost Town, North Vegas
0, 6, // Centro, Flamengo
};
#define AREA_NAME(level, index) areaNames[level][index]
#define GAMEMODE_AREA(level, offset, index) gameAreas[offset + level * 2 + index]
#define GAMEMODE_AREA_NAME(level, offset, index) AREA_NAME(level, GAMEMODE_AREA(level, offset, index))
#else
static char* gameNames[64] = {
// Getaway (0-6)
"Downtown", "Wrigleyville",
"Necropolis De Colon", "Capitolio",
"Downtown", "Upper Strip",
"Centro", "Copacabana",
// Gate race (8-14)
"Greektown", "Grant Park",
"Necropolis de Colon", "Old Havana",
"Lakeside", "Mid Strip",
"Copacabana", "Santa Tereza",
// Checkpoint (16-22)
"Downtown", "Meigs Field",
"The Docks", "Old Havana",
"North Vegas", "Lakeside",
"Lagoa Rodrigo de Freitas", "Praca da Bandeira",
// Trailblazer (24-30)
"Grant Park", "Downtown",
"Old Havana", "Vedado",
"Downtown", "Upper Strip",
"Leblon", "Praca da Bandeira",
// [MP] Cops 'n Robbers (32-38)
"Ukrainian Village", "Downtown",
"Vedado", "Necropolis de Colon",
"Mid Strip", "Downtown",
"Copacabana", "Centro",
// [MP] Capture the Flag (40-46)
"Cabrini Green", "River North",
"Old Havana", "Plaza",
"Lakes", "Ghost Town",
"Flamengo", "Centro",
// [MP] Take a Ride (48-54)
"River North", "Cabrini Green",
"Plaza", "Old Havana",
"Downtown", "Lakes",
"Centro", "Flamengo",
// [MP] Checkpoint (56-62)
"River North", "Cabrini Green",
"Old Havana", "Plaza de la Revolucion",
"Ghost Town", "North Vegas",
"Centro", "Flamengo",
};
#define AREA_NAME(level, index) "???"
#define GAMEMODE_AREA(level, offset, index) (0)
#define GAMEMODE_AREA_NAME(level, offset, index) gameNames[offset + level * 2 + index]
#endif
int CarAvailability[4][10] = { int CarAvailability[4][10] = {
{1,1,1,1,0,0,0,0,0,0}, {1,1,1,1,0,0,0,0,0,0},
{1,1,1,1,0,0,0,0,0,0}, {1,1,1,1,0,0,0,0,0,0},
@ -520,7 +608,6 @@ void LoadFrontendScreens(void)
DrawSync(0); DrawSync(0);
Loadfile("DATA\\FEFONT.BNK", (char*)&feFont); Loadfile("DATA\\FEFONT.BNK", (char*)&feFont);
//PadChecks(); // [A] there is a bug too
} }
@ -797,7 +884,9 @@ void SetupScreenSprts(PSXSCREEN *pScr)
/* end block 3 */ /* end block 3 */
// End Line: 3526 // End Line: 3526
DR_MOVE In;
DR_MOVE Out;
RECT16 storeRect = { 768, 475, 255, 36 };
// [D] [T] // [D] [T]
void DrawScreen(PSXSCREEN *pScr) void DrawScreen(PSXSCREEN *pScr)
@ -805,7 +894,15 @@ void DrawScreen(PSXSCREEN *pScr)
char version_info[32]; char version_info[32];
int numBtnsToDraw; int numBtnsToDraw;
int i; int i;
#ifndef PSX
if (bRedrawFrontend)
{
// flush the old screen
//EndFrame();
bRedrawFrontend = 0;
}
#endif
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
addPrim(current->ot + 11, &BackgroundPolys[i]); addPrim(current->ot + 11, &BackgroundPolys[i]);
@ -822,12 +919,15 @@ void DrawScreen(PSXSCREEN *pScr)
{ {
numBtnsToDraw = pScr->numButtons; numBtnsToDraw = pScr->numButtons;
} }
#ifndef PSX
NewSelection(0);
#endif
for (i = 0; i < numBtnsToDraw; i++) for (i = 0; i < numBtnsToDraw; i++)
{ {
PSXBUTTON *button = &pScr->buttons[i]; PSXBUTTON *button = &pScr->buttons[i];
int status = button->action >> 8; int status = button->action >> 8;
#ifdef PSX
if (status != 5) if (status != 5)
{ {
if (button == pCurrButton) if (button == pCurrButton)
@ -871,6 +971,50 @@ void DrawScreen(PSXSCREEN *pScr)
} }
} }
} }
#else
int draw = (status != 5);
if (button == pCurrButton)
{
RECT16 rect;
rect.x = pCurrButton->s_x;
rect.y = pCurrButton->s_y;
rect.w = 255;
rect.h = 36;
SetDrawMove(&Out, &rect, storeRect.x, storeRect.y);
addPrim(current->ot + 8, &Out);
setXY0(&HighlightSprt, rect.x, rect.y);
addPrim(current->ot + 6, &HighlightSprt);
addPrim(current->ot + 7, &HighlightDummy);
draw = 1;
}
if (draw)
{
if (status == 3)
{
FEPrintString(button->Name, button->x * 2 + button->w, button->y, 4, 32, 32, 32);
}
else
{
if (bMissionSelect && (i == 0 || i == 5) ||
bDoingCarSelect && (i == 0 || i == 2) ||
bInCutSelect && (i == 0 || i == 2))
{
FEPrintString(button->Name, button->x * 2 + button->w, button->y, 4, 124, 108, 40);
}
else
{
FEPrintString(button->Name, button->x * 2 + button->w, button->y, 4, 128, 128, 128);
}
}
}
#endif
} }
#if defined(_DEBUG) || defined(DEBUG_OPTIONS) #if defined(_DEBUG) || defined(DEBUG_OPTIONS)
@ -888,10 +1032,14 @@ void DrawScreen(PSXSCREEN *pScr)
addPrim(&current->ot[3], &extraDummy); addPrim(&current->ot[3], &extraDummy);
} }
} }
#ifdef PSX
else else
{ {
EndFrame(); EndFrame();
} }
#else
EndFrame();
#endif
} }
@ -1224,60 +1372,52 @@ void ReInitScreens(void)
/* end block 3 */ /* end block 3 */
// End Line: 4370 // End Line: 4370
DR_MOVE In; int NewButton(short dir)
DR_MOVE Out;
RECT16 storeRect = { 768, 475, 255, 36 };
// [D] [T]
void NewSelection(short dir)
{ {
PSXBUTTON *pNewB; PSXBUTTON *pNewB;
RECT16 rect; RECT16 rect;
if (pCurrScreen->numButtons == 0) if (pCurrScreen->numButtons == 0)
{ return -1;
#ifndef PSX
EndFrame(); //do not overflow draw buffers
#endif
return;
}
pNewB = pCurrButton; pNewB = pCurrButton;
int btn = 0;
// any buttons pressed? // any buttons pressed?
if (dir != 0) if (dir != 0)
{ {
SetDrawMove(&In, &storeRect, pCurrButton->s_x, pCurrButton->s_y); SetDrawMove(&In, &storeRect, pCurrButton->s_x, pCurrButton->s_y);
addPrim(current->ot+9, &In); addPrim(current->ot+9, &In);
}
int btn = 0; if ((dir & 0x1000) != 0)
{
btn = pCurrButton->u;
}
else if ((dir & 0x4000) != 0)
{
btn = pCurrButton->d;
}
else if ((dir & 0x8000) != 0)
{
btn = pCurrButton->l;
}
else if ((dir & 0x2000) != 0)
{
btn = pCurrButton->r;
}
if ((dir & 0x1000) != 0) if (btn != 0)
{ {
btn = pCurrButton->u; FESound(3);
} pNewB = &pCurrScreen->buttons[btn - 1];
else if ((dir & 0x4000) != 0) }
{
btn = pCurrButton->d;
}
else if ((dir & 0x8000) != 0)
{
btn = pCurrButton->l;
}
else if ((dir & 0x2000) != 0)
{
btn = pCurrButton->r;
} }
pCurrButton = pNewB;
if (btn != 0) #ifdef PSX
{ rect.x = pCurrButton->s_x;
FESound(3); rect.y = pCurrButton->s_y;
pNewB = &pCurrScreen->buttons[btn - 1];
}
rect.x = pNewB->s_x;
rect.y = pNewB->s_y;
rect.w = 255; rect.w = 255;
rect.h = 36; rect.h = 36;
@ -1289,8 +1429,6 @@ void NewSelection(short dir)
addPrim(current->ot + 6, &HighlightSprt); addPrim(current->ot + 6, &HighlightSprt);
addPrim(current->ot + 7, &HighlightDummy); addPrim(current->ot + 7, &HighlightDummy);
pCurrButton = pNewB;
if ((pNewB->action >> 8) == 3) { if ((pNewB->action >> 8) == 3) {
FEPrintString(pNewB->Name, pNewB->x * 2 + pNewB->w, pNewB->y, 4, 32, 32, 32); FEPrintString(pNewB->Name, pNewB->x * 2 + pNewB->w, pNewB->y, 4, 32, 32, 32);
} }
@ -1305,8 +1443,19 @@ void NewSelection(short dir)
FEPrintString(pNewB->Name, pNewB->x * 2 + pNewB->w, pNewB->y, 4, 128, 128, 128); FEPrintString(pNewB->Name, pNewB->x * 2 + pNewB->w, pNewB->y, 4, 128, 128, 128);
} }
} }
#endif
return btn;
}
// [D] [T]
void NewSelection(short dir)
{
#ifdef PSX
NewButton(dir);
EndFrame(); EndFrame();
#else
NewButton(dir);
#endif
} }
@ -1590,7 +1739,52 @@ void PadChecks(void)
} }
} }
// [A] - was inlined in DoFrontEnd
void InitFrontend(void)
{
FEInitCdIcon();
ResetGraph(1);
SetDispMask(0);
bRedrawFrontend = 0;
gInFrontend = 1;
idle_timer = VSync(-1);
LoadFrontendScreens();
SetupBackgroundPolys();
SetupScreenSprts(&PsxScreens[0]);
}
// [A] - was inlined in DoFrontEnd
void InitDisplay(void)
{
SetDispMask(0);
ResetGraph(0);
SetFEDrawMode();
EnableDisplay();
#ifdef PSX
DrawScreen(pCurrScreen);
EndFrame();
NewSelection(0);
// REALLY make sure the screen is cleared
EndFrame();
EndFrame();
EndFrame();
EndFrame();
EndFrame();
EndFrame();
#endif
SetDispMask(1);
}
// decompiled code // decompiled code
// original method signature: // original method signature:
@ -1630,46 +1824,9 @@ void PadChecks(void)
// [D] [T] // [D] [T]
void DoFrontEnd(void) void DoFrontEnd(void)
{ {
FEInitCdIcon(); InitFrontend();
InitDisplay();
ResetGraph(1);
SetDispMask(0);
bRedrawFrontend = 0;
gInFrontend = 1;
idle_timer = VSync(-1);
LoadFrontendScreens();
pCurrScreen = PsxScreens;
pCurrButton = PsxScreens[0].buttons;
SetupBackgroundPolys();
SetupScreenSprts(pCurrScreen);
SetDispMask(0);
ResetGraph(0);
SetFEDrawMode();
SetVideoMode(video_mode);
EnableDisplay();
DrawScreen(pCurrScreen);
EndFrame();
NewSelection(0);
EndFrame();
EndFrame();
EndFrame();
EndFrame();
EndFrame();
EndFrame();
SetDispMask(1);
do do
{ {
PadChecks(); PadChecks();
@ -1693,16 +1850,7 @@ void DoFrontEnd(void)
} }
#ifndef PSX #ifndef PSX
if (bRedrawFrontend)
{
// flush the old screen
EndFrame();
bRedrawFrontend = 0;
}
DrawScreen(pCurrScreen); DrawScreen(pCurrScreen);
NewSelection(0);
#else #else
if (bRedrawFrontend) if (bRedrawFrontend)
{ {
@ -3859,12 +4007,14 @@ void DisplayScoreTable(void)
offset = 32; offset = 32;
else if (GameType == GAME_CAPTURETHEFLAG) else if (GameType == GAME_CAPTURETHEFLAG)
offset = 40; offset = 40;
else if (GameType == GAME_CHECKPOINT && NumPlayers == 2)
offset = 56;
else else
offset = (GameType - 4U) * 8; offset = (GameType - 4U) * 8;
if (GameType != GAME_PURSUIT && GameType != GAME_SURVIVAL) if (GameType != GAME_PURSUIT && GameType != GAME_SURVIVAL)
{ {
sprintf(text, "%s", gameNames[offset + GameLevel * 2 + GameNum]); sprintf(text, "%s", GAMEMODE_AREA_NAME(GameLevel, offset, GameNum));
FEPrintStringSized(text, 420, 206, 0xc00, 2, otherCol.r, otherCol.g, otherCol.b); FEPrintStringSized(text, 420, 206, 0xc00, 2, otherCol.r, otherCol.g, otherCol.b);
} }
@ -3879,7 +4029,7 @@ void DisplayScoreTable(void)
{ {
if (pSE[i].items != -1) if (pSE[i].items != -1)
{ {
sprintf(text, "%d"); sprintf(text, "%d", pSE[i].items);
FEPrintString(text, 140, offset, 2, scoreCol.r, scoreCol.g, scoreCol.b); FEPrintString(text, 140, offset, 2, scoreCol.r, scoreCol.g, scoreCol.b);
} }
} }
@ -3924,9 +4074,12 @@ int ScoreScreen(int bSetup)
if (bSetup) if (bSetup)
{ {
GameLevel = 0; GameLevel = 0;
DisplayScoreTable(); DisplayScoreTable();
bDoingScores = 1; bDoingScores = 1;
currSelIndex = 0; currSelIndex = 0;
return 0; return 0;
} }
@ -3934,57 +4087,37 @@ int ScoreScreen(int bSetup)
{ {
if (currSelIndex == 0) if (currSelIndex == 0)
{ {
if (GameType != GAME_SURVIVAL && GameType != GAME_PURSUIT) if (GameType == GAME_SURVIVAL || GameType == GAME_PURSUIT)
{ {
if (GameNum == 1) if (--GameLevel < 0)
{
GameNum = 0;
}
else
{
GameNum = 1;
GameLevel--;
if (GameLevel < 0)
GameLevel = 3;
}
DisplayScoreTable();
bRedrawFrontend = 1;
}
else
{
GameLevel--;
if (GameLevel < 0)
GameLevel = 3; GameLevel = 3;
GameNum = 0; GameNum = 0;
DisplayScoreTable(); }
bRedrawFrontend = 1; else
{
GameNum ^= 1;
} }
} }
else else
{ {
if (GameType != GAME_SURVIVAL && GameType != GAME_PURSUIT && GameNum == 0) if (GameType == GAME_SURVIVAL || GameType == GAME_PURSUIT)
{ {
GameNum = 1; if (++GameLevel > 3)
DisplayScoreTable();
bRedrawFrontend = 1;
}
else
{
GameLevel++;
if (GameLevel > 3)
GameLevel = 0; GameLevel = 0;
GameNum = 0; GameNum = 0;
DisplayScoreTable();
bRedrawFrontend = 1;
} }
else
{
GameNum ^= 1;
}
} }
#ifdef PSX
DisplayScoreTable();
bRedrawFrontend = 1;
#endif
} }
else if (fePad & 0x10) else if (fePad & 0x10)
{ {
@ -3993,7 +4126,7 @@ int ScoreScreen(int bSetup)
} }
else if ((fePad & 0x1000) || (fePad & 0x4000)) else if ((fePad & 0x1000) || (fePad & 0x4000))
{ {
currSelIndex = currSelIndex ^ 1; currSelIndex ^= 1;
} }
#ifndef PSX #ifndef PSX
@ -4586,18 +4719,18 @@ int GameNameScreen(int bSetup)
{ {
if (GameType == GAME_TAKEADRIVE && NumPlayers == 2) if (GameType == GAME_TAKEADRIVE && NumPlayers == 2)
offset = 0x30; offset = 48;
else if (GameType == GAME_COPSANDROBBERS) else if (GameType == GAME_COPSANDROBBERS)
offset = 0x20; offset = 32;
else if (GameType == GAME_CAPTURETHEFLAG) else if (GameType == GAME_CAPTURETHEFLAG)
offset = 0x28; offset = 40;
else if (GameType == GAME_CHECKPOINT && NumPlayers == 2) else if (GameType == GAME_CHECKPOINT && NumPlayers == 2)
offset = 0x38; offset = 56;
else else
offset = (GameType - 4U) * 8; offset = (GameType - 4U) * 8;
sprintf(pCurrScreen->buttons[0].Name, gameNames[offset + GameLevel * 2]); strcpy_s(pCurrScreen->buttons[0].Name, GAMEMODE_AREA_NAME(GameLevel, offset, 0));
sprintf(pCurrScreen->buttons[1].Name, gameNames[offset + GameLevel * 2 + 1]); strcpy_s(pCurrScreen->buttons[1].Name, GAMEMODE_AREA_NAME(GameLevel, offset, 1));
} }
return 0; return 0;