VOID PAL_MakeScene( VOID ) /*++ Purpose: Draw the scene of the current frame to the screen. Both the map and the sprites are handled here. Parameters: None. Return value: None. --*/ { static SDL_Rect rect = {0, 0, 320, 200}; // // Step 1: Draw the complete map, for both of the layers. // rect.x = PAL_X(gpGlobals->viewport); rect.y = PAL_Y(gpGlobals->viewport); PAL_MapBlitToSurface(PAL_GetCurrentMap(), gpScreen, &rect, 0); PAL_MapBlitToSurface(PAL_GetCurrentMap(), gpScreen, &rect, 1); // // Step 2: Apply screen waving effects. // PAL_ApplyWave(gpScreen); // // Step 3: Draw all the sprites. // PAL_SceneDrawSprites(); // // Check if we need to fade in. // if (gpGlobals->fNeedToFadeIn) { VIDEO_UpdateScreen(NULL); PAL_FadeIn(gpGlobals->wNumPalette, gpGlobals->fNightPalette, 1); gpGlobals->fNeedToFadeIn = FALSE; } }
/*++ Generate the battle scene into the scene buffer. --*/ VOID PAL_BattleMakeScene(void) { int i; PAL_POS pos; LPBYTE pSrc, pDst; BYTE b; // // Draw the background // pSrc = g_Battle.lpBackground->pixels; pDst = g_Battle.lpSceneBuf->pixels; for (i = 0; i < g_Battle.lpSceneBuf->pitch * g_Battle.lpSceneBuf->h; i++) { b = (*pSrc & 0x0F); b += g_Battle.sBackgroundColorShift; if (b & 0x80) { b = 0; } else if (b & 0x70) { b = 0x0F; } *pDst = (b | (*pSrc & 0xF0)); ++pSrc; ++pDst; } PAL_ApplyWave(g_Battle.lpSceneBuf); // // Draw the enemies // for (i = g_Battle.wMaxEnemyIndex; i >= 0; i--) { pos = g_Battle.rgEnemy[i].pos; if (g_Battle.rgEnemy[i].rgwStatus[kStatusConfused] > 0 && g_Battle.rgEnemy[i].rgwStatus[kStatusSleep] == 0 && g_Battle.rgEnemy[i].rgwStatus[kStatusParalyzed] == 0) { // // Enemy is confused // pos = PAL_XY(PAL_X(pos) + RandomLong(-1, 1), PAL_Y(pos)); } pos = PAL_XY(PAL_X(pos) - PAL_RLEGetWidth(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame)) / 2, PAL_Y(pos) - PAL_RLEGetHeight(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame))); if (g_Battle.rgEnemy[i].wObjectID != 0) { if (g_Battle.rgEnemy[i].iColorShift) { PAL_RLEBlitWithColorShift(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame), g_Battle.lpSceneBuf, pos, g_Battle.rgEnemy[i].iColorShift); } else { PAL_RLEBlitToSurface(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame), g_Battle.lpSceneBuf, pos); } } } if (g_Battle.lpSummonSprite != NULL) { // // Draw the summoned god // pos = PAL_XY(PAL_X(g_Battle.posSummon) - PAL_RLEGetWidth(PAL_SpriteGetFrame(g_Battle.lpSummonSprite, g_Battle.iSummonFrame)) / 2, PAL_Y(g_Battle.posSummon) - PAL_RLEGetHeight(PAL_SpriteGetFrame(g_Battle.lpSummonSprite, g_Battle.iSummonFrame))); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(g_Battle.lpSummonSprite, g_Battle.iSummonFrame), g_Battle.lpSceneBuf, pos); } else { // // Draw the players // for (i = gpGlobals->wMaxPartyMemberIndex; i >= 0; i--) { pos = g_Battle.rgPlayer[i].pos; if (gpGlobals->rgPlayerStatus[gpGlobals->rgParty[i].wPlayerRole][kStatusConfused] != 0 && gpGlobals->rgPlayerStatus[gpGlobals->rgParty[i].wPlayerRole][kStatusSleep] == 0 && gpGlobals->rgPlayerStatus[gpGlobals->rgParty[i].wPlayerRole][kStatusParalyzed] == 0 && gpGlobals->g.PlayerRoles.rgwHP[gpGlobals->rgParty[i].wPlayerRole] > 0) { // // Player is confused // continue; } pos = PAL_XY(PAL_X(pos) - PAL_RLEGetWidth(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame)) / 2, PAL_Y(pos) - PAL_RLEGetHeight(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame))); if (g_Battle.rgPlayer[i].iColorShift != 0) { PAL_RLEBlitWithColorShift(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame), g_Battle.lpSceneBuf, pos, g_Battle.rgPlayer[i].iColorShift); } else if (g_Battle.iHidingTime == 0) { PAL_RLEBlitToSurface(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame), g_Battle.lpSceneBuf, pos); } } // // Confused players should be drawn on top of normal players // for (i = gpGlobals->wMaxPartyMemberIndex; i >= 0; i--) { if (gpGlobals->rgPlayerStatus[gpGlobals->rgParty[i].wPlayerRole][kStatusConfused] != 0 && gpGlobals->rgPlayerStatus[gpGlobals->rgParty[i].wPlayerRole][kStatusSleep] == 0 && gpGlobals->rgPlayerStatus[gpGlobals->rgParty[i].wPlayerRole][kStatusParalyzed] == 0 && gpGlobals->g.PlayerRoles.rgwHP[gpGlobals->rgParty[i].wPlayerRole] > 0) { // // Player is confused // pos = PAL_XY(PAL_X(g_Battle.rgPlayer[i].pos), PAL_Y(g_Battle.rgPlayer[i].pos) + RandomLong(-1, 1)); pos = PAL_XY(PAL_X(pos) - PAL_RLEGetWidth(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame)) / 2, PAL_Y(pos) - PAL_RLEGetHeight(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame))); if (g_Battle.rgPlayer[i].iColorShift != 0) { PAL_RLEBlitWithColorShift(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame), g_Battle.lpSceneBuf, pos, g_Battle.rgPlayer[i].iColorShift); } else if (g_Battle.iHidingTime == 0) { PAL_RLEBlitToSurface(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame), g_Battle.lpSceneBuf, pos); } } } } }
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_BattleMakeScene( VOID ) /*++ Purpose: Generate the battle scene into the scene buffer. Parameters: None. Return value: None. --*/ { int i; PAL_POS pos; LPBYTE pSrc, pDst; //BYTE b; // // Draw the background // pSrc = g_Battle.lpBackground->pixels; pDst = g_Battle.lpSceneBuf->pixels; // optimized by ZBY ZBY_TIMING_BEGIN(2); make_colorshift_table(g_Battle.sBackgroundColorShift); if (0) { //if (g_Battle.sBackgroundColorShift == 0) { memcpy(pDst, pSrc, g_Battle.lpSceneBuf->pitch * g_Battle.lpSceneBuf->h); } else { i = g_Battle.lpSceneBuf->pitch * g_Battle.lpSceneBuf->h; while (i--) { /*b = (*pSrc & 0x0F); b += g_Battle.sBackgroundColorShift; if (b & 0x80) { b = 0; } else if (b & 0x70) { b = 0x0F; } *pDst = (b | (*pSrc & 0xF0)); assert(*pDst == cs_table[*pSrc]); */ *pDst = cs_table[*pSrc]; ++pSrc; ++pDst; } } ZBY_TIMING_END(2, "PAL_BattleMakeScene"); PAL_ApplyWave(g_Battle.lpSceneBuf); // // Draw the enemies // for (i = g_Battle.wMaxEnemyIndex; i >= 0; i--) { pos = g_Battle.rgEnemy[i].pos; if (g_Battle.rgEnemy[i].rgwStatus[kStatusConfused] > 0 && g_Battle.rgEnemy[i].rgwStatus[kStatusSleep] == 0 && g_Battle.rgEnemy[i].rgwStatus[kStatusParalyzed] == 0) { // // Enemy is confused // pos = PAL_XY(PAL_X(pos) + RandomLong(-1, 1), PAL_Y(pos)); } pos = PAL_XY(PAL_X(pos) - PAL_RLEGetWidth(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame)) / 2, PAL_Y(pos) - PAL_RLEGetHeight(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame))); if (g_Battle.rgEnemy[i].wObjectID != 0) { if (g_Battle.rgEnemy[i].iColorShift) { PAL_RLEBlitWithColorShift(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame), g_Battle.lpSceneBuf, pos, g_Battle.rgEnemy[i].iColorShift); } else { PAL_RLEBlitToSurface(PAL_SpriteGetFrame(g_Battle.rgEnemy[i].lpSprite, g_Battle.rgEnemy[i].wCurrentFrame), g_Battle.lpSceneBuf, pos); } } } if (g_Battle.lpSummonSprite != NULL) { // // Draw the summoned god // pos = PAL_XY(PAL_X(g_Battle.posSummon) - PAL_RLEGetWidth(PAL_SpriteGetFrame(g_Battle.lpSummonSprite, g_Battle.iSummonFrame)) / 2, PAL_Y(g_Battle.posSummon) - PAL_RLEGetHeight(PAL_SpriteGetFrame(g_Battle.lpSummonSprite, g_Battle.iSummonFrame))); PAL_RLEBlitToSurface(PAL_SpriteGetFrame(g_Battle.lpSummonSprite, g_Battle.iSummonFrame), g_Battle.lpSceneBuf, pos); } else { // // Draw the players // for (i = gpGlobals->wMaxPartyMemberIndex; i >= 0; i--) { pos = g_Battle.rgPlayer[i].pos; if (gpGlobals->rgPlayerStatus[gpGlobals->rgParty[i].wPlayerRole][kStatusConfused] != 0 && gpGlobals->rgPlayerStatus[gpGlobals->rgParty[i].wPlayerRole][kStatusSleep] == 0 && gpGlobals->rgPlayerStatus[gpGlobals->rgParty[i].wPlayerRole][kStatusParalyzed] == 0 && gpGlobals->g.PlayerRoles.rgwHP[gpGlobals->rgParty[i].wPlayerRole] > 0) { // // Player is confused // continue; } pos = PAL_XY(PAL_X(pos) - PAL_RLEGetWidth(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame)) / 2, PAL_Y(pos) - PAL_RLEGetHeight(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame))); if (g_Battle.rgPlayer[i].iColorShift != 0) { PAL_RLEBlitWithColorShift(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame), g_Battle.lpSceneBuf, pos, g_Battle.rgPlayer[i].iColorShift); } else if (g_Battle.iHidingTime == 0) { PAL_RLEBlitToSurface(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame), g_Battle.lpSceneBuf, pos); } } // // Confused players should be drawn on top of normal players // for (i = gpGlobals->wMaxPartyMemberIndex; i >= 0; i--) { if (gpGlobals->rgPlayerStatus[gpGlobals->rgParty[i].wPlayerRole][kStatusConfused] != 0 && gpGlobals->rgPlayerStatus[gpGlobals->rgParty[i].wPlayerRole][kStatusSleep] == 0 && gpGlobals->rgPlayerStatus[gpGlobals->rgParty[i].wPlayerRole][kStatusParalyzed] == 0 && gpGlobals->g.PlayerRoles.rgwHP[gpGlobals->rgParty[i].wPlayerRole] > 0) { // // Player is confused // pos = PAL_XY(PAL_X(g_Battle.rgPlayer[i].pos), PAL_Y(g_Battle.rgPlayer[i].pos) + RandomLong(-1, 1)); pos = PAL_XY(PAL_X(pos) - PAL_RLEGetWidth(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame)) / 2, PAL_Y(pos) - PAL_RLEGetHeight(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame))); if (g_Battle.rgPlayer[i].iColorShift != 0) { PAL_RLEBlitWithColorShift(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame), g_Battle.lpSceneBuf, pos, g_Battle.rgPlayer[i].iColorShift); } else if (g_Battle.iHidingTime == 0) { PAL_RLEBlitToSurface(PAL_SpriteGetFrame(g_Battle.rgPlayer[i].lpSprite, g_Battle.rgPlayer[i].wCurrentFrame), g_Battle.lpSceneBuf, pos); } } } } }