| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616 | 
							- /* -*- mode: c; tab-width: 4; c-basic-offset: 4; c-file-style: "linux" -*- */
 
- //
 
- // Copyright (c) 2009-2011, Wei Mingzhi <whistler_wmz@users.sf.net>.
 
- // Copyright (c) 2011-2017, SDLPAL development team.
 
- // All rights reserved.
 
- //
 
- // This file is part of SDLPAL.
 
- //
 
- // SDLPAL is free software: you can redistribute it and/or modify
 
- // it under the terms of the GNU General Public License as published by
 
- // the Free Software Foundation, either version 3 of the License, or
 
- // (at your option) any later version.
 
- //
 
- // This program is distributed in the hope that it will be useful,
 
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
 
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
- // GNU General Public License for more details.
 
- //
 
- // You should have received a copy of the GNU General Public License
 
- // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
- //
 
- #include "main.h"
 
- VOID
 
- PAL_GameUpdate(
 
-    BOOL       fTrigger
 
- )
 
- /*++
 
-   Purpose:
 
-     The main game logic routine. Update the status of everything.
 
-   Parameters:
 
-     [IN]  fTrigger - whether to process trigger events or not.
 
-   Return value:
 
-     None.
 
- --*/
 
- {
 
-    WORD            wEventObjectID, wDir;
 
-    int             i;
 
-    LPEVENTOBJECT   p;
 
-    //
 
-    // Check for trigger events
 
-    //
 
-    if (fTrigger)
 
-    {
 
-       //
 
-       // Check if we are entering a new scene
 
-       //
 
-       if (gpGlobals->fEnteringScene)
 
-       {
 
-          //
 
-          // Run the script for entering the scene
 
-          //
 
-          gpGlobals->fEnteringScene = FALSE;
 
-          i = gpGlobals->wNumScene - 1;
 
-          gpGlobals->g.rgScene[i].wScriptOnEnter =
 
-             PAL_RunTriggerScript(gpGlobals->g.rgScene[i].wScriptOnEnter, 0xFFFF);
 
-          if (gpGlobals->fEnteringScene || gpGlobals->fGameStart)
 
-          {
 
-             //
 
-             // Don't go further as we're switching to another scene
 
-             //
 
-             return;
 
-          }
 
-          PAL_ClearKeyState();
 
-          PAL_MakeScene();
 
-       }
 
-       //
 
-       // Update the vanish time for all event objects
 
-       //
 
-       for (wEventObjectID = 0; wEventObjectID < gpGlobals->g.nEventObject; wEventObjectID++)
 
-       {
 
-          p = &gpGlobals->g.lprgEventObject[wEventObjectID];
 
-          if (p->sVanishTime != 0)
 
-          {
 
-             p->sVanishTime += ((p->sVanishTime < 0) ? 1 : -1);
 
-          }
 
-       }
 
-       //
 
-       // Loop through all event objects in the current scene
 
-       //
 
-       for (wEventObjectID = gpGlobals->g.rgScene[gpGlobals->wNumScene - 1].wEventObjectIndex + 1;
 
-          wEventObjectID <= gpGlobals->g.rgScene[gpGlobals->wNumScene].wEventObjectIndex;
 
-          wEventObjectID++)
 
-       {
 
-          p = &gpGlobals->g.lprgEventObject[wEventObjectID - 1];
 
-          if (p->sVanishTime != 0)
 
-          {
 
-             continue;
 
-          }
 
-          if (p->sState < 0)
 
-          {
 
-             if (p->x < PAL_X(gpGlobals->viewport) ||
 
-                p->x > PAL_X(gpGlobals->viewport) + 320 ||
 
-                p->y < PAL_Y(gpGlobals->viewport) ||
 
-                p->y > PAL_Y(gpGlobals->viewport) + 320)
 
-             {
 
-                p->sState = abs(p->sState);
 
-                p->wCurrentFrameNum = 0;
 
-             }
 
-          }
 
-          else if (p->sState > 0 && p->wTriggerMode >= kTriggerTouchNear)
 
-          {
 
-             //
 
-             // This event object can be triggered without manually exploring
 
-             //
 
-             if (abs(PAL_X(gpGlobals->viewport) + PAL_X(gpGlobals->partyoffset) - p->x) +
 
-                abs(PAL_Y(gpGlobals->viewport) + PAL_Y(gpGlobals->partyoffset) - p->y) * 2 <
 
-                (p->wTriggerMode - kTriggerTouchNear) * 32 + 16)
 
-             {
 
-                //
 
-                // Player is in the trigger zone.
 
-                //
 
-                if (p->nSpriteFrames)
 
-                {
 
-                   //
 
-                   // The sprite has multiple frames. Try to adjust the direction.
 
-                   //
 
-                   int                xOffset, yOffset;
 
-                   p->wCurrentFrameNum = 0;
 
-                   xOffset = PAL_X(gpGlobals->viewport) + PAL_X(gpGlobals->partyoffset) - p->x;
 
-                   yOffset = PAL_Y(gpGlobals->viewport) + PAL_Y(gpGlobals->partyoffset) - p->y;
 
-                   if (xOffset > 0)
 
-                   {
 
-                      p->wDirection = ((yOffset > 0) ? kDirEast : kDirNorth);
 
-                   }
 
-                   else
 
-                   {
 
-                      p->wDirection = ((yOffset > 0) ? kDirSouth : kDirWest);
 
-                   }
 
-                   //
 
-                   // Redraw the scene
 
-                   //
 
-                   PAL_UpdatePartyGestures(FALSE);
 
-                   PAL_MakeScene();
 
-                   VIDEO_UpdateScreen(NULL);
 
-                }
 
-                //
 
-                // Execute the script.
 
-                //
 
-                p->wTriggerScript = PAL_RunTriggerScript(p->wTriggerScript, wEventObjectID);
 
-                PAL_ClearKeyState();
 
-                if (gpGlobals->fEnteringScene || gpGlobals->fGameStart)
 
-                {
 
-                   //
 
-                   // Don't go further on scene switching
 
-                   //
 
-                   return;
 
-                }
 
-             }
 
-          }
 
-       }
 
-    }
 
-    //
 
-    // Run autoscript for each event objects
 
-    //
 
-    for (wEventObjectID = gpGlobals->g.rgScene[gpGlobals->wNumScene - 1].wEventObjectIndex + 1;
 
-       wEventObjectID <= gpGlobals->g.rgScene[gpGlobals->wNumScene].wEventObjectIndex;
 
-       wEventObjectID++)
 
-    {
 
-       p = &gpGlobals->g.lprgEventObject[wEventObjectID - 1];
 
-       if (p->sState > 0 && p->sVanishTime == 0)
 
-       {
 
-          WORD wScriptEntry = p->wAutoScript;
 
-          if (wScriptEntry != 0)
 
-          {
 
-             p->wAutoScript = PAL_RunAutoScript(wScriptEntry, wEventObjectID);
 
-             if (gpGlobals->fEnteringScene || gpGlobals->fGameStart)
 
-             {
 
-                //
 
-                // Don't go further on scene switching
 
-                //
 
-                return;
 
-             }
 
-          }
 
-       }
 
-       //
 
-       // Check if the player is in the way
 
-       //
 
-       if (fTrigger && p->sState >= kObjStateBlocker && p->wSpriteNum != 0 &&
 
-          abs(p->x - PAL_X(gpGlobals->viewport) - PAL_X(gpGlobals->partyoffset)) +
 
-          abs(p->y - PAL_Y(gpGlobals->viewport) - PAL_Y(gpGlobals->partyoffset)) * 2 <= 12)
 
-       {
 
-          //
 
-          // Player is in the way, try to move a step
 
-          //
 
-          wDir = (p->wDirection + 1) % 4;
 
-          for (i = 0; i < 4; i++)
 
-          {
 
-             int              x, y;
 
-             PAL_POS          pos;
 
-             x = PAL_X(gpGlobals->viewport) + PAL_X(gpGlobals->partyoffset);
 
-             y = PAL_Y(gpGlobals->viewport) + PAL_Y(gpGlobals->partyoffset);
 
-             x += ((wDir == kDirWest || wDir == kDirSouth) ? -16 : 16);
 
-             y += ((wDir == kDirWest || wDir == kDirNorth) ? -8 : 8);
 
-             pos = PAL_XY(x, y);
 
-             if (!PAL_CheckObstacle(pos, TRUE, 0))
 
-             {
 
-                //
 
-                // move here
 
-                //
 
-                gpGlobals->viewport = PAL_XY(
 
-                   PAL_X(pos) - PAL_X(gpGlobals->partyoffset),
 
-                   PAL_Y(pos) - PAL_Y(gpGlobals->partyoffset));
 
-                break;
 
-             }
 
-             wDir = (wDir + 1) % 4;
 
-          }
 
-       }
 
-    }
 
-    gpGlobals->dwFrameNum++;
 
- }
 
