/*++ Load the screen background picture of the battle. --*/ static VOID PAL_LoadBattleBackground(void) { PAL_LARGE BYTE buf[320 * 200]; // // Create the surface // g_Battle.lpBackground = SDL_CreateRGBSurface(gpScreen->flags & ~SDL_HWSURFACE, 320, 200, 8, gpScreen->format->Rmask, gpScreen->format->Gmask, gpScreen->format->Bmask, gpScreen->format->Amask); if (g_Battle.lpBackground == NULL) { TerminateOnError("PAL_LoadBattleBackground(): failed to create surface!"); } #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetSurfacePalette(g_Battle.lpBackground, gpScreen->format->palette); #else SDL_SetPalette(g_Battle.lpBackground, SDL_PHYSPAL | SDL_LOGPAL, VIDEO_GetPalette(), 0, 256); #endif // // Load the picture // PAL_MKFDecompressChunk(buf, 320 * 200, gpGlobals->wNumBattleField, gpGlobals->f.fpFBP); // // Draw the picture to the surface. // PAL_FBPBlitToSurface(buf, g_Battle.lpBackground); }
static VOID PAL_LoadBattleBackground( VOID ) /*++ Purpose: Load the screen background picture of the battle. Parameters: None. Return value: None. --*/ { PAL_LARGE BYTE buf[320 * 200]; UTIL_WriteLog(LOG_DEBUG, "[0x%08x][%s][%s] - %s", (long)PAL_LoadBattleBackground, "PAL_LoadBattleBackground", __FILE__, "start"); // // Create the surface // g_Battle.lpBackground = SDL_CreateRGBSurface(gpScreen->flags & ~SDL_HWSURFACE, 320, 200, 8, gpScreen->format->Rmask, gpScreen->format->Gmask, gpScreen->format->Bmask, gpScreen->format->Amask); if (g_Battle.lpBackground == NULL) { TerminateOnError("PAL_LoadBattleBackground(): failed to create surface!"); } // // Load the picture // PAL_MKFDecompressChunk(buf, 320 * 200, gpGlobals->wNumBattleField, gpGlobals->f.fpFBP); // // Draw the picture to the surface. // PAL_FBPBlitToSurface(buf, g_Battle.lpBackground); UTIL_WriteLog(LOG_DEBUG, "[0x%08x][%s][%s] - %s", (long)PAL_LoadBattleBackground, "PAL_LoadBattleBackground", __FILE__, "end"); }
VOID PAL_DrawOpeningMenuBackground( VOID ) /*++ Purpose: Draw the background of the main menu. Parameters: None. Return value: None. --*/ { LPBYTE buf; buf = (LPBYTE)malloc(320 * 200); if (buf == NULL) { return; } // // Read the picture from fbp.mkf. // PAL_MKFDecompressChunk(buf, 320 * 200, MAINMENU_BACKGROUND_FBPNUM, gpGlobals->f.fpFBP); // // ...and blit it to the screen buffer. // PAL_FBPBlitToSurface(buf, gpScreen); VIDEO_UpdateScreen(NULL); free(buf); }
VOID PAL_LoadResources( VOID ) /*++ Purpose: Load the game resources if needed. Parameters: None. Return value: None. --*/ { int i, index, l, n; WORD wPlayerID, wSpriteNum; if (gpResources == NULL || gpResources->bLoadFlags == 0) { return; } // // Load scene // if (gpResources->bLoadFlags & kLoadScene) { FILE *fpMAP, *fpGOP; fpMAP = UTIL_OpenRequiredFile("map.mkf"); fpGOP = UTIL_OpenRequiredFile("gop.mkf"); if (gpGlobals->fEnteringScene) { gpGlobals->wScreenWave = 0; gpGlobals->sWaveProgression = 0; } // // Free previous loaded scene (sprites and map) // PAL_FreeEventObjectSprites(); PAL_FreeMap(gpResources->lpMap); // // Load map // i = gpGlobals->wNumScene - 1; gpResources->lpMap = PAL_LoadMap(gpGlobals->g.rgScene[i].wMapNum, fpMAP, fpGOP); if (gpResources->lpMap == NULL) { fclose(fpMAP); fclose(fpGOP); TerminateOnError("PAL_LoadResources(): Fail to load map #%d (scene #%d) !", gpGlobals->g.rgScene[i].wMapNum, gpGlobals->wNumScene); } // // Load sprites // index = gpGlobals->g.rgScene[i].wEventObjectIndex; gpResources->nEventObject = gpGlobals->g.rgScene[i + 1].wEventObjectIndex; gpResources->nEventObject -= index; if (gpResources->nEventObject > 0) { gpResources->lppEventObjectSprites = (LPSPRITE *)UTIL_calloc(gpResources->nEventObject, sizeof(LPSPRITE)); } for (i = 0; i < gpResources->nEventObject; i++, index++) { n = gpGlobals->g.lprgEventObject[index].wSpriteNum; if (n == 0) { // // this event object has no sprite // gpResources->lppEventObjectSprites[i] = NULL; continue; } l = PAL_MKFGetDecompressedSize(n, gpGlobals->f.fpMGO); gpResources->lppEventObjectSprites[i] = (LPSPRITE)UTIL_malloc(l); if (PAL_MKFDecompressChunk(gpResources->lppEventObjectSprites[i], l, n, gpGlobals->f.fpMGO) > 0) { gpGlobals->g.lprgEventObject[index].nSpriteFramesAuto = PAL_SpriteGetNumFrames(gpResources->lppEventObjectSprites[i]); } } gpGlobals->partyoffset = PAL_XY(160, 112); fclose(fpGOP); fclose(fpMAP); } // // Load player sprites // if (gpResources->bLoadFlags & kLoadPlayerSprite) { // // Free previous loaded player sprites // PAL_FreePlayerSprites(); for (i = 0; i <= (short)gpGlobals->wMaxPartyMemberIndex; i++) { wPlayerID = gpGlobals->rgParty[i].wPlayerRole; assert(wPlayerID < MAX_PLAYER_ROLES); // // Load player sprite // wSpriteNum = gpGlobals->g.PlayerRoles.rgwSpriteNum[wPlayerID]; l = PAL_MKFGetDecompressedSize(wSpriteNum, gpGlobals->f.fpMGO); gpResources->rglpPlayerSprite[i] = (LPSPRITE)UTIL_malloc(l); PAL_MKFDecompressChunk(gpResources->rglpPlayerSprite[i], l, wSpriteNum, gpGlobals->f.fpMGO); } if (gpGlobals->nFollower > 0) { // // Load the follower sprite // wSpriteNum = gpGlobals->rgParty[i].wPlayerRole; l = PAL_MKFGetDecompressedSize(wSpriteNum, gpGlobals->f.fpMGO); gpResources->rglpPlayerSprite[i] = (LPSPRITE)UTIL_malloc(l); PAL_MKFDecompressChunk(gpResources->rglpPlayerSprite[i], l, wSpriteNum, gpGlobals->f.fpMGO); } } // // Clear all of the load flags // gpResources->bLoadFlags = 0; }
/*++ Load all the loaded sprites. --*/ VOID PAL_LoadBattleSprites(void) { int i, l, x, y, s; FILE *fp; PAL_FreeBattleSprites(); fp = UTIL_OpenRequiredFile("abc.mkf"); // // Load battle sprites for players // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { s = PAL_GetPlayerBattleSprite(gpGlobals->rgParty[i].wPlayerRole); l = PAL_MKFGetDecompressedSize(s, gpGlobals->f.fpF); if (l <= 0) { continue; } g_Battle.rgPlayer[i].lpSprite = UTIL_calloc(l, 1); PAL_MKFDecompressChunk(g_Battle.rgPlayer[i].lpSprite, l, s, gpGlobals->f.fpF); // // Set the default position for this player // x = g_rgPlayerPos[gpGlobals->wMaxPartyMemberIndex][i][0]; y = g_rgPlayerPos[gpGlobals->wMaxPartyMemberIndex][i][1]; g_Battle.rgPlayer[i].posOriginal = PAL_XY(x, y); g_Battle.rgPlayer[i].pos = PAL_XY(x, y); } // // Load battle sprites for enemies // for (i = 0; i < MAX_ENEMIES_IN_TEAM; i++) { if (g_Battle.rgEnemy[i].wObjectID == 0) { continue; } l = PAL_MKFGetDecompressedSize( gpGlobals->g.rgObject[g_Battle.rgEnemy[i].wObjectID].enemy.wEnemyID, fp); if (l <= 0) { continue; } g_Battle.rgEnemy[i].lpSprite = UTIL_calloc(l, 1); PAL_MKFDecompressChunk(g_Battle.rgEnemy[i].lpSprite, l, gpGlobals->g.rgObject[g_Battle.rgEnemy[i].wObjectID].enemy.wEnemyID, fp); // // Set the default position for this enemy // x = gpGlobals->g.EnemyPos.pos[i][g_Battle.wMaxEnemyIndex].x; y = gpGlobals->g.EnemyPos.pos[i][g_Battle.wMaxEnemyIndex].y; y += g_Battle.rgEnemy[i].e.wYPosOffset; g_Battle.rgEnemy[i].posOriginal = PAL_XY(x, y); g_Battle.rgEnemy[i].pos = PAL_XY(x, y); } fclose(fp); }
VOID PAL_ShowFBP( WORD wChunkNum, WORD wFade ) /*++ Purpose: Draw an FBP picture to the screen. Parameters: [IN] wChunkNum - number of chunk in fbp.mkf file. [IN] wFade - fading speed of showing the picture. Return value: None. --*/ { PAL_LARGE BYTE buf[320 * 200]; PAL_LARGE BYTE bufSprite[320 * 200]; const int rgIndex[6] = {0, 3, 1, 5, 2, 4}; SDL_Surface *p; int i, j, k; BYTE a, b; if (PAL_MKFDecompressChunk(buf, 320 * 200, wChunkNum, gpGlobals->f.fpFBP) <= 0) { memset(buf, 0, sizeof(buf)); } if (g_wCurEffectSprite != 0) { PAL_MKFDecompressChunk(bufSprite, 320 * 200, g_wCurEffectSprite, gpGlobals->f.fpMGO); } if (wFade) { wFade++; wFade *= 10; p = SDL_CreateRGBSurface(gpScreen->flags & ~SDL_HWSURFACE, 320, 200, 8, gpScreen->format->Rmask, gpScreen->format->Gmask, gpScreen->format->Bmask, gpScreen->format->Amask); #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetSurfacePalette(p, gpScreen->format->palette); #else SDL_SetPalette(p, SDL_PHYSPAL | SDL_LOGPAL, VIDEO_GetPalette(), 0, 256); #endif PAL_FBPBlitToSurface(buf, p); VIDEO_BackupScreen(); for (i = 0; i < 16; i++) { for (j = 0; j < 6; j++) { // // Blend the pixels in the 2 buffers, and put the result into the // backup buffer // for (k = rgIndex[j]; k < gpScreen->pitch * gpScreen->h; k += 6) { a = ((LPBYTE)(p->pixels))[k]; b = ((LPBYTE)(gpScreenBak->pixels))[k]; if (i > 0) { if ((a & 0x0F) > (b & 0x0F)) { b++; } else if ((a & 0x0F) < (b & 0x0F)) { b--; } } ((LPBYTE)(gpScreenBak->pixels))[k] = ((a & 0xF0) | (b & 0x0F)); } SDL_BlitSurface(gpScreenBak, NULL, gpScreen, NULL); if (g_wCurEffectSprite != 0) { int f = SDL_GetTicks() / 150; PAL_RLEBlitToSurface(PAL_SpriteGetFrame(bufSprite, f % PAL_SpriteGetNumFrames(bufSprite)), gpScreen, PAL_XY(0, 0)); } VIDEO_UpdateScreen(NULL); UTIL_Delay(wFade); } } SDL_FreeSurface(p); } // // HACKHACK: to make the ending show correctly // #ifdef PAL_WIN95 if (wChunkNum != 68) #else if (wChunkNum != 49) #endif { PAL_FBPBlitToSurface(buf, gpScreen); } VIDEO_UpdateScreen(NULL); }
VOID PAL_EndingAnimation( VOID ) /*++ Purpose: Show the ending animation.//就是灵儿独自面对合体水魔兽的动画 Parameters: None. Return value: None. --*/ { LPBYTE buf; LPBYTE bufGirl; SDL_Surface *pUpper; SDL_Surface *pLower; SDL_Rect srcrect, dstrect; int yPosGirl = 180; int i; buf = (LPBYTE)UTIL_calloc(1, 64000); bufGirl = (LPBYTE)UTIL_calloc(1, 6000); pUpper = SDL_CreateRGBSurface(gpScreen->flags & ~SDL_HWSURFACE, 320, 200, 8, gpScreen->format->Rmask, gpScreen->format->Gmask, gpScreen->format->Bmask, gpScreen->format->Amask); pLower = SDL_CreateRGBSurface(gpScreen->flags & ~SDL_HWSURFACE, 320, 200, 8, gpScreen->format->Rmask, gpScreen->format->Gmask, gpScreen->format->Bmask, gpScreen->format->Amask); #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetSurfacePalette(pUpper, gpScreen->format->palette); SDL_SetSurfacePalette(pLower, gpScreen->format->palette); #else SDL_SetPalette(pUpper, SDL_PHYSPAL | SDL_LOGPAL, VIDEO_GetPalette(), 0, 256); SDL_SetPalette(pLower, SDL_PHYSPAL | SDL_LOGPAL, VIDEO_GetPalette(), 0, 256); #endif #ifdef PAL_WIN95 PAL_MKFDecompressChunk(buf, 64000, 69, gpGlobals->f.fpFBP); PAL_FBPBlitToSurface(buf, pUpper); PAL_MKFDecompressChunk(buf, 64000, 70, gpGlobals->f.fpFBP); PAL_FBPBlitToSurface(buf, pLower); #else PAL_MKFDecompressChunk(buf, 64000, 61, gpGlobals->f.fpFBP); PAL_FBPBlitToSurface(buf, pUpper); PAL_MKFDecompressChunk(buf, 64000, 62, gpGlobals->f.fpFBP); PAL_FBPBlitToSurface(buf, pLower); #endif PAL_MKFDecompressChunk(buf, 64000, 571, gpGlobals->f.fpMGO); PAL_MKFDecompressChunk(bufGirl, 6000, 572, gpGlobals->f.fpMGO); srcrect.x = 0; dstrect.x = 0; srcrect.w = 320; dstrect.w = 320; gpGlobals->wScreenWave = 2; for (i = 0; i < 400; i++) { // // Draw the background // srcrect.y = 0; srcrect.h = 200 - i / 2; dstrect.y = i / 2; dstrect.h = 200 - i / 2; SDL_BlitSurface(pLower, &srcrect, gpScreen, &dstrect); srcrect.y = 200 - i / 2; srcrect.h = i / 2; dstrect.y = 0; dstrect.h = i / 2; SDL_BlitSurface(pUpper, &srcrect, gpScreen, &dstrect); PAL_ApplyWave(gpScreen); // // Draw the beast // PAL_RLEBlitToSurface(PAL_SpriteGetFrame(buf, 0), gpScreen, PAL_XY(0, -400 + i)); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(buf, 1), gpScreen, PAL_XY(0, -200 + i)); #ifdef PAL_WIN95 PAL_RLEBlitToSurface(buf + 0x8444, gpScreen, PAL_XY(0, -200 + i)); #else PAL_RLEBlitToSurface(PAL_SpriteGetFrame(buf, 1), gpScreen, PAL_XY(0, -200 + i)); #endif // // Draw the girl // yPosGirl -= i & 1; if (yPosGirl < 80) { yPosGirl = 80; } PAL_RLEBlitToSurface(PAL_SpriteGetFrame(bufGirl, (SDL_GetTicks() / 50) % 4), gpScreen, PAL_XY(220, yPosGirl)); // // Update the screen // VIDEO_UpdateScreen(NULL); if (gpGlobals->fNeedToFadeIn) { PAL_FadeIn(gpGlobals->wNumPalette, gpGlobals->fNightPalette, 1); gpGlobals->fNeedToFadeIn = FALSE; #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetSurfacePalette(pUpper, gpScreen->format->palette); SDL_SetSurfacePalette(pLower, gpScreen->format->palette); #else SDL_SetPalette(pUpper, SDL_LOGPAL | SDL_PHYSPAL, VIDEO_GetPalette(), 0, 256); SDL_SetPalette(pLower, SDL_LOGPAL | SDL_PHYSPAL, VIDEO_GetPalette(), 0, 256); #endif } UTIL_Delay(50); } gpGlobals->wScreenWave = 0; SDL_FreeSurface(pUpper); SDL_FreeSurface(pLower); free(buf); free(bufGirl); }
VOID PAL_ScrollFBP( WORD wChunkNum, WORD wScrollSpeed, BOOL fScrollDown ) /*++ Purpose: Scroll up an FBP picture to the screen. Parameters: [IN] wChunkNum - number of chunk in fbp.mkf file. [IN] wScrollSpeed - scrolling speed of showing the picture. [IN] fScrollDown - TRUE if scroll down, FALSE if scroll up. Return value: None. --*/ { SDL_Surface *p; PAL_LARGE BYTE buf[320 * 200]; PAL_LARGE BYTE bufSprite[320 * 200]; int i, l; SDL_Rect rect, dstrect; if (PAL_MKFDecompressChunk(buf, 320 * 200, wChunkNum, gpGlobals->f.fpFBP) <= 0) { return; } if (g_wCurEffectSprite != 0) { PAL_MKFDecompressChunk(bufSprite, 320 * 200, g_wCurEffectSprite, gpGlobals->f.fpMGO); } p = SDL_CreateRGBSurface(gpScreen->flags & ~SDL_HWSURFACE, 320, 200, 8, gpScreen->format->Rmask, gpScreen->format->Gmask, gpScreen->format->Bmask, gpScreen->format->Amask); if (p == NULL) { return; } #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetSurfacePalette(p, gpScreen->format->palette); #else SDL_SetPalette(p, SDL_PHYSPAL | SDL_LOGPAL, VIDEO_GetPalette(), 0, 256); #endif VIDEO_BackupScreen(); PAL_FBPBlitToSurface(buf, p); if (wScrollSpeed == 0) { wScrollSpeed = 1; } rect.x = 0; rect.w = 320; dstrect.x = 0; dstrect.w = 320; for (l = 0; l < 220; l++) { i = l; if (i > 200) { i = 200; } if (fScrollDown) { rect.y = 0; dstrect.y = i; rect.h = 200 - i; dstrect.h = 200 - i; } else { rect.y = i; dstrect.y = 0; rect.h = 200 - i; dstrect.h = 200 - i; } SDL_BlitSurface(gpScreenBak, &rect, gpScreen, &dstrect); if (fScrollDown) { rect.y = 200 - i; dstrect.y = 0; rect.h = i; dstrect.h = i; } else { rect.y = 0; dstrect.y = 200 - i; rect.h = i; dstrect.h = i; } SDL_BlitSurface(p, &rect, gpScreen, &dstrect); PAL_ApplyWave(gpScreen); if (g_wCurEffectSprite != 0) { int f = SDL_GetTicks() / 150; PAL_RLEBlitToSurface(PAL_SpriteGetFrame(bufSprite, f % PAL_SpriteGetNumFrames(bufSprite)), gpScreen, PAL_XY(0, 0)); } VIDEO_UpdateScreen(NULL); if (gpGlobals->fNeedToFadeIn) { PAL_FadeIn(gpGlobals->wNumPalette, gpGlobals->fNightPalette, 1); gpGlobals->fNeedToFadeIn = FALSE; #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetSurfacePalette(p, gpScreen->format->palette); #else SDL_SetPalette(p, SDL_PHYSPAL | SDL_LOGPAL, VIDEO_GetPalette(), 0, 256); #endif } UTIL_Delay(800 / wScrollSpeed); } SDL_BlitSurface(p, NULL, gpScreen, NULL); SDL_FreeSurface(p); VIDEO_UpdateScreen(NULL); }
VOID PAL_LoadBattleSprites( VOID ) /*++ Purpose: Load all the loaded sprites. Parameters: None. Return value: None. --*/ { int i, l, x, y, s; FILE *fp; UTIL_WriteLog(LOG_DEBUG, "[0x%08x][%s][%s] - %s", (long)PAL_LoadBattleSprites, "PAL_LoadBattleSprites", __FILE__, "start"); PAL_FreeBattleSprites(); fp = UTIL_OpenRequiredFile("abc.mkf"); // // Load battle sprites for players // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { s = PAL_GetPlayerBattleSprite(gpGlobals->rgParty[i].wPlayerRole); l = PAL_MKFGetDecompressedSize(s, gpGlobals->f.fpF); if (l <= 0) { continue; } g_Battle.rgPlayer[i].lpSprite = UTIL_calloc(l, 1); PAL_MKFDecompressChunk(g_Battle.rgPlayer[i].lpSprite, l, s, gpGlobals->f.fpF); // // Set the default position for this player // x = g_rgPlayerPos[gpGlobals->wMaxPartyMemberIndex][i][0]; y = g_rgPlayerPos[gpGlobals->wMaxPartyMemberIndex][i][1]; g_Battle.rgPlayer[i].posOriginal = PAL_XY(x, y); g_Battle.rgPlayer[i].pos = PAL_XY(x, y); } // // Load battle sprites for enemies // for (i = 0; i < MAX_ENEMIES_IN_TEAM; i++) { if (g_Battle.rgEnemy[i].wObjectID == 0) { continue; } l = PAL_MKFGetDecompressedSize( gpGlobals->g.rgObject[g_Battle.rgEnemy[i].wObjectID].enemy.wEnemyID, fp); if (l <= 0) { continue; } g_Battle.rgEnemy[i].lpSprite = UTIL_calloc(l, 1); PAL_MKFDecompressChunk(g_Battle.rgEnemy[i].lpSprite, l, gpGlobals->g.rgObject[g_Battle.rgEnemy[i].wObjectID].enemy.wEnemyID, fp); // // Set the default position for this enemy // x = gpGlobals->g.EnemyPos.pos[i][g_Battle.wMaxEnemyIndex].x; y = gpGlobals->g.EnemyPos.pos[i][g_Battle.wMaxEnemyIndex].y; y += g_Battle.rgEnemy[i].e.wYPosOffset; g_Battle.rgEnemy[i].posOriginal = PAL_XY(x, y); g_Battle.rgEnemy[i].pos = PAL_XY(x, y); } fclose(fp); UTIL_WriteLog(LOG_DEBUG, "[0x%08x][%s][%s] - %s", (long)PAL_LoadBattleSprites, "PAL_LoadBattleSprites", __FILE__, "end"); }
VOID PAL_EquipItemMenu( WORD wItem ) /*++ Purpose: Show the menu which allow players to equip the specified item. Parameters: [IN] wItem - the object ID of the item. Return value: None. --*/ { PAL_LARGE BYTE bufBackground[320 * 200]; PAL_LARGE BYTE bufImage[2048]; WORD w; int iCurrentPlayer, i; BYTE bColor, bSelectedColor; DWORD dwColorChangeTime; gpGlobals->wLastUnequippedItem = wItem; PAL_MKFDecompressChunk(bufBackground, 320 * 200, EQUIPMENU_BACKGROUND_FBPNUM, gpGlobals->f.fpFBP); iCurrentPlayer = 0; bSelectedColor = MENUITEM_COLOR_SELECTED_FIRST; dwColorChangeTime = SDL_GetTicks() + (600 / MENUITEM_COLOR_SELECTED_TOTALNUM); while (TRUE) { wItem = gpGlobals->wLastUnequippedItem; // // Draw the background // PAL_FBPBlitToSurface(bufBackground, gpScreen); // // Draw the item picture // if (PAL_MKFReadChunk(bufImage, 2048, gpGlobals->g.rgObject[wItem].item.wBitmap, gpGlobals->f.fpBALL) > 0) { PAL_RLEBlitToSurface(bufImage, gpScreen, PAL_XY(16, 16)); } // // Draw the current equipment of the selected player // w = gpGlobals->rgParty[iCurrentPlayer].wPlayerRole; for (i = 0; i < MAX_PLAYER_EQUIPMENTS; i++) { if (gpGlobals->g.PlayerRoles.rgwEquipment[i][w] != 0) { PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwEquipment[i][w]), PAL_XY(130, 11 + i * 22), MENUITEM_COLOR, TRUE, FALSE); } } // // Draw the stats of the currently selected player // PAL_DrawNumber(PAL_GetPlayerAttackStrength(w), 4, PAL_XY(260, 14), kNumColorCyan, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerMagicStrength(w), 4, PAL_XY(260, 36), kNumColorCyan, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerDefense(w), 4, PAL_XY(260, 58), kNumColorCyan, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerDexterity(w), 4, PAL_XY(260, 80), kNumColorCyan, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerFleeRate(w), 4, PAL_XY(260, 102), kNumColorCyan, kNumAlignRight); // // Draw a box for player selection // PAL_CreateBox(PAL_XY(2, 95), gpGlobals->wMaxPartyMemberIndex, 2, 0, FALSE); // // Draw the label of players // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { w = gpGlobals->rgParty[i].wPlayerRole; if (iCurrentPlayer == i) { if (gpGlobals->g.rgObject[wItem].item.wFlags & (kItemFlagEquipableByPlayerRole_First << w)) { bColor = bSelectedColor; } else { bColor = MENUITEM_COLOR_SELECTED_INACTIVE; } } else { if (gpGlobals->g.rgObject[wItem].item.wFlags & (kItemFlagEquipableByPlayerRole_First << w)) { bColor = MENUITEM_COLOR; } else { bColor = MENUITEM_COLOR_INACTIVE; } } PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[w]), PAL_XY(15, 108 + 18 * i), bColor, TRUE, FALSE); } // // Draw the text label and amount of the item // if (wItem != 0) { PAL_DrawText(PAL_GetWord(wItem), PAL_XY(5, 70), MENUITEM_COLOR_CONFIRMED, TRUE, FALSE); PAL_DrawNumber(PAL_GetItemAmount(wItem), 2, PAL_XY(65, 73), kNumColorCyan, kNumAlignRight); } // // Update the screen // VIDEO_UpdateScreen(NULL); // // Accept input // PAL_ClearKeyState(); while (TRUE) { PAL_ProcessEvent(); // // See if we should change the highlight color // if (SDL_GetTicks() > dwColorChangeTime) { if ((WORD)bSelectedColor + 1 >= (WORD)MENUITEM_COLOR_SELECTED_FIRST + MENUITEM_COLOR_SELECTED_TOTALNUM) { bSelectedColor = MENUITEM_COLOR_SELECTED_FIRST; } else { bSelectedColor++; } dwColorChangeTime = SDL_GetTicks() + (600 / MENUITEM_COLOR_SELECTED_TOTALNUM); // // Redraw the selected item if needed. // w = gpGlobals->rgParty[iCurrentPlayer].wPlayerRole; if (gpGlobals->g.rgObject[wItem].item.wFlags & (kItemFlagEquipableByPlayerRole_First << w)) { PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[w]), PAL_XY(15, 108 + 18 * iCurrentPlayer), bSelectedColor, TRUE, TRUE); } } if (g_InputState.dwKeyPress != 0) { break; } SDL_Delay(1); } if (wItem == 0) { return; } if (g_InputState.dwKeyPress & (kKeyUp | kKeyLeft)) { iCurrentPlayer--; if (iCurrentPlayer < 0) { iCurrentPlayer = 0; } } else if (g_InputState.dwKeyPress & (kKeyDown | kKeyRight)) { iCurrentPlayer++; if (iCurrentPlayer > gpGlobals->wMaxPartyMemberIndex) { iCurrentPlayer = gpGlobals->wMaxPartyMemberIndex; } } else if (g_InputState.dwKeyPress & kKeyMenu) { return; } else if (g_InputState.dwKeyPress & kKeySearch) { w = gpGlobals->rgParty[iCurrentPlayer].wPlayerRole; if (gpGlobals->g.rgObject[wItem].item.wFlags & (kItemFlagEquipableByPlayerRole_First << w)) { // // Run the equip script // gpGlobals->g.rgObject[wItem].item.wScriptOnEquip = PAL_RunTriggerScript(gpGlobals->g.rgObject[wItem].item.wScriptOnEquip, gpGlobals->rgParty[iCurrentPlayer].wPlayerRole); } } } }
VOID PAL_PlayerStatus( VOID ) /*++ Purpose: Show the player status. Parameters: None. Return value: None. --*/ { PAL_LARGE BYTE bufBackground[320 * 200]; PAL_LARGE BYTE bufImage[16384]; int iCurrent; int iPlayerRole; int i, y; WORD w; const int rgEquipPos[MAX_PLAYER_EQUIPMENTS][2] = { {190, 0}, {248, 40}, {252, 102}, {202, 134}, {142, 142}, {82, 126} }; PAL_MKFDecompressChunk(bufBackground, 320 * 200, STATUS_BACKGROUND_FBPNUM, gpGlobals->f.fpFBP); iCurrent = 0; while (iCurrent >= 0 && iCurrent <= gpGlobals->wMaxPartyMemberIndex) { iPlayerRole = gpGlobals->rgParty[iCurrent].wPlayerRole; // // Draw the background image // PAL_FBPBlitToSurface(bufBackground, gpScreen); // // Draw the text labels // PAL_DrawText(PAL_GetWord(STATUS_LABEL_EXP), PAL_XY(6, 6), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_LEVEL), PAL_XY(6, 32), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_HP), PAL_XY(6, 54), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_MP), PAL_XY(6, 76), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_ATTACKPOWER), PAL_XY(6, 98), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_MAGICPOWER), PAL_XY(6, 118), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_RESISTANCE), PAL_XY(6, 138), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_DEXTERITY), PAL_XY(6, 158), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(STATUS_LABEL_FLEERATE), PAL_XY(6, 178), MENUITEM_COLOR, TRUE, FALSE); PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[iPlayerRole]), PAL_XY(110, 8), MENUITEM_COLOR_CONFIRMED, TRUE, FALSE); // // Draw the stats // PAL_DrawNumber(gpGlobals->Exp.rgPrimaryExp[iPlayerRole].wExp, 5, PAL_XY(58, 6), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.rgLevelUpExp[gpGlobals->g.PlayerRoles.rgwLevel[iPlayerRole]], 5, PAL_XY(58, 15), kNumColorCyan, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwLevel[iPlayerRole], 2, PAL_XY(54, 35), kNumColorYellow, kNumAlignRight); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(65, 58)); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen, PAL_XY(65, 80)); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwHP[iPlayerRole], 4, PAL_XY(42, 56), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxHP[iPlayerRole], 4, PAL_XY(63, 61), kNumColorBlue, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMP[iPlayerRole], 4, PAL_XY(42, 78), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxMP[iPlayerRole], 4, PAL_XY(63, 83), kNumColorBlue, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerAttackStrength(iPlayerRole), 4, PAL_XY(42, 102), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerMagicStrength(iPlayerRole), 4, PAL_XY(42, 122), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerDefense(iPlayerRole), 4, PAL_XY(42, 142), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerDexterity(iPlayerRole), 4, PAL_XY(42, 162), kNumColorYellow, kNumAlignRight); PAL_DrawNumber(PAL_GetPlayerFleeRate(iPlayerRole), 4, PAL_XY(42, 182), kNumColorYellow, kNumAlignRight); // // Draw the equipments // for (i = 0; i < MAX_PLAYER_EQUIPMENTS; i++) { w = gpGlobals->g.PlayerRoles.rgwEquipment[i][iPlayerRole]; if (w == 0) { continue; } // // Draw the image // if (PAL_MKFReadChunk(bufImage, 16384, gpGlobals->g.rgObject[w].item.wBitmap, gpGlobals->f.fpBALL) > 0) { PAL_RLEBlitToSurface(bufImage, gpScreen, PAL_XY(rgEquipPos[i][0], rgEquipPos[i][1])); } // // Draw the text label // PAL_DrawText(PAL_GetWord(w), PAL_XY(rgEquipPos[i][0] + 5, rgEquipPos[i][1] + 38), STATUS_COLOR_EQUIPMENT, TRUE, FALSE); } // // Draw the image of player role // if (PAL_MKFReadChunk(bufImage, 16384, gpGlobals->g.PlayerRoles.rgwAvatar[iPlayerRole], gpGlobals->f.fpRGM) > 0) { PAL_RLEBlitToSurface(bufImage, gpScreen, PAL_XY(110, 30)); } // // Draw all poisons // y = 58; for (i = 0; i < MAX_POISONS; i++) { w = gpGlobals->rgPoisonStatus[i][iCurrent].wPoisonID; if (w != 0 && gpGlobals->g.rgObject[w].poison.wPoisonLevel <= 3) { PAL_DrawText(PAL_GetWord(w), PAL_XY(185, y), (BYTE)(gpGlobals->g.rgObject[w].poison.wColor + 10), TRUE, FALSE); y += 18; } } // // Update the screen // VIDEO_UpdateScreen(NULL); // // Wait for input // PAL_ClearKeyState(); while (TRUE) { UTIL_Delay(1); if (g_InputState.dwKeyPress & kKeyMenu) { iCurrent = -1; break; } else if (g_InputState.dwKeyPress & (kKeyLeft | kKeyUp)) { iCurrent--; break; } else if (g_InputState.dwKeyPress & (kKeyRight | kKeyDown | kKeySearch)) { iCurrent++; break; } } } }