Beispiel #1
0
/*++
 Read global game data from data files.
 --*/
static VOID PAL_ReadGlobalGameData(void)
{
   const GAMEDATA    *p = &gpGlobals->g;
   unsigned int       i;

   LOAD_DATA(p->lprgScriptEntry, p->nScriptEntry * sizeof(SCRIPTENTRY),
      4, gpGlobals->f.fpSSS);

   LOAD_DATA(p->lprgStore, p->nStore * sizeof(STORE), 0, gpGlobals->f.fpDATA);
   LOAD_DATA(p->lprgEnemy, p->nEnemy * sizeof(ENEMY), 1, gpGlobals->f.fpDATA);
   LOAD_DATA(p->lprgEnemyTeam, p->nEnemyTeam * sizeof(ENEMYTEAM),
      2, gpGlobals->f.fpDATA);
   LOAD_DATA(p->lprgMagic, p->nMagic * sizeof(MAGIC), 4, gpGlobals->f.fpDATA);
   LOAD_DATA(p->lprgBattleField, p->nBattleField * sizeof(BATTLEFIELD),
      5, gpGlobals->f.fpDATA);
   LOAD_DATA(p->lprgLevelUpMagic, p->nLevelUpMagic * sizeof(LEVELUPMAGIC_ALL),
      6, gpGlobals->f.fpDATA);
   LOAD_DATA(p->rgwBattleEffectIndex, sizeof(p->rgwBattleEffectIndex),
      11, gpGlobals->f.fpDATA);
   PAL_MKFReadChunk((LPBYTE)&(p->EnemyPos), sizeof(p->EnemyPos),
      13, gpGlobals->f.fpDATA);
   DO_BYTESWAP(&(p->EnemyPos), sizeof(p->EnemyPos));
   PAL_MKFReadChunk((LPBYTE)(p->rgLevelUpExp), sizeof(p->rgLevelUpExp),
      14, gpGlobals->f.fpDATA);
   DO_BYTESWAP(p->rgLevelUpExp, sizeof(p->rgLevelUpExp));
}
Beispiel #2
0
/*++
 Load the default game data.
 --*/