- VOID
 
- PAL_GameUseItem(
 
-    VOID
 
- )
 
- /*++
 
-   Purpose:
 
-     Allow player use an item in the game.
 
-   Parameters:
 
-     None.
 
-   Return value:
 
-     None.
 
- --*/
 
- {
 
-    WORD         wObject;
 
-    while (TRUE)
 
-    {
 
-       wObject = PAL_ItemSelectMenu(NULL, kItemFlagUsable);
 
-       if (wObject == 0)
 
-       {
 
-          return;
 
-       }
 
-       if (!(gpGlobals->g.rgObject[wObject].item.wFlags & kItemFlagApplyToAll))
 
-       {
 
-          //
 
-          // Select the player to use the item on
 
-          //
 
-          WORD     wPlayer = 0;
 
-          while (TRUE)
 
-          {
 
-             wPlayer = PAL_ItemUseMenu(wObject);
 
-             if (wPlayer == MENUITEM_VALUE_CANCELLED)
 
-             {
 
-                break;
 
-             }
 
-             //
 
-             // Run the script
 
-             //
 
-             gpGlobals->g.rgObject[wObject].item.wScriptOnUse =
 
-                PAL_RunTriggerScript(gpGlobals->g.rgObject[wObject].item.wScriptOnUse, wPlayer);
 
-             //
 
-             // Remove the item if the item is consuming and the script succeeded
 
-             //
 
-             if ((gpGlobals->g.rgObject[wObject].item.wFlags & kItemFlagConsuming) &&
 
-                g_fScriptSuccess)
 
-             {
 
-                PAL_AddItemToInventory(wObject, -1);
 
-             }
 
-          }
 
-       }
 
-       else
 
-       {
 
-          //
 
-          // Run the script
 
-          //
 
-          gpGlobals->g.rgObject[wObject].item.wScriptOnUse =
 
-             PAL_RunTriggerScript(gpGlobals->g.rgObject[wObject].item.wScriptOnUse, 0xFFFF);
 
-          //
 
-          // Remove the item if the item is consuming and the script succeeded
 
-          //
 
-          if ((gpGlobals->g.rgObject[wObject].item.wFlags & kItemFlagConsuming) &&
 
-             g_fScriptSuccess)
 
-          {
 
-             PAL_AddItemToInventory(wObject, -1);
 
-          }
 
-          return;
 
-       }
 
-    }
 
- }
 
