VOID PAL_ShowDialogText( LPCSTR lpszText ) /*++ Purpose: Show one line of the dialog text. Parameters: [IN] lpszText - the text to be shown. Return value: None. --*/ { SDL_Rect rect; int x, y, len = strlen(lpszText); PAL_ClearKeyState(); g_TextLib.bIcon = 0; if (gpGlobals->fInBattle && !g_fUpdatedInBattle) { // // Update the screen in battle, or the graphics may seem messed up // VIDEO_UpdateScreen(NULL); g_fUpdatedInBattle = TRUE; } if (g_TextLib.nCurrentDialogLine > 3) { // // The rest dialogs should be shown in the next page. // PAL_DialogWaitForKey(); g_TextLib.nCurrentDialogLine = 0; VIDEO_RestoreScreen(); VIDEO_UpdateScreen(NULL); } x = PAL_X(g_TextLib.posDialogText); y = PAL_Y(g_TextLib.posDialogText) + g_TextLib.nCurrentDialogLine * 18; if (g_TextLib.bDialogPosition == kDialogCenterWindow) { // // The text should be shown in a small window at the center of the screen // #ifndef PAL_CLASSIC if (gpGlobals->fInBattle && g_Battle.BattleResult == kBattleResultOnGoing) { PAL_BattleUIShowText(lpszText, 1400); } else #endif { PAL_POS pos; LPBOX lpBox; // // Create the window box // pos = PAL_XY(PAL_X(g_TextLib.posDialogText) - len * 4, PAL_Y(g_TextLib.posDialogText)); lpBox = PAL_CreateSingleLineBox(pos, (len + 1) / 2, TRUE); rect.x = PAL_X(pos); rect.y = PAL_Y(pos); rect.w = 320 - rect.x * 2 + 32; rect.h = 64; // // Show the text on the screen // pos = PAL_XY(PAL_X(pos) + 8 + ((len & 1) << 2), PAL_Y(pos) + 10); PAL_DrawText(lpszText, pos, 0, FALSE, FALSE); VIDEO_UpdateScreen(&rect); PAL_DialogWaitForKey(); // // Delete the box // PAL_DeleteBox(lpBox); VIDEO_UpdateScreen(&rect); PAL_EndDialog(); } } else { if (g_TextLib.nCurrentDialogLine == 0 && g_TextLib.bDialogPosition != kDialogCenter && (BYTE)lpszText[len - 1] == 0x47 && (BYTE)lpszText[len - 2] == 0xA1) { // // name of character // PAL_DrawText(lpszText, g_TextLib.posDialogTitle, FONT_COLOR_CYAN_ALT, TRUE, TRUE); } else { // // normal texts // char text[3]; if (!g_TextLib.fPlayingRNG && g_TextLib.nCurrentDialogLine == 0) { // // Save the screen before we show the first line of dialog // VIDEO_BackupScreen(); } while (lpszText != NULL && *lpszText != '\0') { switch (*lpszText) { case '-': // // Set the font color to Cyan // if (g_TextLib.bCurrentFontColor == FONT_COLOR_CYAN) { g_TextLib.bCurrentFontColor = FONT_COLOR_DEFAULT; } else { g_TextLib.bCurrentFontColor = FONT_COLOR_CYAN; } lpszText++; break; case '\'': // // Set the font color to Red // if (g_TextLib.bCurrentFontColor == FONT_COLOR_RED) { g_TextLib.bCurrentFontColor = FONT_COLOR_DEFAULT; } else { g_TextLib.bCurrentFontColor = FONT_COLOR_RED; } lpszText++; break; case '\"': // // Set the font color to Yellow // if (g_TextLib.bCurrentFontColor == FONT_COLOR_YELLOW) { g_TextLib.bCurrentFontColor = FONT_COLOR_DEFAULT; } else { g_TextLib.bCurrentFontColor = FONT_COLOR_YELLOW; } lpszText++; break; case '$': // // Set the delay time of text-displaying // g_TextLib.iDelayTime = atoi(lpszText + 1) * 10 / 7; lpszText += 3; break; case '~': // // Delay for a period and quit // UTIL_Delay(atoi(lpszText + 1) * 80 / 7); g_TextLib.nCurrentDialogLine = 0; g_TextLib.fUserSkip = FALSE; return; // don't go further case ')': // // Set the waiting icon // g_TextLib.bIcon = 1; lpszText++; break; case '(': // // Set the waiting icon // g_TextLib.bIcon = 2; lpszText++; break; case '\\': lpszText++; default: if (*lpszText & 0x80) { text[0] = lpszText[0]; text[1] = lpszText[1]; text[2] = '\0'; lpszText += 2; } else { text[0] = *lpszText; text[1] = '\0'; lpszText++; } PAL_DrawText(text, PAL_XY(x, y), g_TextLib.bCurrentFontColor, TRUE, TRUE); x += ((text[0] & 0x80) ? 16 : 8); if (!g_TextLib.fUserSkip) { PAL_ClearKeyState(); UTIL_Delay(g_TextLib.iDelayTime * 8); if (g_InputState.dwKeyPress & (kKeySearch | kKeyMenu)) { // // User pressed a key to skip the dialog // g_TextLib.fUserSkip = TRUE; } } } } g_TextLib.posIcon = PAL_XY(x, y); g_TextLib.nCurrentDialogLine++; } } }
VOID PAL_BattleStartFrame( VOID ) /*++ Purpose: Called once per video frame in battle. Parameters: None. Return value: None. --*/ { int i; int iMax; BOOL fEnded; WORD wPlayerRole; WORD wDexterity; FLOAT flMax; PAL_BattleUpdateFighters(); // // Update the scene // PAL_BattleMakeScene(); SDL_BlitSurface(g_Battle.lpSceneBuf, NULL, gpScreen, NULL); // // Check if the battle is over // fEnded = TRUE; for (i = 0; i <= g_Battle.wMaxEnemyIndex; i++) { if (g_Battle.rgEnemy[i].wObjectID != 0) { fEnded = FALSE; break; } } if (fEnded) { // // All enemies are cleared. Won the battle. // g_Battle.BattleResult = kBattleResultWon; SOUND_Play(-1); return; } else { fEnded = TRUE; for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { wPlayerRole = gpGlobals->rgParty[i].wPlayerRole; if (gpGlobals->g.PlayerRoles.rgwHP[wPlayerRole] != 0 || gpGlobals->rgPlayerStatus[wPlayerRole][kStatusPuppet] != 0) { fEnded = FALSE; break; } } if (fEnded) { // // All players are dead. Lost the battle. // g_Battle.BattleResult = kBattleResultLost; return; } } // // Run the logic for all enemies // for (i = 0; i <= g_Battle.wMaxEnemyIndex; i++) { if (g_Battle.rgEnemy[i].wObjectID == 0) { continue; } if (g_Battle.rgEnemy[i].fTurnStart) { g_Battle.rgEnemy[i].wScriptOnTurnStart = PAL_RunTriggerScript(g_Battle.rgEnemy[i].wScriptOnTurnStart, i); g_Battle.rgEnemy[i].fTurnStart = FALSE; } } for (i = 0; i <= g_Battle.wMaxEnemyIndex; i++) { if (g_Battle.rgEnemy[i].wObjectID == 0) { continue; } switch (g_Battle.rgEnemy[i].state) { case kFighterWait: flMax = PAL_GetTimeChargingSpeed(PAL_GetEnemyDexterity(i)); if (flMax != 0) { g_Battle.rgEnemy[i].flTimeMeter += flMax; if (g_Battle.rgEnemy[i].flTimeMeter > 100 && flMax > 0) { g_Battle.rgEnemy[i].state = kFighterCom; } } break; case kFighterCom: g_Battle.rgEnemy[i].wScriptOnReady = PAL_RunTriggerScript(g_Battle.rgEnemy[i].wScriptOnReady, i); g_Battle.rgEnemy[i].state = kFighterAct; break; case kFighterAct: ////TEST/////////////////////////////////////////////////////////// SOUND_Play(g_Battle.rgEnemy[i].e.wAttackSound); if (g_Battle.rgEnemy[i].fFirstMoveDone) PAL_BattleUIShowText(va("enemy %d attack (2nd)",i), 500); else PAL_BattleUIShowText(va("enemy %d attack",i), 500); g_Battle.rgEnemy[i].flTimeMeter =0; g_Battle.rgEnemy[i].state = kFighterWait; //////////////////////////////////////////////////////////////////// if (!g_Battle.rgEnemy[i].fFirstMoveDone) { if (g_Battle.rgEnemy[i].e.wDualMove >= 2 || (g_Battle.rgEnemy[i].e.wDualMove != 0 && RandomLong(0, 1))) { g_Battle.rgEnemy[i].flTimeMeter = 100; g_Battle.rgEnemy[i].state = kFighterWait; g_Battle.rgEnemy[i].fFirstMoveDone = TRUE; break; } } g_Battle.rgEnemy[i].fFirstMoveDone = FALSE; g_Battle.rgEnemy[i].fTurnStart = TRUE; break; } } // // Update the battle UI // PAL_BattleUIUpdate(); // // Run the logic for all players // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { wPlayerRole = gpGlobals->rgParty[i].wPlayerRole; // // Skip dead players // if (gpGlobals->g.PlayerRoles.rgwHP[wPlayerRole] == 0 && gpGlobals->rgPlayerStatus[wPlayerRole][kStatusPuppet] == 0) { g_Battle.rgPlayer[i].state = kFighterWait; g_Battle.rgPlayer[i].flTimeMeter = 0; continue; } switch (g_Battle.rgPlayer[i].state) { case kFighterWait: wDexterity = PAL_GetPlayerActualDexterity(wPlayerRole); g_Battle.rgPlayer[i].flTimeMeter += PAL_GetTimeChargingSpeed(wDexterity) * g_Battle.rgPlayer[i].flTimeSpeedModifier; break; case kFighterCom: if (g_Battle.UI.state == kBattleUIWait) { PAL_BattleUIPlayerReady(i); } break; case kFighterAct: wDexterity = PAL_GetPlayerActualDexterity(wPlayerRole); g_Battle.rgPlayer[i].action.flRemainingTime -= PAL_GetTimeChargingSpeed(wDexterity); if (g_Battle.rgPlayer[i].action.flRemainingTime < 0) { // // Perform the action for this player. // PAL_BattlePlayerPerformAction(i); // // Reduce the time for other players when uses coopmagic // if (g_Battle.rgPlayer[i].action.ActionType == kBattleActionCoopMagic) { for (iMax = 0; iMax <= gpGlobals->wMaxPartyMemberIndex; iMax++) { g_Battle.rgPlayer[iMax].flTimeMeter = 0; g_Battle.rgPlayer[iMax].flTimeSpeedModifier = 2.0f; } } else { g_Battle.rgPlayer[i].flTimeMeter = 0; } // // Revert this player back to waiting state. // g_Battle.rgPlayer[i].state = kFighterWait; g_Battle.rgPlayer[i].flTimeSpeedModifier = 1.0f; } break; } } // // Start the UI for the fastest and ready player // flMax = 0; iMax = 0; for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { if (g_Battle.rgPlayer[i].state == kFighterCom || (g_Battle.rgPlayer[i].state == kFighterAct && g_Battle.rgPlayer[i].action.ActionType == kBattleActionCoopMagic)) { flMax = 0; break; } else if (g_Battle.rgPlayer[i].state == kFighterWait) { if (g_Battle.rgPlayer[i].flTimeMeter > flMax) { iMax = i; flMax = g_Battle.rgPlayer[i].flTimeMeter; } } } if (flMax > 100.0f) { g_Battle.rgPlayer[iMax].state = kFighterCom; g_Battle.rgPlayer[iMax].fDefending = FALSE; } ////TEST/////////////////////////////////////////////////////////-START if (g_InputState.dwKeyPress & kKeyFlee){ for (i = 0; i < 5; i++){ gpGlobals->g.PlayerRoles.rgwHP[i] = 0; } return; } ////TEST/////////////////////////////////////////////////////////-END }