static VOID PAL_LoadDefaultGame(void)
{
   const GAMEDATA    *p = &gpGlobals->g;
   UINT32             i;

   //
   // Load the default data from the game data files.
   //
   LOAD_DATA(p->lprgEventObject, p->nEventObject * sizeof(EVENTOBJECT),
      0, gpGlobals->f.fpSSS);
   PAL_MKFReadChunk((LPBYTE)(p->rgScene), sizeof(p->rgScene), 1, gpGlobals->f.fpSSS);
   DO_BYTESWAP(p->rgScene, sizeof(p->rgScene));
   PAL_MKFReadChunk((LPBYTE)(p->rgObject), sizeof(p->rgObject), 2, gpGlobals->f.fpSSS);
   DO_BYTESWAP(p->rgObject, sizeof(p->rgObject));

   PAL_MKFReadChunk((LPBYTE)(&(p->PlayerRoles)), sizeof(PLAYERROLES),
      3, gpGlobals->f.fpDATA);
   DO_BYTESWAP(&(p->PlayerRoles), sizeof(PLAYERROLES));

   //
   // Set some other default data.
   //
   gpGlobals->dwCash = 0;
   gpGlobals->wNumMusic = 0;
   gpGlobals->wNumPalette = 0;
   gpGlobals->wNumScene = 1;
   gpGlobals->wCollectValue = 0;
   gpGlobals->fNightPalette = FALSE;
   gpGlobals->wMaxPartyMemberIndex = 0;
   gpGlobals->viewport = PAL_XY(0, 0);
   gpGlobals->wLayer = 0;
   gpGlobals->wChaseRange = 1;
#ifndef PAL_CLASSIC
   gpGlobals->bBattleSpeed = 2;
#endif

   memset(gpGlobals->rgInventory, 0, sizeof(gpGlobals->rgInventory));
   memset(gpGlobals->rgPoisonStatus, 0, sizeof(gpGlobals->rgPoisonStatus));
   memset(gpGlobals->rgParty, 0, sizeof(gpGlobals->rgParty));
   memset(gpGlobals->rgTrail, 0, sizeof(gpGlobals->rgTrail));
   memset(&(gpGlobals->Exp), 0, sizeof(gpGlobals->Exp));

   for (i = 0; i < MAX_PLAYER_ROLES; i++)
   {
      gpGlobals->Exp.rgPrimaryExp[i].wLevel = p->PlayerRoles.rgwLevel[i];
      gpGlobals->Exp.rgHealthExp[i].wLevel = p->PlayerRoles.rgwLevel[i];
      gpGlobals->Exp.rgMagicExp[i].wLevel = p->PlayerRoles.rgwLevel[i];
      gpGlobals->Exp.rgAttackExp[i].wLevel = p->PlayerRoles.rgwLevel[i];
      gpGlobals->Exp.rgMagicPowerExp[i].wLevel = p->PlayerRoles.rgwLevel[i];
      gpGlobals->Exp.rgDefenseExp[i].wLevel = p->PlayerRoles.rgwLevel[i];
      gpGlobals->Exp.rgDexterityExp[i].wLevel = p->PlayerRoles.rgwLevel[i];
      gpGlobals->Exp.rgFleeExp[i].wLevel = p->PlayerRoles.rgwLevel[i];
   }

   gpGlobals->fEnteringScene = TRUE;
}
Beispiel #3
0
INT
PAL_MKFDecompressChunk(
   LPBYTE          lpBuffer,
   UINT            uiBufferSize,
   UINT            uiChunkNum,
   FILE           *fp
)
/*++
  Purpose:

    Decompress a compressed chunk from an MKF archive into lpBuffer.

  Parameters:

    [OUT] lpBuffer - pointer to the destination buffer.

    [IN]  uiBufferSize - size of the destination buffer.

    [IN]  uiChunkNum - the number of the chunk in the MKF archive to read.

    [IN]  fp - pointer to the fopen'ed MKF file.

  Return value:

    Integer value which indicates the size of the chunk.
    -1 if there are error in parameters, or buffer size is not enough.
    -3 if cannot allocate memory for decompression.

--*/
{
   LPBYTE          buf;
   int             len;

   len = PAL_MKFGetChunkSize(uiChunkNum, fp);

   if (len <= 0)
   {
      return len;
   }

   buf = (LPBYTE)malloc(len);
   if (buf == NULL)
   {
      return -3;
   }

   PAL_MKFReadChunk(buf, len, uiChunkNum, fp);

   len = Decompress(buf, lpBuffer, uiBufferSize);
   free(buf);

   return len;
}
Beispiel #4
0
INT
PAL_InitUI(
   VOID
)
/*++
  Purpose:

    Initialze the UI subsystem.

  Parameters:

    None.

  Return value:

    0 = success, -1 = fail.

--*/
{
   int        iSize;

   //
   // Load the UI sprite.
   //
   iSize = PAL_MKFGetChunkSize(CHUNKNUM_SPRITEUI, gpGlobals->f.fpDATA);
   if (iSize < 0)
   {
      return -1;
   }

   gpSpriteUI = (LPSPRITE)calloc(1, iSize);
   if (gpSpriteUI == NULL)
   {
      return -1;
   }

   PAL_MKFReadChunk(gpSpriteUI, iSize, CHUNKNUM_SPRITEUI, gpGlobals->f.fpDATA);

   return 0;
}
Beispiel #5
0
INT
PAL_InitText(
   VOID
)
/*++
  Purpose:

    Initialize the in-game texts.

  Parameters:

    None.

  Return value:

    0 = success.
    -1 = memory allocation error.

--*/
{
   FILE       *fpMsg, *fpWord;
   int         i;

   //
   // Open the message and word data files.
   //
   fpMsg = UTIL_OpenRequiredFile("m.msg");
   fpWord = UTIL_OpenRequiredFile("word.dat");

   //
   // See how many words we have
   //
   fseek(fpWord, 0, SEEK_END);
   i = ftell(fpWord);

   //
   // Each word has 10 bytes
   //
   g_TextLib.nWords = (i + (WORD_LENGTH - 1)) / WORD_LENGTH;

   //
   // Read the words
   //
   g_TextLib.lpWordBuf = (LPBYTE)malloc(i);
   if (g_TextLib.lpWordBuf == NULL)
   {
      fclose(fpWord);
      fclose(fpMsg);
      return -1;
   }
   fseek(fpWord, 0, SEEK_SET);
   fread(g_TextLib.lpWordBuf, i, 1, fpWord);

   //
   // Close the words file
   //
   fclose(fpWord);

   //
   // Read the message offsets. The message offsets are in SSS.MKF #3
   //
   i = PAL_MKFGetChunkSize(3, gpGlobals->f.fpSSS) / sizeof(DWORD);
   g_TextLib.nMsgs = i - 1;

   g_TextLib.lpMsgOffset = (LPDWORD)malloc(i * sizeof(DWORD));
   if (g_TextLib.lpMsgOffset == NULL)
   {
      free(g_TextLib.lpWordBuf);
      fclose(fpMsg);
      return -1;
   }

   PAL_MKFReadChunk((LPBYTE)(g_TextLib.lpMsgOffset), i * sizeof(DWORD), 3,
      gpGlobals->f.fpSSS);

   //
   // Read the messages.
   //
   fseek(fpMsg, 0, SEEK_END);
   i = ftell(fpMsg);

   g_TextLib.lpMsgBuf = (LPBYTE)malloc(i);
   if (g_TextLib.lpMsgBuf == NULL)
   {
      free(g_TextLib.lpMsgOffset);
      free(g_TextLib.lpWordBuf);
      fclose(fpMsg);
      return -1;
   }

   fseek(fpMsg, 0, SEEK_SET);
   fread(g_TextLib.lpMsgBuf, 1, i, fpMsg);

   fclose(fpMsg);

   g_TextLib.bCurrentFontColor = FONT_COLOR_DEFAULT;
   g_TextLib.bIcon = 0;
   g_TextLib.posIcon = 0;
   g_TextLib.nCurrentDialogLine = 0;
   g_TextLib.iDelayTime = 3;
   g_TextLib.posDialogTitle = PAL_XY(12, 8);
   g_TextLib.posDialogText = PAL_XY(44, 26);
   g_TextLib.bDialogPosition = kDialogUpper;
   g_TextLib.fUserSkip = FALSE;

   PAL_MKFReadChunk(g_TextLib.bufDialogIcons, 282, 12, gpGlobals->f.fpDATA);

   return 0;
}
Beispiel #6
0
VOID
PAL_StartDialog(
   BYTE         bDialogLocation,
   BYTE         bFontColor,
   INT          iNumCharFace,
   BOOL         fPlayingRNG
)
/*++
  Purpose:

    Start a new dialog.

  Parameters:

    [IN]  bDialogLocation - the location of the text on the screen.

    [IN]  bFontColor - the font color of the text.

    [IN]  iNumCharFace - number of the character face in RGM.MKF.

    [IN]  fPlayingRNG - whether we are playing a RNG video or not.

  Return value:

    None.

--*/
{
   PAL_LARGE BYTE buf[16384];
   SDL_Rect       rect;

   if (gpGlobals->fInBattle && !g_fUpdatedInBattle)
   {
      //
      // Update the screen in battle, or the graphics may seem messed up
      //
      VIDEO_UpdateScreen(NULL);
      g_fUpdatedInBattle = TRUE;
   }

   g_TextLib.bIcon = 0;
   g_TextLib.posIcon = 0;
   g_TextLib.nCurrentDialogLine = 0;
   g_TextLib.posDialogTitle = PAL_XY(12, 8);
   g_TextLib.fUserSkip = FALSE;

   if (bFontColor != 0)
   {
      g_TextLib.bCurrentFontColor = bFontColor;
   }

   if (fPlayingRNG && iNumCharFace)
   {
      VIDEO_BackupScreen();
      g_TextLib.fPlayingRNG = TRUE;
   }

   switch (bDialogLocation)
   {
   case kDialogUpper:
      if (iNumCharFace > 0)
      {
         //
         // Display the character face at the upper part of the screen
         //
         if (PAL_MKFReadChunk(buf, 16384, iNumCharFace, gpGlobals->f.fpRGM) > 0)
         {
            rect.w = PAL_RLEGetWidth((LPCBITMAPRLE)buf);
            rect.h = PAL_RLEGetHeight((LPCBITMAPRLE)buf);
            rect.x = 48 - rect.w / 2;
            rect.y = 55 - rect.h / 2;

            if (rect.x < 0)
            {
               rect.x = 0;
            }

            if (rect.y < 0)
            {
               rect.y = 0;
            }

            PAL_RLEBlitToSurface((LPCBITMAPRLE)buf, gpScreen, PAL_XY(rect.x, rect.y));

            if (rect.x < 0)
            {
               rect.x = 0;
            }
            if (rect.y < 0)
            {
               rect.y = 0;
            }

            VIDEO_UpdateScreen(&rect);
         }
      }
      g_TextLib.posDialogTitle = PAL_XY(iNumCharFace > 0 ? 80 : 12, 8);
      g_TextLib.posDialogText = PAL_XY(iNumCharFace > 0 ? 96 : 44, 26);
      break;

   case kDialogCenter:
      g_TextLib.posDialogText = PAL_XY(80, 40);
      break;

   case kDialogLower:
      if (iNumCharFace > 0)
      {
         //
         // Display the character face at the lower part of the screen
         //
         if (PAL_MKFReadChunk(buf, 16384, iNumCharFace, gpGlobals->f.fpRGM) > 0)
         {
            rect.x = 270 - PAL_RLEGetWidth((LPCBITMAPRLE)buf) / 2;
            rect.y = 144 - PAL_RLEGetHeight((LPCBITMAPRLE)buf) / 2;

            PAL_RLEBlitToSurface((LPCBITMAPRLE)buf, gpScreen, PAL_XY(rect.x, rect.y));

            VIDEO_UpdateScreen(NULL);
         }
      }
      g_TextLib.posDialogTitle = PAL_XY(iNumCharFace > 0 ? 4 : 12, 108);
      g_TextLib.posDialogText = PAL_XY(iNumCharFace > 0 ? 20 : 44, 126);
      break;

   case kDialogCenterWindow:
      g_TextLib.posDialogText = PAL_XY(160, 40);
      break;
   }

   g_TextLib.bDialogPosition = bDialogLocation;
}
Beispiel #7
0
VOID
MIDI_Play(
   INT       iNumRIX,
   BOOL      fLoop
)
/*++
  Purpose:

    Start playing the specified music in MIDI format.

  Parameters:

    [IN]  iNumRIX - number of the music. 0 to stop playing current music.

    [IN]  fLoop - Whether the music should be looped or not.

  Return value:

    None.

--*/
{
   FILE            *fp;
   unsigned char   *buf;
   int              size;
   SDL_RWops       *rw;
#ifdef PAL_WIN95
   char             filename[1024];
#endif

   if (g_pMid != NULL && iNumRIX == iMidCurrent && native_midi_active())
   {
      return;
   }

   SOUND_PlayCDA(-1);
   native_midi_freesong(g_pMid);
   g_pMid = NULL;
   iMidCurrent = -1;

   if (g_fNoMusic || iNumRIX <= 0)
   {
      return;
   }

#ifdef PAL_WIN95
   sprintf(filename, "%s/musics/%.3d.mid", PAL_PREFIX, iNumRIX);

   g_pMid = native_midi_loadsong(filename);
   if (g_pMid != NULL)
   {
      native_midi_start(g_pMid);

      iMidCurrent = iNumRIX;
      fMidLoop = fLoop;
   }
#else
   fp = UTIL_OpenFile("midi.mkf");
   if (fp == NULL)
   {
      return;
   }

   if (iNumRIX > PAL_MKFGetChunkCount(fp))
   {
      fclose(fp);
      return;
   }

   size = PAL_MKFGetChunkSize(iNumRIX, fp);
   if (size <= 0)
   {
      fclose(fp);
      return;
   }

   buf = (unsigned char *)UTIL_malloc(size);

   PAL_MKFReadChunk((LPBYTE)buf, size, iNumRIX, fp);
   fclose(fp);

   rw = SDL_RWFromConstMem((const void *)buf, size);

   g_pMid = native_midi_loadsong_RW(rw);
   if (g_pMid != NULL)
   {
      native_midi_start(g_pMid);

      iMidCurrent = iNumRIX;
      fMidLoop = fLoop;
   }

   SDL_RWclose(rw);
   free(buf);
#endif
}
Beispiel #8
0
/*++
 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;
}
Beispiel #9
0
VOID
MIDI_Play(
   INT       iNumRIX,
   BOOL      fLoop
)
/*++
  Purpose:

    Start playing the specified music in MIDI format.

  Parameters:

    [IN]  iNumRIX - number of the music. 0 to stop playing current music.

    [IN]  fLoop - Whether the music should be looped or not.

  Return value:

    None.

--*/
{
   FILE            *fp;
   unsigned char   *buf;
   int              size;
   SDL_RWops       *rw;

#ifdef TIMIDITY
   if (g_pMid != NULL && iNumRIX == iMidCurrent && Timidity_Active())
#else
   if (g_pMid != NULL && iNumRIX == iMidCurrent && native_midi_active())
#endif
   {
      return;
   }

   SOUND_PlayCDA(-1);
#ifdef TIMIDITY
   Timidity_FreeSong(g_pMid);
#else
   native_midi_freesong(g_pMid);
#endif
   g_pMid = NULL;
   iMidCurrent = -1;

   if (g_fNoMusic || iNumRIX <= 0)
   {
      return;
   }

   fp = fopen(PAL_PREFIX "midi.mkf", "rb");
   if (fp == NULL)
   {
      return;
   }

   if (iNumRIX > PAL_MKFGetChunkCount(fp))
   {
      fclose(fp);
      return;
   }

   size = PAL_MKFGetChunkSize(iNumRIX, fp);
   if (size <= 0)
   {
      fclose(fp);
      return;
   }

   buf = (unsigned char *)UTIL_malloc(size);

   PAL_MKFReadChunk((LPBYTE)buf, size, iNumRIX, fp);
   fclose(fp);

   rw = SDL_RWFromConstMem((const void *)buf, size);

#ifdef TIMIDITY
   g_pMid = Timidity_LoadSong_RW(rw);
#else
   g_pMid = native_midi_loadsong_RW(rw);
#endif
   if (g_pMid != NULL)
   {
#ifdef TIMIDITY
      Timidity_Start(g_pMid);
#else
      native_midi_start(g_pMid);
#endif

      iMidCurrent = iNumRIX;
      fMidLoop = fLoop;
   }

   SDL_RWclose(rw);
   free(buf);
}
Beispiel #10
0
WORD
PAL_ItemSelectMenuUpdate(
   VOID
)
/*++
  Purpose:

    Initialize the item selection menu.

  Parameters:

    None.

  Return value:

    The object ID of the selected item. 0 if cancelled, 0xFFFF if not confirmed.

--*/
{
#ifndef PAL_WIN95
   int                i, j, k;
   WORD               wObject;
#else
   int                i, j, k, line;
   WORD               wObject, wScript;
#endif
   BYTE               bColor;
   static BYTE        bufImage[2048];
   static WORD        wPrevImageIndex = 0xFFFF;

   //
   // Process input
   //
   if (g_InputState.dwKeyPress & kKeyUp)
   {
      gpGlobals->iCurInvMenuItem -= 3;
   }
   else if (g_InputState.dwKeyPress & kKeyDown)
   {
      gpGlobals->iCurInvMenuItem += 3;
   }
   else if (g_InputState.dwKeyPress & kKeyLeft)
   {
      gpGlobals->iCurInvMenuItem--;
   }
   else if (g_InputState.dwKeyPress & kKeyRight)
   {
      gpGlobals->iCurInvMenuItem++;
   }
   else if (g_InputState.dwKeyPress & kKeyPgUp)
   {
      gpGlobals->iCurInvMenuItem -= 3 * 7;
   }
   else if (g_InputState.dwKeyPress & kKeyPgDn)
   {
      gpGlobals->iCurInvMenuItem += 3 * 7;
   }
   else if (g_InputState.dwKeyPress & kKeyMenu)
   {
      return 0;
   }

   //
   // Make sure the current menu item index is in bound
   //
   if (gpGlobals->iCurInvMenuItem < 0)
   {
      gpGlobals->iCurInvMenuItem = 0;
   }
   else if (gpGlobals->iCurInvMenuItem >= g_iNumInventory)
   {
      gpGlobals->iCurInvMenuItem = g_iNumInventory - 1;
   }

   //
   // Redraw the box
   //
   PAL_CreateBox(PAL_XY(2, 0), 6, 17, 1, FALSE);

   //
   // Draw the texts in the current page
   //
   i = gpGlobals->iCurInvMenuItem / 3 * 3 - 3 * 4;
   if (i < 0)
   {
      i = 0;
   }

   for (j = 0; j < 7; j++)
   {
      for (k = 0; k < 3; k++)
      {
         wObject = gpGlobals->rgInventory[i].wItem;
         bColor = MENUITEM_COLOR;

         if (i >= MAX_INVENTORY || wObject == 0)
         {
            //
            // End of the list reached
            //
            j = 7;
            break;
         }

         if (i == gpGlobals->iCurInvMenuItem)
         {
            if (!(gpGlobals->g.rgObject[wObject].item.wFlags & g_wItemFlags) ||
               (SHORT)gpGlobals->rgInventory[i].nAmount <= (SHORT)gpGlobals->rgInventory[i].nAmountInUse)
            {
               //
               // This item is not selectable
               //
               bColor = MENUITEM_COLOR_SELECTED_INACTIVE;
            }
            else
            {
               //
               // This item is selectable
               //
               if (gpGlobals->rgInventory[i].nAmount == 0)
               {
                  bColor = MENUITEM_COLOR_EQUIPPEDITEM;
               }
               else
               {
                  bColor = MENUITEM_COLOR_SELECTED;
               }
            }
         }
         else if (!(gpGlobals->g.rgObject[wObject].item.wFlags & g_wItemFlags) ||
            (SHORT)gpGlobals->rgInventory[i].nAmount <= (SHORT)gpGlobals->rgInventory[i].nAmountInUse)
         {
            //
            // This item is not selectable
            //
            bColor = MENUITEM_COLOR_INACTIVE;
         }
         else if (gpGlobals->rgInventory[i].nAmount == 0)
         {
            bColor = MENUITEM_COLOR_EQUIPPEDITEM;
         }

         //
         // Draw the text
         //
         PAL_DrawText(PAL_GetWord(wObject), PAL_XY(15 + k * 100, 12 + j * 18),
            bColor, TRUE, FALSE);

         //
         // Draw the cursor on the current selected item
         //
         if (i == gpGlobals->iCurInvMenuItem)
         {
            PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_CURSOR),
               gpScreen, PAL_XY(40 + k * 100, 22 + j * 18));
         }

         //
         // Draw the amount of this item
         //
		 if ((SHORT)gpGlobals->rgInventory[i].nAmount - (SHORT)gpGlobals->rgInventory[i].nAmountInUse > 1)
		 {
            PAL_DrawNumber(gpGlobals->rgInventory[i].nAmount - gpGlobals->rgInventory[i].nAmountInUse,
               2, PAL_XY(96 + k * 100, 17 + j * 18), kNumColorCyan, kNumAlignRight);
		 }

         i++;
      }
   }

   //
   // Draw the picture of current selected item
   //
   PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_ITEMBOX), gpScreen,
      PAL_XY(5, 140));

   wObject = gpGlobals->rgInventory[gpGlobals->iCurInvMenuItem].wItem;

   if (gpGlobals->g.rgObject[wObject].item.wBitmap != wPrevImageIndex)
   {
      if (PAL_MKFReadChunk(bufImage, 2048,
         gpGlobals->g.rgObject[wObject].item.wBitmap, gpGlobals->f.fpBALL) > 0)
      {
         wPrevImageIndex = gpGlobals->g.rgObject[wObject].item.wBitmap;
      }
      else
      {
         wPrevImageIndex = 0xFFFF;
      }
   }

   if (wPrevImageIndex != 0xFFFF)
   {
      PAL_RLEBlitToSurface(bufImage, gpScreen, PAL_XY(12, 148));
   }

   //
   // Draw the description of the selected item
   //