- VOID
 
- PAL_GameEquipItem(
 
-    VOID
 
- )
 
- /*++
 
-   Purpose:
 
-     Allow player equip an item in the game.
 
-   Parameters:
 
-     None.
 
-   Return value:
 
-     None.
 
- --*/
 
- {
 
-    WORD      wObject;
 
-    while (TRUE)
 
-    {
 
-       wObject = PAL_ItemSelectMenu(NULL, kItemFlagEquipable);
 
-       if (wObject == 0)
 
-       {
 
-          return;
 
-       }
 
-       PAL_EquipItemMenu(wObject);
 
-    }
 
- }
 
- VOID
 
- PAL_Search(
 
-    VOID
 
- )
 
- /*++
 
-   Purpose:
 
-     Process searching trigger events.
 
-   Parameters:
 
-     None.
 
-   Return value:
 
-     None.
 
- --*/
 
- {
 
-    int                x, y, xOffset, yOffset, dx, dy, dh, ex, ey, eh, i, k, l;
 
-    LPEVENTOBJECT      p;
 
-    PAL_POS            rgPos[13];
 
-    //
 
-    // Get the party location
 
-    //
 
-    x = PAL_X(gpGlobals->viewport) + PAL_X(gpGlobals->partyoffset);
 
-    y = PAL_Y(gpGlobals->viewport) + PAL_Y(gpGlobals->partyoffset);
 
-    if (gpGlobals->wPartyDirection == kDirNorth || gpGlobals->wPartyDirection == kDirEast)
 
-    {
 
-       xOffset = 16;
 
-    }
 
-    else
 
-    {
 
-       xOffset = -16;
 
-    }
 
-    if (gpGlobals->wPartyDirection == kDirEast || gpGlobals->wPartyDirection == kDirSouth)
 
-    {
 
-       yOffset = 8;
 
-    }
 
-    else
 
-    {
 
-       yOffset = -8;
 
-    }
 
-    rgPos[0] = PAL_XY(x, y);
 
-    for (i = 0; i < 4; i++)
 
-    {
 
-       rgPos[i * 3 + 1] = PAL_XY(x + xOffset, y + yOffset);
 
-       rgPos[i * 3 + 2] = PAL_XY(x, y + yOffset * 2);
 
-       rgPos[i * 3 + 3] = PAL_XY(x + xOffset, y);
 
-       x += xOffset;
 
-       y += yOffset;
 
-    }
 
-    for (i = 0; i < 13; i++)
 
-    {
 
-       //
 
-       // Convert to map location
 
-       //
 
-       dh = ((PAL_X(rgPos[i]) % 32) ? 1 : 0);
 
-       dx = PAL_X(rgPos[i]) / 32;
 
-       dy = PAL_Y(rgPos[i]) / 16;
 
-       //
 
-       // Loop through all event objects
 
-       //
 
-       for (k = gpGlobals->g.rgScene[gpGlobals->wNumScene - 1].wEventObjectIndex;
 
-          k < gpGlobals->g.rgScene[gpGlobals->wNumScene].wEventObjectIndex; k++)
 
-       {
 
-          p = &(gpGlobals->g.lprgEventObject[k]);
 
-          ex = p->x / 32;
 
-          ey = p->y / 16;
 
-          eh = ((p->x % 32) ? 1 : 0);
 
-          if (p->sState <= 0 || p->wTriggerMode >= kTriggerTouchNear ||
 
-             p->wTriggerMode * 6 - 4 < i || dx != ex || dy != ey || dh != eh)
 
-          {
 
-             continue;
 
-          }
 
-          //
 
-          // Adjust direction/gesture for party members and the event object
 
-          //
 
-          if (p->nSpriteFrames * 4 > p->wCurrentFrameNum)
 
-          {
 
-             p->wCurrentFrameNum = 0; // use standing gesture
 
-             p->wDirection = (gpGlobals->wPartyDirection + 2) % 4; // face the party
 
-             for (l = 0; l <= gpGlobals->wMaxPartyMemberIndex; l++)
 
-             {
 
-                //
 
-                // All party members should face the event object
 
-                //
 
-                gpGlobals->rgParty[l].wFrame = gpGlobals->wPartyDirection * 3;
 
-             }
 
-             //
 
-             // Redraw everything
 
-             //
 
-             PAL_MakeScene();
 
-             VIDEO_UpdateScreen(NULL);
 
-          }
 
-          //
 
-          // Execute the script
 
-          //
 
-          p->wTriggerScript = PAL_RunTriggerScript(p->wTriggerScript, k + 1);
 
-          //
 
-          // Clear inputs and delay for a short time
 
-          //
 
-          UTIL_Delay(50);
 
-          PAL_ClearKeyState();
 
-          return; // don't go further
 
-       }
 
-    }
 
- }
 
