VOID PAL_InitInput( VOID ) /*++ Purpose: Initialize the input subsystem. Parameters: None. Return value: None. --*/ { memset(&g_InputState, 0, sizeof(g_InputState)); g_InputState.dir = kDirUnknown; g_InputState.prevdir = kDirUnknown; #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION <= 2 SDL_SetEventFilter(PAL_EventFilter); #else SDL_SetEventFilter(PAL_EventFilter, NULL); #endif // // Setup input // sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); pad.Buttons = 0; // // Start thread to read data // if((pad_sem = SDL_CreateSemaphore(1)) == NULL) { TerminateOnError("Can't create input semaphore\n"); return; } running = 1; if((bthread = SDL_CreateThread(PSP_JoystickUpdate, NULL)) == NULL) { TerminateOnError("Can't create input thread\n"); return; } }
FILE * UTIL_OpenRequiredFile( LPCSTR lpszFileName ) /*++ Purpose: Open a required file. If fails, quit the program. Parameters: [IN] lpszFileName - file name to open. Return value: Pointer to the file. --*/ { FILE *fp; fp = fopen(va("%s%s", PAL_PREFIX, lpszFileName), "rb"); if (fp == NULL) { TerminateOnError("File not found: %s!\n", lpszFileName); } return fp; }
/*++ 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); }
SDL_Surface *CGeneral::LoadImgFile(const char *filename) { SDL_Surface *pic = IMG_Load(filename); if (pic == NULL) { TerminateOnError("Cannot load Image file %s: %s", filename, SDL_GetError()); } return pic; }
SDL_Surface *CGeneral::LoadBitmapFile(const char *filename) { SDL_Surface *pic = SDL_LoadBMP(filename); if (pic == NULL) { TerminateOnError("Cannot load Bitmap file %s: %s", filename, SDL_GetError()); } return pic; }
void CGame::AddPlayer(CBasePlayer *p, int iScore, const char *szName) { if (m_iNumPlayer >= 3) { TerminateOnError("CGame::AddPlayer(): m_iNumPlayer >= 3!"); } m_rgpPlayers[m_iNumPlayer] = p; m_rgiPlayerScore[m_iNumPlayer] = iScore; strncpy(m_rgszPlayerNames[m_iNumPlayer], szName, 20); m_rgszPlayerNames[m_iNumPlayer][19] = '\0'; m_iNumPlayer++; }
TTF_Font *CGeneral::LoadFontFile(const char *filename, int size) { TTF_Font *f = TTF_OpenFont(filename, size); if (f == NULL) { TerminateOnError("Cannot load font file %s (%dpt): %s", filename, size, SDL_GetError()); } return f; }
void * UTIL_malloc( size_t buffer_size ) { // handy wrapper for operations we always forget, like checking malloc's returned pointer. void *buffer; // first off, check if buffer size is valid if (buffer_size == 0) TerminateOnError("UTIL_malloc() called with invalid buffer size: %d\n", buffer_size); buffer = malloc(buffer_size); // allocate real memory space // last check, check if malloc call succeeded if (buffer == NULL) TerminateOnError("UTIL_malloc() failure for %d bytes (out of memory?)\n", buffer_size); return buffer; // nothing went wrong, so return buffer pointer }
void CHand::AddRandomTile(int flag) { if (m_iNumTiles >= MAX_HANDTILE) { TerminateOnError("CHand::GetRandomTile(): Max tile reached"); } m_Tiles[m_iNumTiles].tile = CTile::RandomTile(); m_Tiles[m_iNumTiles].flags = flag; m_Tiles[m_iNumTiles].tileset = -1; m_iNumTiles++; }
void CHand::AddTile(const CTile &t, int flag, int tileset) { if (m_iNumTiles >= MAX_HANDTILE) { TerminateOnError("CHand::GetRandomTile(): Max tile reached"); } m_Tiles[m_iNumTiles].tile = t; m_Tiles[m_iNumTiles].flags = flag; m_Tiles[m_iNumTiles].tileset = tileset; m_iNumTiles++; }
FILE * UTIL_OpenRequiredFile( LPCSTR lpszFileName ) /*++ Purpose: Open a required file. If fails, quit the program. Parameters: [IN] lpszFileName - file name to open. Return value: Pointer to the file. --*/ { FILE *fp; fp = fopen(va("%s%s", PAL_PREFIX, lpszFileName), "rb"); #ifndef _WIN32 if (fp == NULL) { // // try converting the filename to upper-case. // char *pBuf = strdup(lpszFileName); char *p = pBuf; while (*p) { if (*p >= 'a' && *p <= 'z') { *p -= 'a' - 'A'; } p++; } fp = fopen(va("%s%s", PAL_PREFIX, pBuf), "rb"); free(pBuf); } #endif if (fp == NULL) { TerminateOnError("File not found: %s!\n", lpszFileName); } return fp; }
CButton::CButton(int id, int x, int y, int w, int h, int r, int g, int b): CBox(x, y, w, h, r, g, b, 128, false), m_iId(id) { if (num_buttons >= MAX_BUTTONS) { TerminateOnError("CButton::CButton(): num_buttons > MAX_BUTTONS!"); } bid[num_buttons] = id; bx[num_buttons] = x; by[num_buttons] = y; bw[num_buttons] = w; bh[num_buttons] = h; num_buttons++; }
Mix_Chunk *CGeneral::LoadSoundFile(const char *filename) { if (g_fNoSound) { return NULL; } Mix_Chunk *s = Mix_LoadWAV(filename); if (s == NULL) { TerminateOnError("Cannot load sound file %s: %s", filename, SDL_GetError()); } return s; }
Mix_Music *CGeneral::LoadMusicFile(const char *filename) { if (g_fNoMusic) { return NULL; } Mix_Music *m = Mix_LoadMUS(filename); if (m == NULL) { TerminateOnError("Cannot load music file %s: %s", filename, SDL_GetError()); } return m; }
void CGeneral::DrawBGFade(int girlnum, int color, int duration) { if (girlnum < 0 || girlnum > 4 || color < 0 || color > 2) { TerminateOnError("CGeneral::DrawBGFade(): invalid parameter"); } SDL_Surface *bg = ((girlnum >= 4) ? m_imgElectron : m_imgGirls[girlnum][color]); assert(bg != NULL); // display the image ScreenFade(duration, bg); m_iPrevGirl = girlnum; m_iPrevGirlColor = color; }
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 CGeneral::DrawBG(int girlnum, int color) { if (girlnum < 0 || girlnum > 4 || color < 0 || color > 2) { TerminateOnError("CGeneral::DrawBG(): invalid parameter"); } SDL_Surface *bg = ((girlnum >= 4) ? m_imgElectron : m_imgGirls[girlnum][color]); assert(bg != NULL); // display the image SDL_BlitSurface(bg, NULL, gpScreen, NULL); m_iPrevGirl = girlnum; m_iPrevGirlColor = color; }
void CGeneral::DrawGirl(int x, int y, int w, int h, int girlnum, int color) { if (girlnum < 0 || girlnum > 3) { TerminateOnError("CGeneral::DrawGirl(): invalid parameter"); } SDL_Rect dstrect, dstrect2; dstrect.x = dstrect.y = 0; dstrect.w = 640; dstrect.h = 480; dstrect2.x = x; dstrect2.y = y; dstrect2.w = w; dstrect2.h = h; SDL_Surface *bg = m_imgGirls[girlnum][color]; assert(bg != NULL); UTIL_ScaleBlit(bg, &dstrect, gpScreen, &dstrect2); }
void CUIManager::DrawPlayer(int location, const CCard handcard[20], int count_hc, const CCard disc[20], int count_d) { switch (location) { case PLAYER_LOCAL: m_Time = -1; DrawPlayerLocal(handcard, count_hc, disc, count_d); break; case PLAYER_LEFT: DrawPlayerLeft(handcard, count_hc, disc, count_d); break; case PLAYER_RIGHT: DrawPlayerRight(handcard, count_hc, disc, count_d); break; default: TerminateOnError("CUIManager::DrawPlayer(): Unknown location %d", location); break; } }
CButton::~CButton() { int i; for (i = 0; i < num_buttons; i++) { if (bid[i] == m_iId) { break; } } if (i >= num_buttons) { TerminateOnError("CButton::~CButton(): i >= num_buttons"); } while (i < num_buttons - 1) { bid[i] = bid[i + 1]; bx[i] = bx[i + 1]; by[i] = by[i + 1]; bw[i] = bw[i + 1]; bh[i] = bh[i + 1]; i++; } num_buttons--; }
bool CHand::CanChow(const CTile &t, int location) { CTile to_find[2]; if (t.GetSuit() & (TILESUIT_WIND | TILESUIT_DRAGON)) return false; // cannot chow wind or dragon tiles switch (location) { case CHOW_LOWER: if (t.GetValue() > 7) return false; to_find[0] = t() + 1; to_find[1] = t() + 2; break; case CHOW_MIDDLE: if (t.GetValue() == 1 || t.GetValue() == 9) return false; to_find[0] = t() - 1; to_find[1] = t() + 1; break; case CHOW_UPPER: if (t.GetValue() < 3) return false; to_find[0] = t() - 1; to_find[1] = t() - 2; break; default: TerminateOnError("CHand::Chow(): Invalid location"); return false; } return (HasTile(to_find[0]) && HasTile(to_find[1])); }
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; }
void CBot::InvalidDiscard() { // THIS SHOULD NOT HAPPEN !!! SOMETHING MUST HAVE BEEN MESSED UP. TerminateOnError("CBot::InvalidDiscard()"); }
void CGame::Run() { int i, j; // the game must be played with 3 players if (m_iNumPlayer != 3) { TerminateOnError("CGame::Run(): m_iNumPlayer != 3!"); } for (i = 0; i < 3; i++) { char player_names[3][20]; strncpy(player_names[RL(0, i)], m_rgszPlayerNames[0], 20); strncpy(player_names[RL(1, i)], m_rgszPlayerNames[1], 20); strncpy(player_names[RL(2, i)], m_rgszPlayerNames[2], 20); player_names[0][19] = '\0'; player_names[1][19] = '\0'; player_names[2][19] = '\0'; m_rgpPlayers[i]->SetPlayerNames(player_names); } // The main game loop while (1) { int iWinner = PlayRound(), scores[3]; bool fLordWon = (iWinner == m_iCurLord); CCard rgRemainCards[3][20]; for (i = 0; i < 3; i++) { for (j = 0; j < 20; j++) { rgRemainCards[i][j] = m_rgpPlayers[i]->Hand()[j]; } } scores[0] = m_iPoints * ((fLordWon ^ (m_iCurLord != 0)) ? 1 : -1); scores[1] = m_iPoints * ((fLordWon ^ (m_iCurLord != 1)) ? 1 : -1); scores[2] = m_iPoints * ((fLordWon ^ (m_iCurLord != 2)) ? 1 : -1); scores[m_iCurLord] *= 2; if (atoi(cfg.Get("GAME", "ShowCards", "1"))) { m_rgpPlayers[0]->ShowAllCards(RL(iWinner, 0), rgRemainCards); m_rgpPlayers[1]->ShowAllCards(RL(iWinner, 1), rgRemainCards); m_rgpPlayers[2]->ShowAllCards(RL(iWinner, 2), rgRemainCards); } m_rgiPlayerScore[0] += scores[0]; m_rgiPlayerScore[1] += scores[1]; m_rgiPlayerScore[2] += scores[2]; if (m_fSingleGame) { cfg.Set("GAME", "Score", va("%d", m_rgiPlayerScore[0])); cfg.Set("GAME", "BotScore1", va("%d", m_rgiPlayerScore[1])); cfg.Set("GAME", "BotScore2", va("%d", m_rgiPlayerScore[2])); } // send score information to players m_rgpPlayers[0]->ScoreBoard(m_rgszPlayerNames, scores, m_rgiPlayerScore, scores[0] > 0); m_rgpPlayers[1]->ScoreBoard(m_rgszPlayerNames, scores, m_rgiPlayerScore, scores[1] > 0); m_rgpPlayers[2]->ScoreBoard(m_rgszPlayerNames, scores, m_rgiPlayerScore, scores[2] > 0); // Wait for all players to get ready for next round time_t t; time(&t); while (1) { UTIL_Delay(10); if (m_rgpPlayers[0]->IsReady() && m_rgpPlayers[1]->IsReady() && m_rgpPlayers[2]->IsReady()) { break; } if (time(NULL) - t > 30 && !m_fSingleGame) { g_UI.PopMessage(msg("someone_quit")); return; // someone delayed for too long; close the server } } } }
/*++ Start a battle. Parameters: [IN] wEnemyTeam - the number of the enemy team. [IN] fIsBoss - TRUE for boss fight (not allowed to flee). Return value: The result of the battle. --*/ BATTLERESULT PAL_StartBattle(WORD wEnemyTeam, BOOL fIsBoss) { int i; WORD w, wPrevWaveLevel; SHORT sPrevWaveProgression; // // Set the screen waving effects // wPrevWaveLevel = gpGlobals->wScreenWave; sPrevWaveProgression = gpGlobals->sWaveProgression; gpGlobals->sWaveProgression = 0; gpGlobals->wScreenWave = gpGlobals->g.lprgBattleField[gpGlobals->wNumBattleField].wScreenWave; // // Make sure everyone in the party is alive, also clear all hidden // EXP count records // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { w = gpGlobals->rgParty[i].wPlayerRole; if (gpGlobals->g.PlayerRoles.rgwHP[w] == 0) { gpGlobals->g.PlayerRoles.rgwHP[w] = 1; gpGlobals->rgPlayerStatus[w][kStatusPuppet] = 0; } gpGlobals->Exp.rgHealthExp[w].wCount = 0; gpGlobals->Exp.rgMagicExp[w].wCount = 0; gpGlobals->Exp.rgAttackExp[w].wCount = 0; gpGlobals->Exp.rgMagicPowerExp[w].wCount = 0; gpGlobals->Exp.rgDefenseExp[w].wCount = 0; gpGlobals->Exp.rgDexterityExp[w].wCount = 0; gpGlobals->Exp.rgFleeExp[w].wCount = 0; } // // Clear all item-using records // for (i = 0; i < MAX_INVENTORY; i++) { gpGlobals->rgInventory[i].nAmountInUse = 0; } // // Store all enemies // for (i = 0; i < MAX_ENEMIES_IN_TEAM; i++) { memset(&(g_Battle.rgEnemy[i]), 0, sizeof(BATTLEENEMY)); w = gpGlobals->g.lprgEnemyTeam[wEnemyTeam].rgwEnemy[i]; if (w == 0xFFFF) { break; } if (w != 0) { g_Battle.rgEnemy[i].e = gpGlobals->g.lprgEnemy[gpGlobals->g.rgObject[w].enemy.wEnemyID]; g_Battle.rgEnemy[i].wObjectID = w; g_Battle.rgEnemy[i].state = kFighterWait; g_Battle.rgEnemy[i].wScriptOnTurnStart = gpGlobals->g.rgObject[w].enemy.wScriptOnTurnStart; g_Battle.rgEnemy[i].wScriptOnBattleEnd = gpGlobals->g.rgObject[w].enemy.wScriptOnBattleEnd; g_Battle.rgEnemy[i].wScriptOnReady = gpGlobals->g.rgObject[w].enemy.wScriptOnReady; g_Battle.rgEnemy[i].iColorShift = 0; g_Battle.rgEnemy[i].dwMaxHealth = g_Battle.rgEnemy[i].e.wHealth; #ifndef PAL_CLASSIC g_Battle.rgEnemy[i].flTimeMeter = 50; // // HACK: Otherwise the black thief lady will be too hard to beat // if (g_Battle.rgEnemy[i].e.wDexterity == 164) { g_Battle.rgEnemy[i].e.wDexterity /= ((gpGlobals->wMaxPartyMemberIndex == 0) ? 6 : 3); } // // HACK: Heal up automatically for final boss // if (g_Battle.rgEnemy[i].e.wHealth == 32760) { for (w = 0; w < MAX_PLAYER_ROLES; w++) { gpGlobals->g.PlayerRoles.rgwHP[w] = gpGlobals->g.PlayerRoles.rgwMaxHP[w]; gpGlobals->g.PlayerRoles.rgwMP[w] = gpGlobals->g.PlayerRoles.rgwMaxMP[w]; } } // // Yet another HACKs // if ((SHORT)g_Battle.rgEnemy[i].e.wDexterity == -32) { g_Battle.rgEnemy[i].e.wDexterity = 0; // for Grandma Knife } else if (g_Battle.rgEnemy[i].e.wDexterity == 20) { // // for Fox Demon // if (gpGlobals->g.PlayerRoles.rgwLevel[0] < 15) { g_Battle.rgEnemy[i].e.wDexterity = 8; } else if (gpGlobals->g.PlayerRoles.rgwLevel[4] > 28 || gpGlobals->Exp.rgPrimaryExp[4].wExp > 0) { g_Battle.rgEnemy[i].e.wDexterity = 60; } } else if (g_Battle.rgEnemy[i].e.wExp == 250 && g_Battle.rgEnemy[i].e.wCash == 1100) { g_Battle.rgEnemy[i].e.wDexterity += 12; // for Snake Demon } else if ((SHORT)g_Battle.rgEnemy[i].e.wDexterity == -60) { g_Battle.rgEnemy[i].e.wDexterity = 15; // for Spider } else if ((SHORT)g_Battle.rgEnemy[i].e.wDexterity == -30) { g_Battle.rgEnemy[i].e.wDexterity = (WORD)-10; // for Stone Head } else if ((SHORT)g_Battle.rgEnemy[i].e.wDexterity == -16) { g_Battle.rgEnemy[i].e.wDexterity = 0; // for Zombie } else if ((SHORT)g_Battle.rgEnemy[i].e.wDexterity == -20) { g_Battle.rgEnemy[i].e.wDexterity = -8; // for Flower Demon } else if (g_Battle.rgEnemy[i].e.wLevel < 20 && gpGlobals->wNumScene >= 0xD8 && gpGlobals->wNumScene <= 0xE2) { // // for low-level monsters in the Cave of Trial // g_Battle.rgEnemy[i].e.wLevel += 15; g_Battle.rgEnemy[i].e.wDexterity += 25; } else if (gpGlobals->wNumScene == 0x90) { g_Battle.rgEnemy[i].e.wDexterity += 25; // for Tower Dragons } else if (g_Battle.rgEnemy[i].e.wLevel == 2 && g_Battle.rgEnemy[i].e.wCash == 48) { g_Battle.rgEnemy[i].e.wDexterity += 8; // for Miao Fists } else if (g_Battle.rgEnemy[i].e.wLevel == 4 && g_Battle.rgEnemy[i].e.wCash == 240) { g_Battle.rgEnemy[i].e.wDexterity += 18; // for Fat Miao } else if (g_Battle.rgEnemy[i].e.wLevel == 16 && g_Battle.rgEnemy[i].e.wMagicRate == 4 && g_Battle.rgEnemy[i].e.wAttackEquivItemRate == 4) { g_Battle.rgEnemy[i].e.wDexterity += 50; // for Black Spider } #endif } } g_Battle.wMaxEnemyIndex = i - 1; // // Store all players // for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++) { g_Battle.rgPlayer[i].flTimeMeter = 15.0f; #ifndef PAL_CLASSIC g_Battle.rgPlayer[i].flTimeSpeedModifier = 2.0f; g_Battle.rgPlayer[i].sTurnOrder = -1; #endif g_Battle.rgPlayer[i].wHidingTime = 0; g_Battle.rgPlayer[i].state = kFighterWait; g_Battle.rgPlayer[i].action.sTarget = -1; g_Battle.rgPlayer[i].fDefending = FALSE; g_Battle.rgPlayer[i].wCurrentFrame = 0; g_Battle.rgPlayer[i].iColorShift = FALSE; } // // Load sprites and background // PAL_LoadBattleSprites(); PAL_LoadBattleBackground(); // // Create the surface for scene buffer // g_Battle.lpSceneBuf = SDL_CreateRGBSurface(gpScreen->flags & ~SDL_HWSURFACE, 320, 200, 8, gpScreen->format->Rmask, gpScreen->format->Gmask, gpScreen->format->Bmask, gpScreen->format->Amask); if (g_Battle.lpSceneBuf == NULL) { TerminateOnError("PAL_StartBattle(): creating surface for scene buffer failed!"); } #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetSurfacePalette(g_Battle.lpSceneBuf, gpScreen->format->palette); #else SDL_SetPalette(g_Battle.lpSceneBuf, SDL_PHYSPAL | SDL_LOGPAL, VIDEO_GetPalette(), 0, 256); #endif PAL_UpdateEquipments(); g_Battle.iExpGained = 0; g_Battle.iCashGained = 0; g_Battle.fIsBoss = fIsBoss; g_Battle.fEnemyCleared = FALSE; g_Battle.fEnemyMoving = FALSE; g_Battle.iHidingTime = 0; g_Battle.wMovingPlayerIndex = 0; g_Battle.UI.szMsg[0] = '\0'; g_Battle.UI.szNextMsg[0] = '\0'; g_Battle.UI.dwMsgShowTime = 0; g_Battle.UI.state = kBattleUIWait; g_Battle.UI.fAutoAttack = FALSE; g_Battle.UI.wSelectedIndex = 0; g_Battle.UI.wPrevEnemyTarget = 0; memset(g_Battle.UI.rgShowNum, 0, sizeof(g_Battle.UI.rgShowNum)); g_Battle.lpSummonSprite = NULL; g_Battle.sBackgroundColorShift = 0; gpGlobals->fInBattle = TRUE; g_Battle.BattleResult = kBattleResultPreBattle; PAL_BattleUpdateFighters(); // // Load the battle effect sprite. // i = PAL_MKFGetChunkSize(10, gpGlobals->f.fpDATA); g_Battle.lpEffectSprite = UTIL_malloc(i); PAL_MKFReadChunk(g_Battle.lpEffectSprite, i, 10, gpGlobals->f.fpDATA); #ifdef PAL_CLASSIC g_Battle.Phase = kBattlePhaseSelectAction; g_Battle.fRepeat = FALSE; g_Battle.fForce = FALSE; g_Battle.fFlee = FALSE; #endif #ifdef PAL_ALLOW_KEYREPEAT SDL_EnableKeyRepeat(120, 75); #endif // // Run the main battle routine. // i = PAL_BattleMain(); #ifdef PAL_ALLOW_KEYREPEAT SDL_EnableKeyRepeat(0, 0); PAL_ClearKeyState(); g_InputState.prevdir = kDirUnknown; #endif if (i == kBattleResultWon) { // // Player won the battle. Add the Experience points. // PAL_BattleWon(); } // // Clear all item-using records // for (w = 0; w < MAX_INVENTORY; w++) { gpGlobals->rgInventory[w].nAmountInUse = 0; } // // Clear all player status, poisons and temporary effects // PAL_ClearAllPlayerStatus(); for (w = 0; w < MAX_PLAYER_ROLES; w++) { PAL_CurePoisonByLevel(w, 3); PAL_RemoveEquipmentEffect(w, kBodyPartExtra); } // // Free all the battle sprites // PAL_FreeBattleSprites(); free(g_Battle.lpEffectSprite); // // Free the surfaces for the background picture and scene buffer // SDL_FreeSurface(g_Battle.lpBackground); SDL_FreeSurface(g_Battle.lpSceneBuf); g_Battle.lpBackground = NULL; g_Battle.lpSceneBuf = NULL; gpGlobals->fInBattle = FALSE; PAL_PlayMUS(gpGlobals->wNumMusic, TRUE, 1); // // Restore the screen waving effects // gpGlobals->sWaveProgression = sPrevWaveProgression; gpGlobals->wScreenWave = wPrevWaveLevel; return i; }
bool CHand::Chow(const CTile &t, int location, bool open, int flags) { handtile_t *p[3] = {NULL, NULL, NULL}; CTile to_find[2]; if (t.GetSuit() & (TILESUIT_WIND | TILESUIT_DRAGON)) return false; // cannot chow wind or dragon tiles int i, j, found = 0; switch (location) { case CHOW_LOWER: if (t.GetValue() > 7) return false; to_find[0] = t() + 1; to_find[1] = t() + 2; break; case CHOW_MIDDLE: if (t.GetValue() == 1 || t.GetValue() == 9) return false; to_find[0] = t() - 1; to_find[1] = t() + 1; break; case CHOW_UPPER: if (t.GetValue() < 3) return false; to_find[0] = t() - 1; to_find[1] = t() - 2; break; default: TerminateOnError("CHand::Chow(): Invalid location"); return false; } for (i = 0; i < m_iNumTiles; i++) { if (m_Tiles[i].flags & (HT_LOCKED | HT_TOCHOW)) continue; // skip open or closed kong tiles for (j = 0; j < 2; j++) { if (m_Tiles[i].tile == to_find[j]) { if (found < 2) p[found++] = &m_Tiles[i]; to_find[j] = 0; // already found this one } } if (!open && m_Tiles[i].tile == t) { p[2] = &m_Tiles[i]; } } if (found < 2 || (!open && p[2] == NULL)) return false; // cannot chow with this tile // Add this tile into the hand if (open) { m_Tiles[m_iNumTiles].tile = t; m_Tiles[m_iNumTiles].tileset = m_iNumTileSets; m_Tiles[m_iNumTiles].flags = (HT_OPENCHOW | HT_FROMOPPONENT | flags); m_iNumTiles++; } // mark the tiles as open pungs p[0]->flags |= ((open ? HT_OPENCHOW : HT_CLOSEDCHOW) | flags); p[1]->flags |= ((open ? HT_OPENCHOW : HT_CLOSEDCHOW) | flags); p[0]->tileset = p[1]->tileset = m_iNumTileSets; if (!open) { p[2]->flags |= (HT_CLOSEDCHOW | flags); p[2]->tileset = m_iNumTileSets; } // Add a tileset switch (location) { case CHOW_LOWER: m_TileSets[m_iNumTileSets].first = t; break; case CHOW_MIDDLE: m_TileSets[m_iNumTileSets].first = t() - 1; break; case CHOW_UPPER: m_TileSets[m_iNumTileSets].first = t() - 2; break; } m_TileSets[m_iNumTileSets].type = ((open ? HT_OPENCHOW : HT_CLOSEDCHOW) | flags); m_iNumTileSets++; return true; }
void CGeneral::ScreenFade(int duration, SDL_Surface *s) { SDL_Surface *pNewFadeSurface = SDL_CreateRGBSurface(gpScreen->flags & (~SDL_HWSURFACE), gpScreen->w, gpScreen->h, gpScreen->format->BitsPerPixel, gpScreen->format->Rmask, gpScreen->format->Gmask, gpScreen->format->Bmask, gpScreen->format->Amask); if (!pNewFadeSurface) { // cannot create surface, just blit the surface to the screen if (s != NULL) { SDL_BlitSurface(s, NULL, gpScreen, NULL); SDL_UpdateRect(gpScreen, 0, 0, gpScreen->w, gpScreen->h); } return; } if (s == NULL) { // make black screen SDL_FillRect(pNewFadeSurface, NULL, SDL_MapRGB(pNewFadeSurface->format, 0, 0, 0)); } else { SDL_BlitSurface(s, NULL, pNewFadeSurface, NULL); } if (SDL_MUSTLOCK(gpScreen)) { if (SDL_LockSurface(gpScreen) < 0) { // cannot lock screen, just blit the surface to the screen if (s != NULL) { SDL_BlitSurface(s, NULL, gpScreen, NULL); SDL_UpdateRect(gpScreen, 0, 0, gpScreen->w, gpScreen->h); } return; } } const unsigned long size = gpScreen->pitch * gpScreen->h; unsigned char *fadeFromRGB = (unsigned char *)calloc(size, 1); unsigned char *fadeToRGB = (unsigned char *)calloc(size, 1); if (fadeFromRGB == NULL || fadeToRGB == NULL) { TerminateOnError("Memory allocation error !"); } memcpy(fadeFromRGB, gpScreen->pixels, size); memcpy(fadeToRGB, pNewFadeSurface->pixels, size); int first = SDL_GetTicks(), now = first; do { // The +50 is to allow first frame to show some change float ratio = (now - first + 50) / (float)duration; const unsigned char amount = (unsigned char)(ratio * 255); const unsigned char oldamount = 255 - amount; unsigned char *pw = (unsigned char *)gpScreen->pixels; unsigned char *stop = pw + size; unsigned char *from = fadeFromRGB; unsigned char *to = fadeToRGB; do { //dividing by 256 instead of 255 provides huge optimization *pw = (oldamount * *(from++) + amount * *(to++)) / 256; } while (++pw != stop); now = SDL_GetTicks(); SDL_UpdateRect(gpScreen, 0, 0, gpScreen->w, gpScreen->h); } while (now - first + 50 < duration); free(fadeFromRGB); free(fadeToRGB); SDL_BlitSurface(pNewFadeSurface, NULL, gpScreen, NULL); SDL_UpdateRect(gpScreen, 0, 0, gpScreen->w, gpScreen->h); if (SDL_MUSTLOCK(gpScreen)) SDL_UnlockSurface(gpScreen); SDL_FreeSurface(pNewFadeSurface); }