#ifndef PAL_WIN95
   if (!g_fNoDesc && gpGlobals->lpObjectDesc != NULL)
   {
      char szDesc[512], *next;
      const char *d = PAL_GetObjectDesc(gpGlobals->lpObjectDesc, wObject);

      if (d != NULL)
      {
         k = 150;
         strcpy(szDesc, d);
         d = szDesc;

         while (TRUE)
         {
            next = strchr(d, '*');
            if (next != NULL)
            {
               *next = '\0';
               next++;
            }

            PAL_DrawText(d, PAL_XY(75, k), DESCTEXT_COLOR, TRUE, FALSE);
            k += 16;

            if (next == NULL)
            {
               break;
            }

            d = next;
         }
      }
   }
#else
   if (!g_fNoDesc)
   {
      wScript = gpGlobals->g.rgObject[wObject].item.wScriptDesc;
      line = 0;
      while (wScript && gpGlobals->g.lprgScriptEntry[wScript].wOperation != 0)
      {
         if (gpGlobals->g.lprgScriptEntry[wScript].wOperation == 0xFFFF)
         {
            wScript = PAL_RunAutoScript(wScript, (1 << 15) | line);
            line++;
         }
         else
         {
            wScript = PAL_RunAutoScript(wScript, 0);
         }
      }
   }