- VOID
 
- PAL_StartFrame(
 
-    VOID
 
- )
 
- /*++
 
-   Purpose:
 
-     Starts a video frame. Called once per video frame.
 
-   Parameters:
 
-     None.
 
-   Return value:
 
-     None.
 
- --*/
 
- {
 
-    //
 
-    // Run the game logic of one frame
 
-    //
 
-    PAL_GameUpdate(TRUE);
 
-    if (gpGlobals->fEnteringScene)
 
-    {
 
-       return;
 
-    }
 
-    //
 
-    // Update the positions and gestures of party members
 
-    //
 
-    PAL_UpdateParty();
 
-    //
 
-    // Update the scene
 
-    //
 
-    PAL_MakeScene();
 
-    VIDEO_UpdateScreen(NULL);
 
-    if (g_InputState.dwKeyPress & kKeyMenu)
 
-    {
 
-       //
 
-       // Show the in-game menu
 
-       //
 
-       PAL_InGameMenu();
 
-    }
 
-    else if (g_InputState.dwKeyPress & kKeyUseItem)
 
-    {
 
-       //
 
-       // Show the use item menu
 
-       //
 
-       PAL_GameUseItem();
 
-    }
 
-    else if (g_InputState.dwKeyPress & kKeyThrowItem)
 
-    {
 
-       //
 
-       // Show the equipment menu
 
-       //
 
-       PAL_GameEquipItem();
 
-    }
 
-    else if (g_InputState.dwKeyPress & kKeyForce)
 
-    {
 
-       //
 
-       // Show the magic menu
 
-       //
 
-       PAL_InGameMagicMenu();
 
-    }
 
-    else if (g_InputState.dwKeyPress & kKeyStatus)
 
-    {
 
-       //
 
-       // Show the player status
 
-       //
 
-       PAL_PlayerStatus();
 
-    }
 
-    else if (g_InputState.dwKeyPress & kKeySearch)
 
-    {
 
-       //
 
-       // Process search events
 
-       //
 
-       PAL_Search();
 
-    }
 
-    else if (g_InputState.dwKeyPress & kKeyFlee)
 
-    {
 
-       //
 
-       // Quit Game
 
-       //
 
-       PAL_QuitGame();
 
-    }
 
-    if (--gpGlobals->wChasespeedChangeCycles == 0)
 
-    {
 
-       gpGlobals->wChaseRange = 1;
 
-    }
 
- }
 
- VOID
 
- PAL_WaitForKey(
 
-    WORD      wTimeOut
 
- )
 
- /*++
 
-   Purpose:
 
-     Wait for any key.
 
-   Parameters:
 
-     [IN]  wTimeOut - the maximum time of the waiting. 0 = wait forever.
 
-   Return value:
 
-     None.
 
- --*/
 
- {
 
-    DWORD     dwTimeOut = SDL_GetTicks() + wTimeOut;
 
-    PAL_ClearKeyState();
 
-    while (wTimeOut == 0 || !SDL_TICKS_PASSED(SDL_GetTicks(), dwTimeOut))
 
-    {
 
-       UTIL_Delay(5);
 
-       if (g_InputState.dwKeyPress & (kKeySearch | kKeyMenu))
 
-       {
 
-          break;
 
-       }
 
-    }
 
- }
 
 
  |