scummvm/gob/game.cpp
Torbjörn Andersson c3f3d9f3f2 Made Gobliiins less of a CPU hog by adding some strategic delays and
turning on the screen auto-dirtying - some as Simon uses. It's not perfect
by any means, but it may be good enough for 0.8.0 at least.

svn-id: r18649
2005-08-10 15:48:50 +00:00

1940 lines
44 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2004 Ivan Dubrov
* Copyright (C) 2004-2005 The ScummVM project
*
* This program 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 2
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#include "gob/gob.h"
#include "gob/global.h"
#include "gob/game.h"
#include "gob/video.h"
#include "gob/dataio.h"
#include "gob/pack.h"
#include "gob/scenery.h"
#include "gob/inter.h"
#include "gob/parse.h"
#include "gob/draw.h"
#include "gob/mult.h"
#include "gob/util.h"
#include "gob/goblin.h"
#include "gob/cdrom.h"
namespace Gob {
Game_ExtTable *game_extTable = 0;
char *game_totFileData = 0;
Game_TotTextTable *game_totTextData;
Game_TotResTable *game_totResourceTable = 0;
char *game_imFileData = 0;
int16 game_extHandle = 0;
char game_curExtFile[14];
char game_curTotFile[14];
char game_curImaFile[18];
Game_Collision *game_collisionAreas = 0;
char game_shouldPushColls = 0;
char game_collStr[256];
int16 game_lastCollKey;
int16 game_lastCollAreaIndex;
int16 game_lastCollId;
char game_handleMouse;
char game_forceHandleMouse;
char game_tempStr[256];
int16 game_activeCollResId;
int16 game_activeCollIndex;
// Collisions stack
int16 game_collStackSize = 0;
Game_Collision *game_collStack[3];
int16 game_collStackElemSizes[3];
int16 game_mouseButtons = 0;
// Capture
static Common::Rect game_captureStack[20];
static int16 game_captureCount = 0;
Snd_SoundDesc *game_soundSamples[20];
char game_soundFromExt[20];
char game_totToLoad[20];
int32 game_startTimeKey;
char *game_loadExtData(int16 itemId, int16 *pResWidth, int16 *pResHeight) {
int16 commonHandle;
int16 itemsCount;
int32 offset;
uint32 size;
Game_ExtItem *item;
char isPacked;
int16 handle;
int32 tableSize;
char path[20];
char *dataBuf;
char *packedBuf;
char *dataPtr;
itemId -= 30000;
if (game_extTable == 0)
return 0;
commonHandle = -1;
itemsCount = game_extTable->itemsCount;
item = &game_extTable->items[itemId];
tableSize = szGame_ExtTable + szGame_ExtItem * itemsCount;
offset = item->offset;
size = item->size;
if (item->width & 0x8000)
isPacked = 1;
else
isPacked = 0;
if (pResWidth != 0) {
*pResWidth = item->width & 0x7fff;
*pResHeight = item->height;
debug(7, "game_loadExtData(%d, %d, %d)", itemId, *pResWidth, *pResHeight);
}
debug(7, "game_loadExtData(%d, 0, 0)", itemId);
if (item->height == 0)
size += (item->width & 0x7fff) << 16;
debug(7, "size: %d off: %d", size, offset);
if (offset >= 0) {
handle = game_extHandle;
} else {
offset = -(offset + 1);
tableSize = 0;
data_closeData(game_extHandle);
strcpy(path, "commun.ex1");
path[strlen(path) - 1] = *(game_totFileData + 0x3c) + '0';
commonHandle = data_openData(path);
handle = commonHandle;
}
debug(7, "off: %ld size: %ld", offset, tableSize);
data_seekData(handle, offset + tableSize, SEEK_SET);
if (isPacked)
dataBuf = (char *)malloc(size);
else
dataBuf = (char *)malloc(size);
dataPtr = dataBuf;
while (size > 32000) {
// BUG: huge->far conversion. Need normalization?
data_readData(handle, (char *)dataPtr, 32000);
size -= 32000;
dataPtr += 32000;
}
data_readData(handle, (char *)dataPtr, size);
if (commonHandle != -1) {
data_closeData(commonHandle);
game_extHandle = data_openData(game_curExtFile);
}
if (isPacked != 0) {
packedBuf = dataBuf;
dataBuf = (char *)malloc(READ_LE_UINT32(packedBuf));
unpackData(packedBuf, dataBuf);
free(packedBuf);
}
return dataBuf;
}
void game_clearCollisions() {
int16 i;
for (i = 0; i < 250; i++) {
game_collisionAreas[i].id = 0;
game_collisionAreas[i].left = -1;
}
}
void game_addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom,
int16 flags, int16 key, int16 funcEnter, int16 funcLeave) {
int16 i;
Game_Collision *ptr;
debug(5, "game_addNewCollision");
debug(5, "id = %x", id);
debug(5, "left = %d, top = %d, right = %d, bottom = %d", left, top, right, bottom);
debug(5, "flags = %x, key = %x", flags, key);
debug(5, "funcEnter = %d, funcLeave = %d", funcEnter, funcLeave);
for (i = 0; i < 250; i++) {
if (game_collisionAreas[i].left != -1)
continue;
ptr = &game_collisionAreas[i];
ptr->id = id;
ptr->left = left;
ptr->top = top;
ptr->right = right;
ptr->bottom = bottom;
ptr->flags = flags;
ptr->key = key;
ptr->funcEnter = funcEnter;
ptr->funcLeave = funcLeave;
return;
}
error("game_addNewCollision: Collision array full!\n");
}
void game_freeCollision(int16 id) {
int16 i;
for (i = 0; i < 250; i++) {
if (game_collisionAreas[i].id == id)
game_collisionAreas[i].left = -1;
}
}
void game_pushCollisions(char all) {
Game_Collision *srcPtr;
Game_Collision *destPtr;
int16 size;
debug(0, "game_pushCollisions");
for (size = 0, srcPtr = game_collisionAreas; srcPtr->left != -1;
srcPtr++) {
if (all || (srcPtr->id & 0x8000))
size++;
}
destPtr = (Game_Collision *)malloc(size * sizeof(Game_Collision));
game_collStack[game_collStackSize] = destPtr;
game_collStackElemSizes[game_collStackSize] = size;
game_collStackSize++;
for (srcPtr = game_collisionAreas; srcPtr->left != -1; srcPtr++) {
if (all || (srcPtr->id & 0x8000)) {
memcpy(destPtr, srcPtr, sizeof(Game_Collision));
srcPtr->left = -1;
destPtr++;
}
}
}
void game_popCollisions(void) {
Game_Collision *destPtr;
Game_Collision *srcPtr;
debug(0, "game_popCollision");
game_collStackSize--;
for (destPtr = game_collisionAreas; destPtr->left != -1; destPtr++);
srcPtr = game_collStack[game_collStackSize];
memcpy(destPtr, srcPtr,
game_collStackElemSizes[game_collStackSize] *
sizeof(Game_Collision));
free(game_collStack[game_collStackSize]);
}
int16 game_checkMousePoint(int16 all, int16 *resId, int16 *resIndex) {
Game_Collision *ptr;
int16 i;
if (resId != 0)
*resId = 0;
*resIndex = 0;
ptr = game_collisionAreas;
for (i = 0; ptr->left != -1; ptr++, i++) {
if (all) {
if ((ptr->flags & 0xf) > 1)
continue;
if ((ptr->flags & 0xff00) != 0)
continue;
if (inter_mouseX < ptr->left
|| inter_mouseX > ptr->right
|| inter_mouseY < ptr->top
|| inter_mouseY > ptr->bottom)
continue;
if (resId != 0)
*resId = ptr->id;
*resIndex = i;
return ptr->key;
} else {
if ((ptr->flags & 0xff00) != 0)
continue;
if ((ptr->flags & 0xf) != 1 && (ptr->flags & 0xf) != 2)
continue;
if ((ptr->flags & 0xf0) >> 4 != game_mouseButtons - 1
&& (ptr->flags & 0xf0) >> 4 != 2)
continue;
if (inter_mouseX < ptr->left
|| inter_mouseX > ptr->right
|| inter_mouseY < ptr->top
|| inter_mouseY > ptr->bottom)
continue;
if (resId != 0)
*resId = ptr->id;
*resIndex = i;
return ptr->key;
}
}
if (game_mouseButtons != 1 && all == 0)
return 0x11b;
return 0;
}
void game_capturePush(int16 left, int16 top, int16 width, int16 height) {
int16 right;
if (game_captureCount == 20)
error("game_capturePush: Capture stack overflow!");
game_captureStack[game_captureCount].left = left;
game_captureStack[game_captureCount].top = top;
game_captureStack[game_captureCount].right = left + width;
game_captureStack[game_captureCount].bottom = top + height;
draw_spriteTop = top;
draw_spriteBottom = height;
right = left + width - 1;
left &= 0xfff0;
right |= 0xf;
draw_spritesArray[30 + game_captureCount] =
vid_initSurfDesc(videoMode, right - left + 1, height, 0);
draw_sourceSurface = 21;
draw_destSurface = 30 + game_captureCount;
draw_spriteLeft = left;
draw_spriteRight = right - left + 1;
draw_destSpriteX = 0;
draw_destSpriteY = 0;
draw_transparency = 0;
draw_spriteOperation(0);
game_captureCount++;
}
void game_capturePop(char doDraw) {
if (game_captureCount <= 0)
return;
game_captureCount--;
if (doDraw) {
draw_destSpriteX = game_captureStack[game_captureCount].left;
draw_destSpriteY = game_captureStack[game_captureCount].top;
draw_spriteRight =
game_captureStack[game_captureCount].width();
draw_spriteBottom =
game_captureStack[game_captureCount].height();
draw_transparency = 0;
draw_sourceSurface = 30 + game_captureCount;
draw_destSurface = 21;
draw_spriteLeft = draw_destSpriteX & 0xf;
draw_spriteTop = 0;
draw_spriteOperation(0);
}
vid_freeSurfDesc(draw_spritesArray[30 + game_captureCount]);
}
char *game_loadTotResource(int16 id) {
Game_TotResItem *itemPtr;
int32 offset;
itemPtr = &game_totResourceTable->items[id];
offset = itemPtr->offset;
if (offset >= 0) {
return ((char *)game_totResourceTable) + szGame_TotResTable +
szGame_TotResItem * game_totResourceTable->itemsCount + offset;
} else {
return (char *)(game_imFileData + (int32)READ_LE_UINT32(&((int32 *)game_imFileData)[-offset - 1]));
}
}
void game_loadSound(int16 slot, char *dataPtr) {
Snd_SoundDesc *soundDesc;
soundDesc = (Snd_SoundDesc *)malloc(sizeof(Snd_SoundDesc));
game_soundSamples[slot] = soundDesc;
soundDesc->frequency = (dataPtr[4] << 8) + dataPtr[5];
soundDesc->size = (dataPtr[1] << 16) + (dataPtr[2] << 8) + dataPtr[3];
soundDesc->data = dataPtr + 6;
soundDesc->timerTicks = (int32)1193180 / (int32)soundDesc->frequency;
soundDesc->inClocks = (soundDesc->frequency * 10) / 182;
soundDesc->flag = 0;
}
void game_interLoadSound(int16 slot) {
char *dataPtr;
int16 id;
if (slot == -1)
slot = parse_parseValExpr();
id = inter_load16();
if (id == -1) {
inter_execPtr += 9;
return;
}
if (id >= 30000) {
dataPtr = game_loadExtData(id, 0, 0);
game_soundFromExt[slot] = 1;
} else {
dataPtr = game_loadTotResource(id);
game_soundFromExt[slot] = 0;
}
game_loadSound(slot, dataPtr);
}
void game_freeSoundSlot(int16 slot) {
if (slot == -1)
slot = parse_parseValExpr();
if (game_soundSamples[slot] == 0)
return;
if (game_soundFromExt[slot] == 1) {
free(game_soundSamples[slot]->data - 6);
game_soundFromExt[slot] = 0;
}
free(game_soundSamples[slot]);
game_soundSamples[slot] = 0;
}
int16 game_checkKeys(int16 *pMouseX, int16 *pMouseY, int16 *pButtons, char handleMouse) {
util_processInput();
if (VAR(58) != 0) {
if (mult_frameStart != (int)VAR(58) - 1)
mult_frameStart++;
else
mult_frameStart = 0;
mult_playMult(mult_frameStart + VAR(57), mult_frameStart + VAR(57), 1,
handleMouse);
}
if (inter_soundEndTimeKey != 0
&& util_getTimeKey() >= inter_soundEndTimeKey) {
snd_stopSound(inter_soundStopVal);
inter_soundEndTimeKey = 0;
}
if (useMouse == 0)
error("game_checkKeys: Can't work without mouse!");
util_getMouseState(pMouseX, pMouseY, pButtons);
if (*pButtons == 3)
*pButtons = 0;
return util_checkKey();
}
int16 game_checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId,
int16 *pResIndex) {
char *savedIP;
int16 resIndex;
int16 key;
int16 oldIndex;
int16 oldId;
uint32 timeKey;
if (deltaTime >= -1) {
game_lastCollKey = 0;
game_lastCollAreaIndex = 0;
game_lastCollId = 0;
}
if (pResId != 0)
*pResId = 0;
resIndex = 0;
if (draw_cursorIndex == -1 && handleMouse != 0
&& game_lastCollKey == 0) {
game_lastCollKey =
game_checkMousePoint(1, &game_lastCollId,
&game_lastCollAreaIndex);
if (game_lastCollKey != 0 && (game_lastCollId & 0x8000) != 0) {
savedIP = inter_execPtr;
inter_execPtr = (char *)game_totFileData +
game_collisionAreas[game_lastCollAreaIndex].funcEnter;
inter_funcBlock(0);
inter_execPtr = savedIP;
}
}
if (handleMouse != 0)
draw_animateCursor(-1);
timeKey = util_getTimeKey();
while (1) {
if (inter_terminate != 0) {
if (handleMouse)
draw_blitCursor();
return 0;
}
if (draw_noInvalidated == 0) {
if (handleMouse)
draw_animateCursor(-1);
else
draw_blitInvalidated();
}
// NOTE: the original asm does the below game_checkKeys call
// _before_ this check. However, that can cause keypresses to get lost
// since there's a return statement in this check.
// Additionally, I added a 'deltaTime == -1' check there, since
// when this function is called with deltaTime == -1 in game_inputArea,
// and the return value is then discarded.
if (deltaTime < 0) {
uint32 curtime = util_getTimeKey();
if (deltaTime == -1 || curtime + deltaTime > timeKey) {
if (pResId != 0)
*pResId = 0;
if (pResIndex != 0)
*pResIndex = 0;
return 0;
}
}
key = game_checkKeys(&inter_mouseX, &inter_mouseY,
&game_mouseButtons, handleMouse);
if (handleMouse == 0 && game_mouseButtons != 0) {
util_waitMouseRelease(0);
key = 3;
}
if (key != 0) {
if (handleMouse == 1)
draw_blitCursor();
if (pResId != 0)
*pResId = 0;
if (pResIndex != 0)
*pResIndex = 0;
if (game_lastCollKey != 0 &&
game_collisionAreas[game_lastCollAreaIndex].funcLeave != 0) {
savedIP = inter_execPtr;
inter_execPtr = (char *)game_totFileData +
game_collisionAreas[game_lastCollAreaIndex].funcLeave;
inter_funcBlock(0);
inter_execPtr = savedIP;
}
game_lastCollKey = 0;
if (key != 0)
return key;
}
if (handleMouse != 0) {
if (game_mouseButtons != 0) {
oldIndex = 0;
draw_animateCursor(2);
if (deltaTime <= 0) {
if (handleMouse == 1)
util_waitMouseRelease(1);
} else if (deltaTime > 0) {
util_delay(deltaTime);
}
draw_animateCursor(-1);
if (pResId != 0)
*pResId = 0;
key = game_checkMousePoint(0, pResId, &resIndex);
if (pResIndex != 0)
*pResIndex = resIndex;
if (key != 0 || (pResId != 0 && *pResId != 0)) {
if (handleMouse == 1 && (deltaTime <= 0
|| game_mouseButtons == 0))
draw_blitCursor();
if (game_lastCollKey != 0 &&
game_collisionAreas[game_lastCollAreaIndex].funcLeave != 0) {
savedIP = inter_execPtr;
inter_execPtr =
(char *)game_totFileData +
game_collisionAreas[game_lastCollAreaIndex].funcLeave;
inter_funcBlock(0);
inter_execPtr = savedIP;
}
game_lastCollKey = 0;
return key;
}
if (game_lastCollKey != 0 &&
game_collisionAreas[game_lastCollAreaIndex].funcLeave != 0) {
savedIP = inter_execPtr;
inter_execPtr =
(char *)game_totFileData +
game_collisionAreas[game_lastCollAreaIndex].funcLeave;
inter_funcBlock(0);
inter_execPtr = savedIP;
}
game_lastCollKey =
game_checkMousePoint(1, &game_lastCollId,
&game_lastCollAreaIndex);
if (game_lastCollKey != 0
&& (game_lastCollId & 0x8000) != 0) {
savedIP = inter_execPtr;
inter_execPtr =
(char *)game_totFileData +
game_collisionAreas[game_lastCollAreaIndex].funcEnter;
inter_funcBlock(0);
inter_execPtr = savedIP;
}
} else {
if (handleMouse != 0 &&
(inter_mouseX != draw_cursorX
|| inter_mouseY != draw_cursorY)) {
oldIndex = game_lastCollAreaIndex;
oldId = game_lastCollId;
key =
game_checkMousePoint(1,
&game_lastCollId,
&game_lastCollAreaIndex);
if (key != game_lastCollKey) {
if (game_lastCollKey != 0
&& (oldId & 0x8000) != 0) {
savedIP = inter_execPtr;
inter_execPtr = (char *)game_totFileData +
game_collisionAreas[oldIndex].funcLeave;
inter_funcBlock(0);
inter_execPtr = savedIP;
}
game_lastCollKey = key;
if (game_lastCollKey != 0 && (game_lastCollId & 0x8000) != 0) {
savedIP = inter_execPtr;
inter_execPtr = (char *)game_totFileData +
game_collisionAreas[game_lastCollAreaIndex].funcEnter;
inter_funcBlock(0);
inter_execPtr = savedIP;
}
}
}
}
}
if (handleMouse != 0)
draw_animateCursor(-1);
util_delay(10);
snd_loopSounds();
}
}
int16 game_inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 backColor,
int16 frontColor, char *str, int16 fontIndex, char inpType, int16 *pTotTime) {
int16 handleMouse;
uint32 editSize;
FontDesc *pFont;
char curSym;
int16 key;
const char *str1;
const char *str2;
int16 i;
uint32 pos;
int16 flag;
int16 savedKey;
if (game_handleMouse != 0 &&
(useMouse != 0 || game_forceHandleMouse != 0))
handleMouse = 1;
else
handleMouse = 0;
pos = strlen(str);
pFont = draw_fonts[fontIndex];
editSize = width / pFont->itemWidth;
while (1) {
strcpy(game_tempStr, str);
strcat(game_tempStr, " ");
if (strlen(game_tempStr) > editSize)
strcpy(game_tempStr, str);
draw_destSpriteX = xPos;
draw_destSpriteY = yPos;
draw_spriteRight = editSize * pFont->itemWidth;
draw_spriteBottom = height;
draw_destSurface = 21;
draw_backColor = backColor;
draw_frontColor = frontColor;
draw_textToPrint = game_tempStr;
draw_transparency = 1;
draw_fontIndex = fontIndex;
draw_spriteOperation(DRAW_FILLRECT);
draw_destSpriteY = yPos + (height - 8) / 2;
draw_spriteOperation(DRAW_PRINTTEXT);
if (pos == editSize)
pos--;
curSym = game_tempStr[pos];
flag = 1;
while (1) {
game_tempStr[0] = curSym;
game_tempStr[1] = 0;
draw_destSpriteX = xPos + pFont->itemWidth * pos;
draw_destSpriteY = yPos + height - 1;
draw_spriteRight = pFont->itemWidth;
draw_spriteBottom = 1;
draw_destSurface = 21;
draw_backColor = frontColor;
draw_spriteOperation(DRAW_FILLRECT);
if (flag != 0) {
key = game_checkCollisions(handleMouse, -1,
&game_activeCollResId,
&game_activeCollIndex);
}
flag = 0;
key = game_checkCollisions(handleMouse, -300,
&game_activeCollResId, &game_activeCollIndex);
if (*pTotTime > 0) {
*pTotTime -= 300;
if (*pTotTime <= 1) {
key = 0;
game_activeCollResId = 0;
break;
}
}
game_tempStr[0] = curSym;
game_tempStr[1] = 0;
draw_destSpriteX = xPos + pFont->itemWidth * pos;
draw_destSpriteY = yPos + height - 1;
draw_spriteRight = pFont->itemWidth;
draw_spriteBottom = 1;
draw_destSurface = 21;
draw_backColor = backColor;
draw_frontColor = frontColor;
draw_textToPrint = game_tempStr;
draw_transparency = 1;
draw_spriteOperation(DRAW_FILLRECT);
draw_destSpriteY = yPos + (height - 8) / 2;
draw_spriteOperation(DRAW_PRINTTEXT);
if (key != 0 || game_activeCollResId != 0)
break;
key = game_checkCollisions(handleMouse, -300,
&game_activeCollResId, &game_activeCollIndex);
if (*pTotTime > 0) {
*pTotTime -= 300;
if (*pTotTime <= 1) {
key = 0;
game_activeCollResId = 0;
break;
}
}
if (key != 0 || game_activeCollResId != 0)
break;
if (inter_terminate != 0)
return 0;
}
if (key == 0 || game_activeCollResId != 0
|| inter_terminate != 0)
return 0;
switch (key) {
case 0x4d00: // Right Arrow
if (pos < strlen(str) && pos < editSize - 1) {
pos++;
continue;
}
return 0x5000;
case 0x4b00: // Left Arrow
if (pos > 0) {
pos--;
continue;
}
return 0x4800;
case 0xe08: // Backspace
if (pos > 0) {
util_cutFromStr(str, pos - 1, 1);
pos--;
continue;
}
case 0x5300: // Del
if (pos >= strlen(str))
continue;
util_cutFromStr(str, pos, 1);
continue;
case 0x1c0d: // Enter
case 0x3b00: // F1
case 0x3c00: // F2
case 0x3d00: // F3
case 0x3e00: // F4
case 0x3f00: // F5
case 0x4000: // F6
case 0x4100: // F7
case 0x4200: // F8
case 0x4300: // F9
case 0x4400: // F10
case 0x4800: // Up arrow
case 0x5000: // Down arrow
return key;
case 0x11b: // Escape
if (useMouse != 0)
continue;
game_forceHandleMouse = !game_forceHandleMouse;
if (game_handleMouse != 0 &&
(useMouse != 0 || game_forceHandleMouse != 0))
handleMouse = 1;
else
handleMouse = 0;
if (pressedKeys[1] == 0)
continue;
while (pressedKeys[1] != 0);
continue;
default:
savedKey = key;
key &= 0xff;
if ((inpType == 9 || inpType == 10) && key >= ' '
&& key <= 0xff) {
str1 = "0123456789-.,+ ";
str2 = "0123456789-,,+ ";
if ((savedKey >> 8) > 1
&& (savedKey >> 8) < 12)
key = ((savedKey >> 8) - 1) % 10 + '0';
for (i = 0; str1[i] != 0; i++) {
if (key == str1[i]) {
key = str2[i];
break;
}
}
if (i == (int16)strlen(str1))
key = 0;
}
if (key >= ' ' && key <= 0xff) {
if (editSize == strlen(str))
util_cutFromStr(str, strlen(str) - 1,
1);
if (key >= 'a' && key <= 'z')
key += ('A' - 'a');
pos++;
game_tempStr[0] = key;
game_tempStr[1] = 0;
util_insertStr(game_tempStr, str, pos - 1);
//strupr(str);
}
}
}
}
int16 game_multiEdit(int16 time, int16 index, int16 *pCurPos, Game_InputDesc * inpDesc) {
Game_Collision *collArea;
int16 descInd;
int16 key;
int16 found = -1;
int16 i;
descInd = 0;
for (i = 0; i < 250; i++) {
collArea = &game_collisionAreas[i];
if (collArea->left == -1)
continue;
if ((collArea->id & 0x8000) == 0)
continue;
if ((collArea->flags & 0x0f) < 3)
continue;
if ((collArea->flags & 0x0f) > 10)
continue;
strcpy(game_tempStr, inter_variables + collArea->key);
draw_destSpriteX = collArea->left;
draw_destSpriteY = collArea->top;
draw_spriteRight = collArea->right - collArea->left + 1;
draw_spriteBottom = collArea->bottom - collArea->top + 1;
draw_destSurface = 21;
draw_backColor = inpDesc[descInd].backColor;
draw_frontColor = inpDesc[descInd].frontColor;
draw_textToPrint = game_tempStr;
draw_transparency = 1;
draw_fontIndex = inpDesc[descInd].fontIndex;
draw_spriteOperation(DRAW_FILLRECT);
draw_destSpriteY +=
((collArea->bottom - collArea->top + 1) - 8) / 2;
draw_spriteOperation(DRAW_PRINTTEXT);
descInd++;
}
for (i = 0; i < 40; i++) {
WRITE_VAR_OFFSET(i * 4 + 0x44, 0);
}
while (1) {
descInd = 0;
for (i = 0; i < 250; i++) {
collArea = &game_collisionAreas[i];
if (collArea->left == -1)
continue;
if ((collArea->id & 0x8000) == 0)
continue;
if ((collArea->flags & 0x0f) < 3)
continue;
if ((collArea->flags & 0x0f) > 10)
continue;
if (descInd == *pCurPos) {
found = i;
break;
}
descInd++;
}
assert(found != -1);
collArea = &game_collisionAreas[found];
key = game_inputArea(collArea->left, collArea->top,
collArea->right - collArea->left + 1,
collArea->bottom - collArea->top + 1,
inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor,
inter_variables + collArea->key,
inpDesc[*pCurPos].fontIndex, collArea->flags, &time);
if (inter_terminate != 0)
return 0;
switch (key) {
case 0:
if (game_activeCollResId == 0)
return 0;
if ((game_collisionAreas[game_activeCollIndex].
flags & 0x0f) < 3)
return 0;
if ((game_collisionAreas[game_activeCollIndex].
flags & 0x0f) > 10)
return 0;
*pCurPos = 0;
for (i = 0; i < 250; i++) {
collArea = &game_collisionAreas[i];
if (collArea->left == -1)
continue;
if ((collArea->id & 0x8000) == 0)
continue;
if ((collArea->flags & 0x0f) < 3)
continue;
if ((collArea->flags & 0x0f) > 10)
continue;
if (i == game_activeCollIndex)
break;
pCurPos[0]++;
}
break;
case 0x3b00:
case 0x3c00:
case 0x3d00:
case 0x3e00:
case 0x3f00:
case 0x4000:
case 0x4100:
case 0x4200:
case 0x4300:
case 0x4400:
return key;
case 0x1c0d:
if (index == 1)
return key;
if (*pCurPos == index - 1) {
*pCurPos = 0;
break;
}
pCurPos[0]++;
break;
case 0x5000:
if (index - 1 > *pCurPos)
pCurPos[0]++;
break;
case 0x4800:
if (*pCurPos > 0)
pCurPos[0]--;
break;
}
}
}
int16 game_adjustKey(int16 key) {
if (key <= 0x60 || key >= 0x7b)
return key;
return key - 0x20;
}
void game_collisionsBlock(void) {
Game_InputDesc descArray[20];
int16 array[250];
char count;
int16 collResId;
char *startIP;
int16 curCmd;
int16 cmd;
int16 cmdHigh;
int16 key;
int16 flags;
int16 left;
int16 top;
int16 width;
int16 height;
int16 var_22;
int16 index;
int16 curEditIndex;
int16 deltaTime;
int16 descIndex2;
int16 stackPos2;
int16 descIndex;
int16 timeVal;
char *str;
int16 pos;
int16 savedCollStackSize;
int16 i;
int16 counter;
int16 var_24;
int16 var_26;
int16 collStackPos;
Game_Collision *collPtr;
int16 timeKey;
char *savedIP;
if (game_shouldPushColls)
game_pushCollisions(1);
collResId = -1;
inter_execPtr++;
count = *inter_execPtr++;
game_handleMouse = inter_execPtr[0];
deltaTime = 1000 * (byte)inter_execPtr[1];
descIndex2 = (byte)inter_execPtr[2];
stackPos2 = (byte)inter_execPtr[3];
descIndex = (byte)inter_execPtr[4];
if (stackPos2 != 0 || descIndex != 0)
deltaTime /= 100;
timeVal = deltaTime;
inter_execPtr += 6;
startIP = inter_execPtr;
WRITE_VAR(16, 0);
var_22 = 0;
index = 0;
curEditIndex = 0;
for (curCmd = 0; curCmd < count; curCmd++) {
array[curCmd] = 0;
cmd = *inter_execPtr++;
if ((cmd & 0x40) != 0) {
cmd -= 0x40;
cmdHigh = (byte)*inter_execPtr;
inter_execPtr++;
cmdHigh <<= 8;
} else {
cmdHigh = 0;
}
if ((cmd & 0x80) != 0) {
left = parse_parseValExpr();
top = parse_parseValExpr();
width = parse_parseValExpr();
height = parse_parseValExpr();
} else {
left = inter_load16();
top = inter_load16();
width = inter_load16();
height = inter_load16();
}
cmd &= 0x7f;
debug(4, "game_collisionsBlock(%d)", cmd);
switch (cmd) {
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
util_waitKey();
var_22 = 1;
key = parse_parseVarIndex();
descArray[index].fontIndex = inter_load16();
descArray[index].backColor = *inter_execPtr++;
descArray[index].frontColor = *inter_execPtr++;
if (cmd < 5 || cmd > 8) {
descArray[index].ptr = 0;
} else {
descArray[index].ptr = inter_execPtr + 2;
inter_execPtr += inter_load16();
}
if (left == -1)
break;
if ((cmd & 1) == 0) {
game_addNewCollision(curCmd + 0x8000, left,
top,
left +
width *
draw_fonts[descArray[index].fontIndex]->
itemWidth - 1, top + height - 1, cmd, key,
0,
inter_execPtr - (char *)game_totFileData);
inter_execPtr += 2;
inter_execPtr += READ_LE_UINT16(inter_execPtr);
} else {
game_addNewCollision(curCmd + 0x8000, left,
top,
left +
width *
draw_fonts[descArray[index].fontIndex]->
itemWidth - 1, top + height - 1, cmd, key,
0, 0);
}
index++;
break;
case 21:
key = inter_load16();
array[curCmd] = inter_load16();
flags = inter_load16() & 3;
game_addNewCollision(curCmd + 0x8000, left, top,
left + width - 1,
top + height - 1,
(flags << 4) + cmdHigh + 2, key,
inter_execPtr - (char *)game_totFileData, 0);
inter_execPtr += 2;
inter_execPtr += READ_LE_UINT16(inter_execPtr);
break;
case 20:
collResId = curCmd;
// Fall through to case 2
case 2:
key = inter_load16();
array[curCmd] = inter_load16();
flags = inter_load16() & 3;
game_addNewCollision(curCmd + 0x8000, left, top,
left + width - 1,
top + height - 1,
(flags << 4) + cmdHigh + 2, key, 0,
inter_execPtr - (char *)game_totFileData);
inter_execPtr += 2;
inter_execPtr += READ_LE_UINT16(inter_execPtr);
break;
case 0:
inter_execPtr += 6;
startIP = inter_execPtr;
inter_execPtr += 2;
inter_execPtr += READ_LE_UINT16(inter_execPtr);
key = curCmd + 0xA000;
game_addNewCollision(curCmd + 0x8000, left, top,
left + width - 1,
top + height - 1,
cmd + cmdHigh, key,
startIP - (char *)game_totFileData,
inter_execPtr - (char *)game_totFileData);
inter_execPtr += 2;
inter_execPtr += READ_LE_UINT16(inter_execPtr);
break;
case 1:
key = inter_load16();
array[curCmd] = inter_load16();
flags = inter_load16() & 3;
startIP = inter_execPtr;
inter_execPtr += 2;
inter_execPtr += READ_LE_UINT16(inter_execPtr);
if (key == 0)
key = curCmd + 0xa000;
game_addNewCollision(curCmd + 0x8000, left, top,
left + width - 1,
top + height - 1,
(flags << 4) + cmd + cmdHigh, key,
startIP - (char *)game_totFileData,
inter_execPtr - (char *)game_totFileData);
inter_execPtr += 2;
inter_execPtr += READ_LE_UINT16(inter_execPtr);
break;
}
}
game_forceHandleMouse = 0;
util_waitKey();
do {
if (var_22 != 0) {
key =
game_multiEdit(deltaTime, index, &curEditIndex,
descArray);
if (key == 0x1c0d) {
for (i = 0; i < 250; i++) {
if (game_collisionAreas[i].left == -1)
continue;
if ((game_collisionAreas[i].id & 0x8000) == 0)
continue;
if ((game_collisionAreas[i].flags & 1) != 0)
continue;
if ((game_collisionAreas[i].flags & 0x0f) <= 2)
continue;
collResId = game_collisionAreas[i].id;
game_activeCollResId = collResId;
collResId &= 0x7fff;
game_activeCollIndex = i;
break;
}
break;
}
} else {
key =
game_checkCollisions(game_handleMouse, -deltaTime,
&game_activeCollResId, &game_activeCollIndex);
}
if ((key & 0xff) >= ' ' && (key & 0xff) <= 0xff &&
(key >> 8) > 1 && (key >> 8) < 12) {
key = '0' + (((key >> 8) - 1) % 10) + (key & 0xff00);
}
if (game_activeCollResId == 0) {
if (key != 0) {
for (i = 0; i < 250; i++) {
if (game_collisionAreas[i].left == -1)
continue;
if ((game_collisionAreas[i].
id & 0x8000) == 0)
continue;
if (game_collisionAreas[i].key == key
|| game_collisionAreas[i].key ==
0x7fff) {
game_activeCollResId =
game_collisionAreas[i].id;
game_activeCollIndex = i;
break;
}
}
if (game_activeCollResId == 0) {
for (i = 0; i < 250; i++) {
if (game_collisionAreas[i].left == -1)
continue;
if ((game_collisionAreas[i].id & 0x8000) == 0)
continue;
if ((game_collisionAreas[i].key & 0xff00) != 0)
continue;
if (game_collisionAreas[i].key == 0)
continue;
if (game_adjustKey(key & 0xff) == game_adjustKey(game_collisionAreas[i].key) || game_collisionAreas[i].key == 0x7fff) {
game_activeCollResId = game_collisionAreas[i].id;
game_activeCollIndex = i;
break;
}
}
}
} else {
if (deltaTime != 0 && VAR(16) == 0) {
if (stackPos2 != 0) {
collStackPos = 0;
collPtr = game_collisionAreas;
for (i = 0, collPtr = game_collisionAreas; collPtr->left != -1; i++, collPtr++) {
if ((collPtr->id & 0x8000) == 0)
continue;
collStackPos++;
if (collStackPos != stackPos2)
continue;
game_activeCollResId = collPtr->id;
game_activeCollIndex = i;
WRITE_VAR(2, inter_mouseX);
WRITE_VAR(3, inter_mouseY);
WRITE_VAR(4, game_mouseButtons);
WRITE_VAR(16, array[(uint16)game_activeCollResId & ~0x8000]);
if (collPtr->funcLeave != 0) {
timeKey = util_getTimeKey();
savedIP = inter_execPtr;
inter_execPtr = (char *)game_totFileData + collPtr->funcLeave;
game_shouldPushColls = 1;
savedCollStackSize = game_collStackSize;
inter_funcBlock(0);
if (savedCollStackSize != game_collStackSize)
game_popCollisions();
game_shouldPushColls = 0;
inter_execPtr = savedIP;
deltaTime = timeVal - (util_getTimeKey() - timeKey);
if (deltaTime < 2)
deltaTime = 2;
}
if (VAR(16) == 0)
game_activeCollResId = 0;
break;
}
} else {
if (descIndex != 0) {
counter = 0;
for (i = 0; i < 250; i++) {
if (game_collisionAreas[i].left == -1)
continue;
if ((game_collisionAreas[i].id & 0x8000) == 0)
continue;
counter++;
if (counter != descIndex)
continue;
game_activeCollResId = game_collisionAreas[i].id;
game_activeCollIndex = i;
break;
}
} else {
for (i = 0; i < 250; i++) {
if (game_collisionAreas[i].left == -1)
continue;
if ((game_collisionAreas[i].id & 0x8000) == 0)
continue;
game_activeCollResId = game_collisionAreas[i].id;
game_activeCollIndex = i;
break;
}
}
}
} else {
if (descIndex2 != 0) {
counter = 0;
for (i = 0; i < 250; i++) {
if (game_collisionAreas[i].left == -1)
continue;
if ((game_collisionAreas[i].id & 0x8000) == 0)
continue;
counter++;
if (counter != descIndex2)
continue;
game_activeCollResId = game_collisionAreas[i].id;
game_activeCollIndex = i;
break;
}
}
}
}
}
if (game_activeCollResId == 0)
continue;
if (game_collisionAreas[game_activeCollIndex].funcLeave != 0)
continue;
WRITE_VAR(2, inter_mouseX);
WRITE_VAR(3, inter_mouseY);
WRITE_VAR(4, game_mouseButtons);
WRITE_VAR(16, array[(uint16)game_activeCollResId & ~0x8000]);
if (game_collisionAreas[game_activeCollIndex].funcEnter != 0) {
savedIP = inter_execPtr;
inter_execPtr = (char *)game_totFileData +
game_collisionAreas[game_activeCollIndex].
funcEnter;
game_shouldPushColls = 1;
collStackPos = game_collStackSize;
inter_funcBlock(0);
if (collStackPos != game_collStackSize)
game_popCollisions();
game_shouldPushColls = 0;
inter_execPtr = savedIP;
}
WRITE_VAR(16, 0);
game_activeCollResId = 0;
}
while (game_activeCollResId == 0 && inter_terminate == 0);
if (((uint16)game_activeCollResId & ~0x8000) == collResId) {
collStackPos = 0;
var_24 = 0;
var_26 = 1;
for (i = 0; i < 250; i++) {
if (game_collisionAreas[i].left == -1)
continue;
if ((game_collisionAreas[i].id & 0x8000) == 0)
continue;
if ((game_collisionAreas[i].flags & 0x0f) < 3)
continue;
if ((game_collisionAreas[i].flags & 0x0f) > 10)
continue;
if ((game_collisionAreas[i].flags & 0x0f) > 8) {
strcpy(game_tempStr,
inter_variables + game_collisionAreas[i].key);
while ((pos =
util_strstr(" ", game_tempStr)) != 0) {
util_cutFromStr(game_tempStr, pos - 1, 1);
pos = util_strstr(" ", game_tempStr);
}
strcpy(inter_variables + game_collisionAreas[i].key, game_tempStr);
}
if ((game_collisionAreas[i].flags & 0x0f) >= 5 &&
(game_collisionAreas[i].flags & 0x0f) <= 8) {
str = descArray[var_24].ptr;
strcpy(game_tempStr, inter_variables + game_collisionAreas[i].key);
if ((game_collisionAreas[i].flags & 0x0f) < 7)
util_prepareStr(game_tempStr);
pos = 0;
do {
strcpy(game_collStr, str);
pos += strlen(str) + 1;
str += strlen(str) + 1;
if ((game_collisionAreas[i].flags & 0x0f) < 7)
util_prepareStr(game_collStr);
if (strcmp(game_tempStr, game_collStr) == 0) {
VAR(17)++;
WRITE_VAR(17 + var_26, 1);
break;
}
} while (READ_LE_UINT16(descArray[var_24].ptr - 2) > pos);
collStackPos++;
} else {
VAR(17 + var_26) = 2;
}
var_24++;
var_26++;
}
if (collStackPos != (int16)VAR(17))
WRITE_VAR(17, 0);
else
WRITE_VAR(17, 1);
}
savedIP = 0;
if (inter_terminate == 0) {
savedIP = (char *)game_totFileData +
game_collisionAreas[game_activeCollIndex].funcLeave;
WRITE_VAR(2, inter_mouseX);
WRITE_VAR(3, inter_mouseY);
WRITE_VAR(4, game_mouseButtons);
if (VAR(16) == 0) {
WRITE_VAR(16, array[(uint16)game_activeCollResId & ~0x8000]);
}
}
for (curCmd = 0; curCmd < count; curCmd++) {
game_freeCollision(curCmd + 0x8000);
}
inter_execPtr = savedIP;
}
void game_prepareStart(void) {
int16 i;
game_clearCollisions();
pPaletteDesc->unused2 = draw_unusedPalette2;
pPaletteDesc->unused1 = draw_unusedPalette1;
pPaletteDesc->vgaPal = draw_vgaPalette;
vid_setFullPalette(pPaletteDesc);
draw_backSurface = vid_initSurfDesc(videoMode, 320, 200, 0);
vid_fillRect(draw_backSurface, 0, 0, 319, 199, 1);
draw_frontSurface = pPrimarySurfDesc;
vid_fillRect(draw_frontSurface, 0, 0, 319, 199, 1);
util_setMousePos(152, 92);
draw_cursorX = 152;
inter_mouseX = 152;
draw_cursorY = 92;
inter_mouseY = 92;
draw_invalidatedCount = 0;
draw_noInvalidated = 1;
draw_applyPal = 0;
draw_paletteCleared = 0;
draw_cursorWidth = 16;
draw_cursorHeight = 16;
draw_transparentCursor = 1;
for (i = 0; i < 40; i++) {
draw_cursorAnimLow[i] = -1;
draw_cursorAnimDelays[i] = 0;
draw_cursorAnimHigh[i] = 0;
}
draw_cursorAnimLow[1] = 0;
draw_cursorSprites = vid_initSurfDesc(videoMode, 32, 16, 2);
draw_cursorBack = vid_initSurfDesc(videoMode, 16, 16, 0);
draw_renderFlags = 0;
draw_backDeltaX = 0;
draw_backDeltaY = 0;
game_startTimeKey = util_getTimeKey();
}
void game_loadTotFile(char *path) {
int16 handle;
handle = data_openData(path);
if (handle >= 0) {
data_closeData(handle);
game_totFileData = data_getData(path);
} else {
game_totFileData = 0;
}
}
void game_loadExtTable(void) {
int16 count, i;
// Function is correct. [sev]
game_extHandle = data_openData(game_curExtFile);
if (game_extHandle < 0)
return;
data_readData(game_extHandle, (char *)&count, 2);
count = FROM_LE_16(count);
data_seekData(game_extHandle, 0, 0);
game_extTable = (Game_ExtTable *)malloc(sizeof(Game_ExtTable)
+ sizeof(Game_ExtItem) * count);
data_readData(game_extHandle, (char *)&game_extTable->itemsCount, 2);
game_extTable->itemsCount = FROM_LE_16(game_extTable->itemsCount);
data_readData(game_extHandle, (char *)&game_extTable->unknown, 1);
for (i = 0; i < count; i++) {
data_readData(game_extHandle, (char *)&game_extTable->items[i].offset, 4);
game_extTable->items[i].offset = FROM_LE_32(game_extTable->items[i].offset);
data_readData(game_extHandle, (char *)&game_extTable->items[i].size, 2);
game_extTable->items[i].size = FROM_LE_16(game_extTable->items[i].size);
data_readData(game_extHandle, (char *)&game_extTable->items[i].width, 2);
game_extTable->items[i].width = FROM_LE_16(game_extTable->items[i].width);
data_readData(game_extHandle, (char *)&game_extTable->items[i].height, 2);
game_extTable->items[i].height = FROM_LE_16(game_extTable->items[i].height);
}
}
void game_loadImFile(void) {
char path[20];
int16 handle;
if (game_totFileData[0x3d] != 0 && game_totFileData[0x3b] == 0)
return;
strcpy(path, "commun.im1");
if (game_totFileData[0x3b] != 0)
path[strlen(path) - 1] = '0' + game_totFileData[0x3b];
handle = data_openData(path);
if (handle < 0)
return;
data_closeData(handle);
game_imFileData = data_getData(path);
}
void game_playTot(int16 skipPlay) {
char savedTotName[20];
int16 *oldCaptureCounter;
int16 *oldBreakFrom;
int16 *oldNestLevel;
int16 captureCounter;
int16 breakFrom;
int16 nestLevel;
char needTextFree;
char needFreeResTable;
char *curPtr;
int32 variablesCount;
char *filePtr;
char *savedIP;
int16 i;
oldNestLevel = inter_nestLevel;
oldBreakFrom = inter_breakFromLevel;
oldCaptureCounter = scen_pCaptureCounter;
savedIP = inter_execPtr;
inter_nestLevel = &nestLevel;
inter_breakFromLevel = &breakFrom;
scen_pCaptureCounter = &captureCounter;
strcpy(savedTotName, game_curTotFile);
if (skipPlay == 0) {
while (1) {
for (i = 0; i < 4; i++) {
draw_fontToSprite[i].sprite = -1;
draw_fontToSprite[i].base = -1;
draw_fontToSprite[i].width = -1;
draw_fontToSprite[i].height = -1;
}
cd_stopPlaying();
draw_animateCursor(4);
inter_initControlVars();
mult_initAll();
mult_zeroMultData();
for (i = 0; i < 20; i++)
draw_spritesArray[i] = 0;
draw_spritesArray[20] = draw_frontSurface;
draw_spritesArray[21] = draw_backSurface;
draw_spritesArray[23] = draw_cursorSprites;
for (i = 0; i < 20; i++)
game_soundSamples[i] = 0;
game_totTextData = 0;
game_totResourceTable = 0;
game_imFileData = 0;
game_extTable = 0;
game_extHandle = -1;
needFreeResTable = 1;
needTextFree = 1;
game_totToLoad[0] = 0;
if (game_curTotFile[0] == 0 && game_totFileData == 0)
break;
game_loadTotFile(game_curTotFile);
if (game_totFileData == 0) {
draw_blitCursor();
break;
}
strcpy(game_curImaFile, game_curTotFile);
strcpy(game_curExtFile, game_curTotFile);
game_curImaFile[strlen(game_curImaFile) - 4] = 0;
strcat(game_curImaFile, ".ima");
game_curExtFile[strlen(game_curExtFile) - 4] = 0;
strcat(game_curExtFile, ".ext");
debug(0, "IMA: %s", game_curImaFile);
debug(0, "EXT: %s", game_curExtFile);
filePtr = (char *)game_totFileData + 0x30;
if (READ_LE_UINT32(filePtr) != (uint32)-1) {
curPtr = game_totFileData;
game_totTextData =
(Game_TotTextTable *) (curPtr +
READ_LE_UINT32((char *)game_totFileData + 0x30));
game_totTextData->itemsCount = (int16)READ_LE_UINT16(&game_totTextData->itemsCount);
for (i = 0; i < game_totTextData->itemsCount; ++i) {
game_totTextData->items[i].offset = (int16)READ_LE_UINT16(&game_totTextData->items[i].offset);
game_totTextData->items[i].size = (int16)READ_LE_UINT16(&game_totTextData->items[i].size);
}
needTextFree = 0;
}
filePtr = (char *)game_totFileData + 0x34;
if (READ_LE_UINT32(filePtr) != (uint32)-1) {
curPtr = game_totFileData;
game_totResourceTable =
(Game_TotResTable *)(curPtr +
READ_LE_UINT32((char *)game_totFileData + 0x34));
game_totResourceTable->itemsCount = (int16)READ_LE_UINT16(&game_totResourceTable->itemsCount);
for (i = 0; i < game_totResourceTable->itemsCount; ++i) {
game_totResourceTable->items[i].offset = (int32)READ_LE_UINT32(&game_totResourceTable->items[i].offset);
game_totResourceTable->items[i].size = (int16)READ_LE_UINT16(&game_totResourceTable->items[i].size);
game_totResourceTable->items[i].width = (int16)READ_LE_UINT16(&game_totResourceTable->items[i].width);
game_totResourceTable->items[i].height = (int16)READ_LE_UINT16(&game_totResourceTable->items[i].height);
}
needFreeResTable = 0;
}
game_loadImFile();
game_loadExtTable();
inter_animDataSize = READ_LE_UINT16((char *)game_totFileData + 0x38);
if (inter_variables == 0) {
variablesCount = READ_LE_UINT32((char *)game_totFileData + 0x2c);
inter_variables = (char *)malloc(variablesCount * 4);
for (i = 0; i < variablesCount; i++)
WRITE_VAR(i, 0);
}
inter_execPtr = (char *)game_totFileData;
inter_execPtr += READ_LE_UINT32((char *)game_totFileData + 0x64);
inter_renewTimeInVars();
WRITE_VAR(13, useMouse);
WRITE_VAR(14, soundFlags);
WRITE_VAR(15, videoMode);
WRITE_VAR(16, language);
inter_callSub(2);
if (game_totToLoad[0] != 0)
inter_terminate = 0;
variablesCount = READ_LE_UINT32((char *)game_totFileData + 0x2c);
draw_blitInvalidated();
free(game_totFileData);
game_totFileData = 0;
if (needTextFree)
free(game_totTextData);
game_totTextData = 0;
if (needFreeResTable)
free(game_totResourceTable);
game_totResourceTable = 0;
free(game_imFileData);
game_imFileData = 0;
free(game_extTable);
game_extTable = 0;
if (game_extHandle >= 0)
data_closeData(game_extHandle);
game_extHandle = -1;
for (i = 0; i < *scen_pCaptureCounter; i++)
game_capturePop(0);
mult_checkFreeMult();
mult_freeAll();
for (i = 0; i < 20; i++) {
if (draw_spritesArray[i] != 0)
vid_freeSurfDesc(draw_spritesArray[i]);
draw_spritesArray[i] = 0;
}
snd_stopSound(0);
for (i = 0; i < 20; i++)
game_freeSoundSlot(i);
if (game_totToLoad[0] == 0)
break;
strcpy(game_curTotFile, game_totToLoad);
}
}
strcpy(game_curTotFile, savedTotName);
inter_nestLevel = oldNestLevel;
inter_breakFromLevel = oldBreakFrom;
scen_pCaptureCounter = oldCaptureCounter;
inter_execPtr = savedIP;
}
void game_start(void) {
game_collisionAreas = (Game_Collision *)malloc(250 * sizeof(Game_Collision));
game_prepareStart();
game_playTot(0);
free(game_collisionAreas);
vid_freeSurfDesc(draw_cursorSprites);
vid_freeSurfDesc(draw_cursorBack);
vid_freeSurfDesc(draw_backSurface);
}
} // End of namespace Gob