#endif

   if (g_InputState.dwKeyPress & kKeySearch)
   {
      if ((gpGlobals->g.rgObject[wObject].item.wFlags & g_wItemFlags) &&
         (SHORT)gpGlobals->rgInventory[gpGlobals->iCurInvMenuItem].nAmount >
         (SHORT)gpGlobals->rgInventory[gpGlobals->iCurInvMenuItem].nAmountInUse)
      {
         if (gpGlobals->rgInventory[gpGlobals->iCurInvMenuItem].nAmount > 0)
         {
            j = (gpGlobals->iCurInvMenuItem < 3 * 4) ? (gpGlobals->iCurInvMenuItem / 3) : 4;
            k = gpGlobals->iCurInvMenuItem % 3;

            PAL_DrawText(PAL_GetWord(wObject), PAL_XY(15 + k * 100, 12 + j * 18),
               MENUITEM_COLOR_CONFIRMED, FALSE, FALSE);
         }

         return wObject;
      }
   }

   return 0xFFFF;
}
Beispiel #11
0
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);
         }
      }
   }
}
Beispiel #12
0
static VOID
PAL_BuyMenu_OnItemChange(
   WORD           wCurrentItem
)
/*++
  Purpose:

    Callback function which is called when player selected another item
    in the buy menu.

  Parameters:

    [IN]  wCurrentItem - current item on the menu, indicates the object ID of
                         the currently selected item.

  Return value:

    None.

--*/
{
   const SDL_Rect      rect = {20, 8, 128, 175};
   int                 i, n;
   PAL_LARGE BYTE      bufImage[2048];

   //
   // Draw the picture of current selected item
   //
   PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_ITEMBOX), gpScreen,
      PAL_XY(35, 8));

   if (PAL_MKFReadChunk(bufImage, 2048,
      gpGlobals->g.rgObject[wCurrentItem].item.wBitmap, gpGlobals->f.fpBALL) > 0)
   {
      PAL_RLEBlitToSurface(bufImage, gpScreen, PAL_XY(42, 16));
   }

   //
   // See how many of this item we have in the inventory
   //
   n = 0;

   for (i = 0; i < MAX_INVENTORY; i++)
   {
      if (gpGlobals->rgInventory[i].wItem == 0)
      {
         break;
      }
      else if (gpGlobals->rgInventory[i].wItem == wCurrentItem)
      {
         n = gpGlobals->rgInventory[i].nAmount;
         break;
      }
   }

   //
   // Draw the amount of this item in the inventory
   //
   PAL_CreateSingleLineBox(PAL_XY(20, 105), 5, FALSE);
   PAL_DrawText(PAL_GetWord(BUYMENU_LABEL_CURRENT), PAL_XY(30, 115), 0, FALSE, FALSE);
   PAL_DrawNumber(n, 6, PAL_XY(69, 119), kNumColorYellow, kNumAlignRight);

   //
   // Draw the cash amount
   //
   PAL_CreateSingleLineBox(PAL_XY(20, 145), 5, FALSE);
   PAL_DrawText(PAL_GetWord(CASH_LABEL), PAL_XY(30, 155), 0, FALSE, FALSE);
   PAL_DrawNumber(gpGlobals->dwCash, 6, PAL_XY(69, 159), kNumColorYellow, kNumAlignRight);

   VIDEO_UpdateScreen(&rect);
}
Beispiel #13
0
WORD
PAL_ItemUseMenu(
   WORD           wItemToUse
)
/*++
  Purpose:

    Show the use item menu.

  Parameters:

    [IN]  wItemToUse - the object ID of the item to use.

  Return value:

    The selected player to use the item onto.
    MENUITEM_VALUE_CANCELLED if user cancelled.

--*/
{
   BYTE           bColor, bSelectedColor;
   PAL_LARGE BYTE bufImage[2048];
   DWORD          dwColorChangeTime;
   static WORD    wSelectedPlayer = 0;
   SDL_Rect       rect = {110, 2, 200, 180};
   int            i;

   bSelectedColor = MENUITEM_COLOR_SELECTED_FIRST;
   dwColorChangeTime = 0;

   while (TRUE)
   {
      if (wSelectedPlayer > gpGlobals->wMaxPartyMemberIndex)
      {
         wSelectedPlayer = 0;
      }

      //
      // Draw the box
      //
      PAL_CreateBox(PAL_XY(110, 2), 7, 9, 0, FALSE);

      //
      // Draw the stats of the selected player
      //
      PAL_DrawText(PAL_GetWord(STATUS_LABEL_LEVEL), PAL_XY(200, 16),
         ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE);
      PAL_DrawText(PAL_GetWord(STATUS_LABEL_HP), PAL_XY(200, 34),
         ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE);
      PAL_DrawText(PAL_GetWord(STATUS_LABEL_MP), PAL_XY(200, 52),
         ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE);
      PAL_DrawText(PAL_GetWord(STATUS_LABEL_ATTACKPOWER), PAL_XY(200, 70),
         ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE);
      PAL_DrawText(PAL_GetWord(STATUS_LABEL_MAGICPOWER), PAL_XY(200, 88),
         ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE);
      PAL_DrawText(PAL_GetWord(STATUS_LABEL_RESISTANCE), PAL_XY(200, 106),
         ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE);
      PAL_DrawText(PAL_GetWord(STATUS_LABEL_DEXTERITY), PAL_XY(200, 124),
         ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE);
      PAL_DrawText(PAL_GetWord(STATUS_LABEL_FLEERATE), PAL_XY(200, 142),
         ITEMUSEMENU_COLOR_STATLABEL, TRUE, FALSE);

      i = gpGlobals->rgParty[wSelectedPlayer].wPlayerRole;

      PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwLevel[i], 4, PAL_XY(240, 20),
         kNumColorYellow, kNumAlignRight);

      PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen,
         PAL_XY(263, 38));
      PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxHP[i], 4,
         PAL_XY(261, 40), kNumColorBlue, kNumAlignRight);
      PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwHP[i], 4,
         PAL_XY(240, 37), kNumColorYellow, kNumAlignRight);

      PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH), gpScreen,
         PAL_XY(263, 56));
      PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMaxMP[i], 4,
         PAL_XY(261, 58), kNumColorBlue, kNumAlignRight);
      PAL_DrawNumber(gpGlobals->g.PlayerRoles.rgwMP[i], 4,
         PAL_XY(240, 55), kNumColorYellow, kNumAlignRight);

      PAL_DrawNumber(PAL_GetPlayerAttackStrength(i), 4, PAL_XY(240, 74),
         kNumColorYellow, kNumAlignRight);
      PAL_DrawNumber(PAL_GetPlayerMagicStrength(i), 4, PAL_XY(240, 92),
         kNumColorYellow, kNumAlignRight);
      PAL_DrawNumber(PAL_GetPlayerDefense(i), 4, PAL_XY(240, 110),
         kNumColorYellow, kNumAlignRight);
      PAL_DrawNumber(PAL_GetPlayerDexterity(i), 4, PAL_XY(240, 128),
         kNumColorYellow, kNumAlignRight);
      PAL_DrawNumber(PAL_GetPlayerFleeRate(i), 4, PAL_XY(240, 146),
         kNumColorYellow, kNumAlignRight);

      //
      // Draw the names of the players in the party
      //
      for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++)
      {
         if (i == wSelectedPlayer)
         {
            bColor = bSelectedColor;
         }
         else
         {
            bColor = MENUITEM_COLOR;
         }

         PAL_DrawText(PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[gpGlobals->rgParty[i].wPlayerRole]),
            PAL_XY(125, 16 + 20 * i), bColor, TRUE, FALSE);
      }

      PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_ITEMBOX), gpScreen,
         PAL_XY(120, 80));

      i = PAL_GetItemAmount(wItemToUse);

      if (i > 0)
      {
         //
         // Draw the picture of the item
         //
         if (PAL_MKFReadChunk(bufImage, 2048,
            gpGlobals->g.rgObject[wItemToUse].item.wBitmap, gpGlobals->f.fpBALL) > 0)
         {
            PAL_RLEBlitToSurface(bufImage, gpScreen, PAL_XY(127, 88));
         }

         //
         // Draw the amount and label of the item
         //
         PAL_DrawText(PAL_GetWord(wItemToUse), PAL_XY(116, 143), STATUS_COLOR_EQUIPMENT,
            TRUE, FALSE);
         PAL_DrawNumber(i, 2, PAL_XY(170, 133), kNumColorCyan, kNumAlignRight);
      }

      //
      // Update the screen area
      //
      VIDEO_UpdateScreen(&rect);

      //
      // Wait for key
      //
      PAL_ClearKeyState();

      while (TRUE)
      {
         //
         // 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.
            //
            PAL_DrawText(
               PAL_GetWord(gpGlobals->g.PlayerRoles.rgwName[gpGlobals->rgParty[wSelectedPlayer].wPlayerRole]),
               PAL_XY(125, 16 + 20 * wSelectedPlayer), bSelectedColor, FALSE, TRUE);
         }

         PAL_ProcessEvent();

         if (g_InputState.dwKeyPress != 0)
         {
            break;
         }

         SDL_Delay(1);
      }

      if (i <= 0)
      {
         return MENUITEM_VALUE_CANCELLED;
      }

      if (g_InputState.dwKeyPress & (kKeyUp | kKeyLeft))
      {
         wSelectedPlayer--;
      }
      else if (g_InputState.dwKeyPress & (kKeyDown | kKeyRight))
      {
         if (wSelectedPlayer < gpGlobals->wMaxPartyMemberIndex)
         {
            wSelectedPlayer++;
         }
      }
      else if (g_InputState.dwKeyPress & kKeyMenu)
      {
         break;
      }
      else if (g_InputState.dwKeyPress & kKeySearch)
      {
         return gpGlobals->rgParty[wSelectedPlayer].wPlayerRole;
      }
   }

   return MENUITEM_VALUE_CANCELLED;
}
Beispiel #14
0
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;
         }
      }
   }
}
Beispiel #15
0
SDL_Color *
PAL_GetPalette(
   INT         iPaletteNum,
   BOOL        fNight
)
/*++
  Purpose:

    Get the specified palette in pat.mkf file.

  Parameters:

    [IN]  iPaletteNum - number of the palette.

    [IN]  fNight - whether use the night palette or not.

  Return value:

    Pointer to the palette. NULL if failed.

--*/
{
   static SDL_Color      palette[256];
   PAL_LARGE BYTE        buf[1536];
   INT                   i;
   FILE                 *fp;

   fp = UTIL_OpenRequiredFile("pat.mkf");

   //
   // Read the palette data from the pat.mkf file
   //
   i = PAL_MKFReadChunk(buf, 1536, iPaletteNum, fp);

   fclose(fp);

   if (i < 0)
   {
      //
      // Read failed
      //
      return NULL;
   }
   else if (i <= 256 * 3)
   {
      //
      // There is no night colors in the palette
      //
      fNight = FALSE;
   }

   for (i = 0; i < 256; i++)
   {
      palette[i].r = buf[(fNight ? 256 * 3 : 0) + i * 3] << 2;
      palette[i].g = buf[(fNight ? 256 * 3 : 0) + i * 3 + 1] << 2;
      palette[i].b = buf[(fNight ? 256 * 3 : 0) + i * 3 + 2] << 2;
#if 0
      palette[i].r += (255 - palette[i].r) / 5;
      palette[i].g += (255 - palette[i].g) / 5;
      palette[i].b += (255 - palette[i].b) / 5;
#endif
   }

   return palette;
}