Implemented (currently still endian-unsafe) save/load

svn-id: r24745
This commit is contained in:
Sven Hesse 2006-11-19 17:52:52 +00:00
parent 55da3104cc
commit 2454f78589
10 changed files with 948 additions and 273 deletions

View File

@ -544,4 +544,12 @@ void Draw::printTextCentered(int16 arg_0, int16 left, int16 top, int16 right,
spriteOperation(DRAW_PRINTTEXT);
}
int32 Draw::getSpriteRectSize(int16 index) {
if (_spritesArray[index] == 0)
return 0;
return _vm->_video->getRectSize(_spritesArray[index]->width, _spritesArray[index]->height,
0, _vm->_global->_videoMode);
}
} // End of namespace Gob

View File

@ -135,6 +135,7 @@ public:
int16 transp, Video::SurfaceDesc *dest, Video::FontDesc *font);
void printTextCentered(int16 arg_0, int16 left, int16 top, int16 right,
int16 bottom, char *str, int16 fontIndex, int16 color);
int32 getSpriteRectSize(int16 index);
virtual void initBigSprite(int16 index, int16 width, int16 height, int16 flags) = 0;
virtual void printText(void) = 0;

View File

@ -363,239 +363,6 @@ void Game::freeSoundSlot(int16 slot) {
}
}
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;
Video::FontDesc *pFont;
char curSym;
int16 key;
const char *str1;
const char *str2;
int16 i;
uint32 pos;
int16 flag;
int16 savedKey;
if (_handleMouse != 0 &&
(_vm->_global->_useMouse != 0 || _forceHandleMouse != 0))
handleMouse = 1;
else
handleMouse = 0;
pos = strlen(str);
pFont = _vm->_draw->_fonts[fontIndex];
editSize = width / pFont->itemWidth;
while (1) {
strcpy(_tempStr, str);
strcat(_tempStr, " ");
if (strlen(_tempStr) > editSize)
strcpy(_tempStr, str);
_vm->_draw->_destSpriteX = xPos;
_vm->_draw->_destSpriteY = yPos;
_vm->_draw->_spriteRight = editSize * pFont->itemWidth;
_vm->_draw->_spriteBottom = height;
_vm->_draw->_destSurface = 21;
_vm->_draw->_backColor = backColor;
_vm->_draw->_frontColor = frontColor;
_vm->_draw->_textToPrint = _tempStr;
_vm->_draw->_transparency = 1;
_vm->_draw->_fontIndex = fontIndex;
_vm->_draw->spriteOperation(DRAW_FILLRECT);
_vm->_draw->_destSpriteY = yPos + (height - 8) / 2;
_vm->_draw->spriteOperation(DRAW_PRINTTEXT);
if (pos == editSize)
pos--;
curSym = _tempStr[pos];
flag = 1;
while (1) {
_tempStr[0] = curSym;
_tempStr[1] = 0;
_vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
_vm->_draw->_destSpriteY = yPos + height - 1;
_vm->_draw->_spriteRight = pFont->itemWidth;
_vm->_draw->_spriteBottom = 1;
_vm->_draw->_destSurface = 21;
_vm->_draw->_backColor = frontColor;
_vm->_draw->spriteOperation(DRAW_FILLRECT);
if (flag != 0) {
key = checkCollisions(handleMouse, -1,
&_activeCollResId,
&_activeCollIndex);
}
flag = 0;
key = checkCollisions(handleMouse, -300,
&_activeCollResId, &_activeCollIndex);
if (*pTotTime > 0) {
*pTotTime -= 300;
if (*pTotTime <= 1) {
key = 0;
_activeCollResId = 0;
break;
}
}
_tempStr[0] = curSym;
_tempStr[1] = 0;
_vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
_vm->_draw->_destSpriteY = yPos + height - 1;
_vm->_draw->_spriteRight = pFont->itemWidth;
_vm->_draw->_spriteBottom = 1;
_vm->_draw->_destSurface = 21;
_vm->_draw->_backColor = backColor;
_vm->_draw->_frontColor = frontColor;
_vm->_draw->_textToPrint = _tempStr;
_vm->_draw->_transparency = 1;
_vm->_draw->spriteOperation(DRAW_FILLRECT);
_vm->_draw->_destSpriteY = yPos + (height - 8) / 2;
_vm->_draw->spriteOperation(DRAW_PRINTTEXT);
if (key != 0 || _activeCollResId != 0)
break;
key = checkCollisions(handleMouse, -300,
&_activeCollResId, &_activeCollIndex);
if (*pTotTime > 0) {
*pTotTime -= 300;
if (*pTotTime <= 1) {
key = 0;
_activeCollResId = 0;
break;
}
}
if (key != 0 || _activeCollResId != 0)
break;
if (_vm->_inter->_terminate)
return 0;
}
if (key == 0 || _activeCollResId != 0 || _vm->_inter->_terminate)
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) {
_vm->_util->cutFromStr(str, pos - 1, 1);
pos--;
continue;
}
case 0x5300: // Del
if (pos >= strlen(str))
continue;
_vm->_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 (_vm->_global->_useMouse != 0)
continue;
_forceHandleMouse = !_forceHandleMouse;
if (_handleMouse != 0 &&
(_vm->_global->_useMouse != 0 || _forceHandleMouse != 0))
handleMouse = 1;
else
handleMouse = 0;
if (_vm->_global->_pressedKeys[1] == 0)
continue;
while (_vm->_global->_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))
_vm->_util->cutFromStr(str, strlen(str) - 1,
1);
if (key >= 'a' && key <= 'z')
key += ('A' - 'a');
pos++;
_tempStr[0] = key;
_tempStr[1] = 0;
_vm->_util->insertStr(_tempStr, str, pos - 1);
//strupr(str);
}
}
}
}
int16 Game::adjustKey(int16 key) {
if (key <= 0x60 || key >= 0x7b)
return key;
@ -987,7 +754,6 @@ void Game::sub_ADD2(void) {
_vm->_video->clearSurf(_vm->_draw->_backSurface);
_vm->_draw->initBigSprite(23, 32, 16, 2);
// TODO: That assignment is not in the original assembly, why?
_vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[23];
_vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack;
_vm->_draw->_scummvmCursor =

View File

@ -195,8 +195,6 @@ public:
void freeCollision(int16 id);
void loadSound(int16 slot, char *dataPtr);
int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 backColor,
int16 frontColor, char *str, int16 fontIndex, char inpType, int16 *pTotTime);
int16 adjustKey(int16 key);
void loadTotFile(char *path);
void loadExtTable(void);
@ -226,6 +224,9 @@ public:
virtual void collisionsBlock(void) = 0;
virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos,
InputDesc *inpDesc, int16 *collResId, int16 *collIndex) = 0;
virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
int16 backColor, int16 frontColor, char *str, int16 fontIndex,
char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex) = 0;
virtual int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons,
char handleMouse) = 0;
virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId,
@ -290,6 +291,9 @@ public:
virtual void collisionsBlock(void);
virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos,
InputDesc *inpDesc, int16 *collResId, int16 *collIndex);
virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
int16 backColor, int16 frontColor, char *str, int16 fontIndex,
char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex);
virtual int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons,
char handleMouse);
virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId,
@ -314,6 +318,9 @@ public:
virtual void collisionsBlock(void);
virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos,
InputDesc *inpDesc, int16 *collResId, int16 *collIndex);
virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
int16 backColor, int16 frontColor, char *str, int16 fontIndex,
char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex);
virtual int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons,
char handleMouse);
virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId,

View File

@ -852,7 +852,7 @@ void Game_v1::collisionsBlock(void) {
if (var_22 != 0) {
key =
multiEdit(deltaTime, index, &curEditIndex,
descArray, 0, 0);
descArray, &_activeCollResId, &_activeCollIndex);
if (key == 0x1c0d) {
for (i = 0; i < 250; i++) {
@ -1233,22 +1233,20 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
collArea->bottom - collArea->top + 1,
inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor,
_vm->_global->_inter_variables + collArea->key,
inpDesc[*pCurPos].fontIndex, collArea->flags, &time);
inpDesc[*pCurPos].fontIndex, collArea->flags, &time, collResId, collIndex);
if (_vm->_inter->_terminate)
return 0;
switch (key) {
case 0:
if (_activeCollResId == 0)
if (*collResId == 0)
return 0;
if ((_collisionAreas[_activeCollIndex].
flags & 0x0f) < 3)
if ((_collisionAreas[*collIndex].flags & 0x0f) < 3)
return 0;
if ((_collisionAreas[_activeCollIndex].
flags & 0x0f) > 10)
if ((_collisionAreas[*collIndex].flags & 0x0f) > 10)
return 0;
*pCurPos = 0;
@ -1267,7 +1265,7 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
if ((collArea->flags & 0x0f) > 10)
continue;
if (i == _activeCollIndex)
if (i == *collIndex)
break;
pCurPos[0]++;
@ -1312,6 +1310,236 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
}
}
int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
int16 backColor, int16 frontColor, char *str, int16 fontIndex,
char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex) {
int16 handleMouse;
uint32 editSize;
Video::FontDesc *pFont;
char curSym;
int16 key;
const char *str1;
const char *str2;
int16 i;
uint32 pos;
int16 flag;
int16 savedKey;
if (_handleMouse != 0 &&
(_vm->_global->_useMouse != 0 || _forceHandleMouse != 0))
handleMouse = 1;
else
handleMouse = 0;
pos = strlen(str);
pFont = _vm->_draw->_fonts[fontIndex];
editSize = width / pFont->itemWidth;
while (1) {
strcpy(_tempStr, str);
strcat(_tempStr, " ");
if (strlen(_tempStr) > editSize)
strcpy(_tempStr, str);
_vm->_draw->_destSpriteX = xPos;
_vm->_draw->_destSpriteY = yPos;
_vm->_draw->_spriteRight = editSize * pFont->itemWidth;
_vm->_draw->_spriteBottom = height;
_vm->_draw->_destSurface = 21;
_vm->_draw->_backColor = backColor;
_vm->_draw->_frontColor = frontColor;
_vm->_draw->_textToPrint = _tempStr;
_vm->_draw->_transparency = 1;
_vm->_draw->_fontIndex = fontIndex;
_vm->_draw->spriteOperation(DRAW_FILLRECT);
_vm->_draw->_destSpriteY = yPos + (height - 8) / 2;
_vm->_draw->spriteOperation(DRAW_PRINTTEXT);
if (pos == editSize)
pos--;
curSym = _tempStr[pos];
flag = 1;
while (1) {
_tempStr[0] = curSym;
_tempStr[1] = 0;
_vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
_vm->_draw->_destSpriteY = yPos + height - 1;
_vm->_draw->_spriteRight = pFont->itemWidth;
_vm->_draw->_spriteBottom = 1;
_vm->_draw->_destSurface = 21;
_vm->_draw->_backColor = frontColor;
_vm->_draw->spriteOperation(DRAW_FILLRECT);
if (flag != 0) {
key = checkCollisions(handleMouse, -1, collResId, collIndex);
}
flag = 0;
key = checkCollisions(handleMouse, -300, collResId, collIndex);
if (*pTotTime > 0) {
*pTotTime -= 300;
if (*pTotTime <= 1) {
key = 0;
*collResId = 0;
break;
}
}
_tempStr[0] = curSym;
_tempStr[1] = 0;
_vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
_vm->_draw->_destSpriteY = yPos + height - 1;
_vm->_draw->_spriteRight = pFont->itemWidth;
_vm->_draw->_spriteBottom = 1;
_vm->_draw->_destSurface = 21;
_vm->_draw->_backColor = backColor;
_vm->_draw->_frontColor = frontColor;
_vm->_draw->_textToPrint = _tempStr;
_vm->_draw->_transparency = 1;
_vm->_draw->spriteOperation(DRAW_FILLRECT);
_vm->_draw->_destSpriteY = yPos + (height - 8) / 2;
_vm->_draw->spriteOperation(DRAW_PRINTTEXT);
if (key != 0 || *collResId != 0)
break;
key = checkCollisions(handleMouse, -300, collResId, collIndex);
if (*pTotTime > 0) {
*pTotTime -= 300;
if (*pTotTime <= 1) {
key = 0;
*collResId = 0;
break;
}
}
if (key != 0 || *collResId != 0)
break;
if (_vm->_inter->_terminate)
return 0;
}
if (key == 0 || *collResId != 0 || _vm->_inter->_terminate)
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) {
_vm->_util->cutFromStr(str, pos - 1, 1);
pos--;
continue;
}
case 0x5300: // Del
if (pos >= strlen(str))
continue;
_vm->_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 (_vm->_global->_useMouse != 0)
continue;
_forceHandleMouse = !_forceHandleMouse;
if (_handleMouse != 0 &&
(_vm->_global->_useMouse != 0 || _forceHandleMouse != 0))
handleMouse = 1;
else
handleMouse = 0;
if (_vm->_global->_pressedKeys[1] == 0)
continue;
while (_vm->_global->_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))
_vm->_util->cutFromStr(str, strlen(str) - 1,
1);
if (key >= 'a' && key <= 'z')
key += ('A' - 'a');
pos++;
_tempStr[0] = key;
_tempStr[1] = 0;
_vm->_util->insertStr(_tempStr, str, pos - 1);
//strupr(str);
}
}
}
}
int16 Game_v1::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) {
Collision *ptr;
int16 i;

View File

@ -89,7 +89,7 @@ void Game_v2::playTot(int16 skipPlay) {
_vm->_mult->initAll();
_vm->_mult->zeroMultData();
for (i = 0; i < 20; i++)
for (i = 0; i < 50; i++)
_vm->_draw->_spritesArray[i] = 0;
_vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface;
@ -1223,13 +1223,13 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
if (collArea->left == -1)
continue;
if ((collArea->id & 0xC000) == 0x8000)
if ((collArea->id & 0xC000) != 0x8000)
continue;
if ((collArea->flags & 0x0f) < 3)
if ((collArea->flags & 0x0F) < 3)
continue;
if ((collArea->flags & 0x0f) > 10)
if ((collArea->flags & 0x0F) > 10)
continue;
strcpy(_tempStr, _vm->_global->_inter_variables + collArea->key);
@ -1251,12 +1251,10 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
w2E8E2Bak = _vm->_draw->_word_2E8E2;
_vm->_draw->_word_2E8E2 = 2;
_vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData = 0;
_vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
_vm->_draw->_destSpriteY += ((collArea->bottom - collArea->top + 1) -
_vm->_draw->_fonts[_vm->_draw->_fontIndex]->itemHeight) / 2;
_vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
_vm->_draw->_word_2E8E2 = w2E8E2Bak;
@ -1278,13 +1276,13 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
if (collArea->left == -1)
continue;
if ((collArea->id & 0xC000) == 0x8000)
if ((collArea->id & 0xC000) != 0x8000)
continue;
if ((collArea->flags & 0x0f) < 3)
if ((collArea->flags & 0x0F) < 3)
continue;
if ((collArea->flags & 0x0f) > 10)
if ((collArea->flags & 0x0F) > 10)
continue;
if (descInd == *pCurPos) {
@ -1304,7 +1302,7 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
collArea->bottom - collArea->top + 1,
inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor,
_vm->_global->_inter_variables + collArea->key,
inpDesc[*pCurPos].fontIndex, collArea->flags, &time);
inpDesc[*pCurPos].fontIndex, collArea->flags, &time, collResId, collIndex);
if (_vm->_inter->_terminate)
return 0;
@ -1314,10 +1312,38 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
if (*collResId == 0)
return 0;
if ((_collisionAreas[*collIndex].flags & 0x0f) < 3)
if (_mouseButtons != 0) {
for (collArea = _collisionAreas, i = 0; collArea->left != -1; collArea++, i++)
{
if ((collArea->flags & 0xF00))
continue;
if ((collArea->id & 0x4000))
continue;
if ((collArea->left > _vm->_global->_inter_mouseX) ||
(collArea->right < _vm->_global->_inter_mouseX) ||
(collArea->top > _vm->_global->_inter_mouseY) ||
(collArea->bottom < _vm->_global->_inter_mouseY));
continue;
if ((collArea->id & 0xF000))
continue;
if ((collArea->flags & 0x0F) < 3)
continue;
if ((collArea->flags & 0x0F) > 10)
continue;
*collIndex = i;
}
}
if ((_collisionAreas[*collIndex].flags & 0x0F) < 3)
return 0;
if ((_collisionAreas[*collIndex].flags & 0x0f) > 10)
if ((_collisionAreas[*collIndex].flags & 0x0F) > 10)
return 0;
*pCurPos = 0;
@ -1327,18 +1353,16 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
if (collArea->left == -1)
continue;
if ((collArea->id & 0xC000) == 0x8000)
if ((collArea->id & 0xC000) != 0x8000)
continue;
if ((collArea->flags & 0x0f) < 3)
if ((collArea->flags & 0x0F) < 3)
continue;
if ((collArea->flags & 0x0f) > 10)
if ((collArea->flags & 0x0F) > 10)
continue;
if (i == *collIndex)
break;
if (i != *collIndex)
pCurPos[0]++;
}
break;
@ -1381,6 +1405,251 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
}
}
int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
int16 backColor, int16 frontColor, char *str, int16 fontIndex,
char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex) {
int16 handleMouse;
uint32 editSize;
Video::FontDesc *pFont;
char curSym;
int16 key;
const char *str1;
const char *str2;
int16 i;
uint32 pos;
int16 flag;
int16 savedKey;
void *fontExtraBak;
int16 w2E8E2Bak;
if ((_handleMouse != 0) &&
((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0)))
handleMouse = 1;
else
handleMouse = 0;
pos = strlen(str);
pFont = _vm->_draw->_fonts[fontIndex];
editSize = width / pFont->itemWidth;
while (1) {
strcpy(_tempStr, str);
strcat(_tempStr, " ");
if (strlen(_tempStr) > editSize)
strcpy(_tempStr, str);
fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
w2E8E2Bak = _vm->_draw->_word_2E8E2;
_vm->_draw->_word_2E8E2 = 2;
_vm->_draw->_fonts[fontIndex]->extraData = 0;
_vm->_draw->_destSpriteX = xPos;
_vm->_draw->_destSpriteY = yPos;
_vm->_draw->_spriteRight = editSize * pFont->itemWidth;
_vm->_draw->_spriteBottom = height;
_vm->_draw->_destSurface = 21;
_vm->_draw->_backColor = backColor;
_vm->_draw->_frontColor = frontColor;
_vm->_draw->_textToPrint = _tempStr;
_vm->_draw->_transparency = 1;
_vm->_draw->_fontIndex = fontIndex;
_vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10 );
_vm->_draw->_destSpriteY = yPos + (height - pFont->itemHeight) / 2;
_vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
_vm->_draw->_word_2E8E2 = w2E8E2Bak;
_vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak;
if (pos == editSize)
pos--;
curSym = _tempStr[pos];
flag = 1;
if (_vm->_global->_inter_variables != 0)
WRITE_VAR(56, pos);
while (1) {
fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
w2E8E2Bak = _vm->_draw->_word_2E8E2;
_vm->_draw->_word_2E8E2 = 2;
_vm->_draw->_fonts[fontIndex]->extraData = 0;
_tempStr[0] = curSym;
_tempStr[1] = 0;
_vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
_vm->_draw->_destSpriteY = yPos + height - 1;
_vm->_draw->_spriteRight = pFont->itemWidth;
_vm->_draw->_spriteBottom = 1;
_vm->_draw->_destSurface = 21;
_vm->_draw->_backColor = frontColor;
_vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
_vm->_draw->_word_2E8E2 = w2E8E2Bak;
_vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak;
if (flag != 0) {
key = checkCollisions(handleMouse, -1, collResId, collIndex);
if (key == 0)
key = checkCollisions(handleMouse, -300, collResId, collIndex);
flag = 0;
} else
key = checkCollisions(handleMouse, -300, collResId, collIndex);
fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
w2E8E2Bak = _vm->_draw->_word_2E8E2;
_vm->_draw->_word_2E8E2 = 2;
_vm->_draw->_fonts[fontIndex]->extraData = 0;
_tempStr[0] = curSym;
_tempStr[1] = 0;
_vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
_vm->_draw->_destSpriteY = yPos + height - 1;
_vm->_draw->_spriteRight = pFont->itemWidth;
_vm->_draw->_spriteBottom = 1;
_vm->_draw->_destSurface = 21;
_vm->_draw->_backColor = backColor;
_vm->_draw->_frontColor = frontColor;
_vm->_draw->_textToPrint = _tempStr;
_vm->_draw->_transparency = 1;
_vm->_draw->_fontIndex = fontIndex;
_vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
_vm->_draw->_destSpriteY = yPos + (height - pFont->itemHeight) / 2;
_vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
_vm->_draw->_word_2E8E2 = w2E8E2Bak;
_vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak;
if (key != 0 || *collResId != 0)
break;
key = checkCollisions(handleMouse, -300, collResId, collIndex);
if ((key != 0) || (*collResId != 0) || _vm->_inter->_terminate || _vm->_quitRequested)
break;
if (*pTotTime > 0) {
*pTotTime -= 600;
if (*pTotTime <= 1) {
key = 0;
*collResId = 0;
break;
}
}
}
if ((key == 0) || (*collResId != 0) || _vm->_inter->_terminate || _vm->_quitRequested)
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) {
_vm->_util->cutFromStr(str, pos - 1, 1);
pos--;
continue;
}
case 0x5300: // Del
if (pos >= strlen(str))
continue;
_vm->_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 (_vm->_global->_useMouse != 0)
continue;
_forceHandleMouse = !_forceHandleMouse;
if (_handleMouse != 0 &&
(_vm->_global->_useMouse != 0 || _forceHandleMouse != 0))
handleMouse = 1;
else
handleMouse = 0;
while (_vm->_global->_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) &&
((_vm->_global->_pressedKeys[42] != 0) || (_vm->_global->_pressedKeys[56] != 0)))
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))
_vm->_util->cutFromStr(str, strlen(str) - 1, 1);
/* if (key >= 'a' && key <= 'z')
key += ('A' - 'a');*/
pos++;
_tempStr[0] = key;
_tempStr[1] = 0;
_vm->_util->insertStr(_tempStr, str, pos - 1);
//strupr(str);
}
}
}
}
int16 Game_v2::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) {
Collision *ptr;
int16 i;

View File

@ -20,6 +20,7 @@
*
*/
#include "common/stdafx.h"
#include "common/endian.h"
#include "base/plugins.h"
#include "common/config-manager.h"
@ -168,6 +169,14 @@ GobEngine::GobEngine(OSystem * syst, uint32 features, Common::Language lang,
strcat(_startTot0, "0.tot");
}
int i;
_saveFiles = new char*[3];
for (i = 0; i < 3; i++)
_saveFiles[i] = new char[_targetName.size() + 5];
sprintf(_saveFiles[0], "%s.cat", _targetName.c_str());
sprintf(_saveFiles[1], "%s.sav", _targetName.c_str());
sprintf(_saveFiles[2], "%s.blo", _targetName.c_str());
Common::addSpecialDebugLevel(DEBUG_FUNCOP, "FuncOpcodes", "Script FuncOpcodes debug level");
Common::addSpecialDebugLevel(DEBUG_DRAWOP, "DrawOpcodes", "Script DrawOpcodes debug level");
Common::addSpecialDebugLevel(DEBUG_GOBOP, "GoblinOpcodes", "Script GoblinOpcodes debug level");
@ -202,6 +211,11 @@ GobEngine::~GobEngine() {
delete _music;
delete[] _startTot;
delete[] _startTot0;
int i;
for (i = 0; i < 3; i++)
delete[] _saveFiles[i];
delete[] _saveFiles;
}
int GobEngine::go() {
@ -219,6 +233,218 @@ void GobEngine::writeVarDebug(uint32 offs, uint32 v) {
(*(uint32 *)(_global->_inter_variables + (offs))) = v;
}
// Seeking with SEEK_END (and therefore also pos()) doesn't work with
// gzip'd save files, so reading the whole thing in is necessary
uint32 GobEngine::getSaveSize(Common::InSaveFile &in) {
char buf[1024];
uint32 size;
uint32 i;
uint32 pos;
size = 0;
pos = in.pos();
in.seek(0, SEEK_SET);
while ((i = in.read(buf, 1024)) > 0)
size += i;
in.seek(0, pos);
return size;
}
int32 GobEngine::getSaveSize(enum SaveFiles sFile) {
int32 size;
Common::InSaveFile *in;
if ((in = _saveFileMan->openForLoading(_saveFiles[(int) sFile]))) {
size = getSaveSize(*in);
delete in;
} else
size = -1;
debugC(1, DEBUG_FILEIO, "Requested size of file \"%s\": %d", _saveFiles[(int) sFile], size);
return size;
}
void GobEngine::saveGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset) {
int32 retSize;
int16 index;
int16 top;
bool writePal;
char *sName;
char *buf;
char *oBuf;
int32 iSize;
int32 oSize;
int32 oOff;
Video::SurfaceDesc *destDesc;
Video::SurfaceDesc *srcDesc;
Common::InSaveFile *in;
Common::OutSaveFile *out;
index = 0;
oBuf = 0;
in = 0;
writePal = false;
sName = _saveFiles[(int) sFile];
// WRITE_VAR(1, 1)
*((uint32*)(_global->_inter_variables + 4)) = 1;
if (size < 0) {
if (size < -1000) {
writePal = true;
size += 1000;
}
index = -size - 1;
assert((index >= 0) && (index < 50)); // Just to be sure...
buf = (char *) _draw->_spritesArray[index]->vidPtr;
size = _draw->getSpriteRectSize(index);
if ((_draw->_spritesArray[index]->vidMode & 0x80) == 0)
size = -size;
} else if (size == 0) {
dataVar = 0;
size = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
buf = _global->_inter_variables;
} else
buf = _global->_inter_variables + dataVar;
if ((in = _saveFileMan->openForLoading(sName)))
iSize = getSaveSize(*in);
else
iSize = 0;
oOff = offset < 0 ? MAX(0, iSize - (-offset - 1)) : offset;
oSize = MAX(iSize, oOff + ABS(size));
oBuf = new char[oSize];
memset(oBuf, 0, oSize);
if (in) {
in->read(oBuf, iSize);
delete in;
}
if(!(out = _saveFileMan->openForSaving(sName))) {
warning("Can't write file \"%s\"", sName);
delete[] oBuf;
return;
}
if (writePal) {
memcpy(oBuf + oOff, (char *) _global->_pPaletteDesc->vgaPal, 768);
oOff += 768;
}
if (size < 0) {
srcDesc = _draw->_spritesArray[index];
destDesc = _video->initSurfDesc(_global->_videoMode, srcDesc->width, 25, 0);
for (top = 0, retSize = 0; top < srcDesc->height; top += 25) {
int16 height = MIN(25, srcDesc->height - top);
_video->drawSprite(srcDesc, destDesc, 0, top, srcDesc->width - 1,
top + height - 1, 0, 0, 0);
memcpy(oBuf + oOff, (char *) destDesc->vidPtr, srcDesc->width * 25);
oOff += srcDesc->width * 25;
}
_video->freeSurfDesc(destDesc);
} else
memcpy(oBuf + oOff, buf, size);
out->write(oBuf, oSize);
out->flush();
if (out->ioFailed())
warning("Can't write file \"%s\"", sName);
else {
debugC(1, DEBUG_FILEIO, "Saved file \"%s\" (%d, %d bytes at %d)",
sName, dataVar, size, offset);
// WRITE_VAR(1, 0)
*((uint32*)(_global->_inter_variables + 4)) = 0;
}
delete out;
delete[] oBuf;
}
void GobEngine::loadGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset) {
int32 sSize;
int32 retSize;
int16 index;
int16 y;
char *buf;
char *sName;
bool readPal;
Video::SurfaceDesc *destDesc;
Video::SurfaceDesc *srcDesc;
Common::InSaveFile *in;
readPal = false;
sName = _saveFiles[(int) sFile];
if (size < 0) {
if (size < -1000) {
readPal = true;
size += 1000;
}
index = -size - 1;
assert((index >= 0) && (index < 50)); // Just to be sure...
buf = (char *) _draw->_spritesArray[index]->vidPtr;
size = _draw->getSpriteRectSize(index);
if ((_draw->_spritesArray[index]->vidMode & 0x80) == 0)
size = -size;
} else if (size == 0) {
dataVar = 0;
size = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
buf = _global->_inter_variables;
} else
buf = _global->_inter_variables + dataVar;
if (_global->_inter_resStr[0] == 0) {
if (readPal)
size += 768;
// WRITE_VAR(1, size)
*((uint32*)(_global->_inter_variables + 4)) = (uint32) size;
return;
}
// WRITE_VAR(1, 1)
*((uint32*)(_global->_inter_variables + 4)) = 1;
if(!(in = _saveFileMan->openForLoading(sName)))
return;
debugC(1, DEBUG_FILEIO, "Loading file \"%s\" (%d, %d bytes at %d)",
sName, dataVar, size, offset);
sSize = getSaveSize(*in);
_draw->animateCursor(4);
if (offset < 0)
in->seek(sSize - (-offset - 1), 0);
else
in->seek(offset, 0);
if (readPal) {
retSize = in->read((char *) _global->_pPaletteDesc->vgaPal, 768);
_draw->_applyPal = 1;
}
if (size < 0) {
destDesc = _draw->_spritesArray[index];
srcDesc = _video->initSurfDesc(_global->_videoMode, destDesc->width, 25, 0);
for (y = 0, retSize = 0; y < destDesc->height; y += 25) {
int16 height = MIN(25, destDesc->height - y);
retSize += in->read((char *) srcDesc->vidPtr, destDesc->width * 25);
_video->drawSprite(srcDesc, destDesc, 0, 0, destDesc->width - 1, height - 1, 0, y, 0);
}
_video->freeSurfDesc(srcDesc);
} else
retSize = in->read(buf, size);
if (retSize == size)
// WRITE_VAR(1, 0)
*((uint32*)(_global->_inter_variables + 4)) = 0;
delete in;
return;
}
int GobEngine::init() {
_snd = new Snd(this);
_global = new Global(this);

View File

@ -25,6 +25,7 @@
#include "common/stdafx.h"
#include "common/system.h"
#include "common/savefile.h"
#include "engines/engine.h"
@ -81,6 +82,12 @@ enum {
DEBUG_COLLISIONS = 1 << 8
};
enum SaveFiles {
SAVE_CAT = 0,
SAVE_SAV,
SAVE_BLO
};
class GobEngine : public Engine {
protected:
int go();
@ -98,6 +105,7 @@ public:
Common::Language _language;
char *_startTot;
char *_startTot0;
char **_saveFiles;
bool _copyProtection;
bool _quitRequested;
@ -123,6 +131,10 @@ public:
Music *_music;
void writeVarDebug(uint32 offs, uint32 v);
inline uint32 getSaveSize(Common::InSaveFile &in);
int32 getSaveSize(enum SaveFiles sFile);
void saveGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset);
void loadGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset);
};
} // End of namespace Gob

View File

@ -318,6 +318,9 @@ protected:
void o2_stub0x80(void);
void o2_stub0x82(void);
void o2_stub0x85(void);
bool o2_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag);
bool o2_readData(char &cmdCount, int16 &counter, int16 &retFlag);
bool o2_writeData(char &cmdCount, int16 &counter, int16 &retFlag);
bool o2_checkData(char &cmdCount, int16 &counter, int16 &retFlag);
bool o2_stopSound(char &cmdCount, int16 &counter, int16 &retFlag);
bool o2_createSprite(char &cmdCount, int16 &counter, int16 &retFlag);

View File

@ -525,7 +525,7 @@ void Inter_v2::setupOpcodes(void) {
/* 3C */
OPCODE(o1_waitEndPlay),
OPCODE(o1_playComposition),
OPCODE(o1_getFreeMem),
OPCODE(o2_getFreeMem),
OPCODE(o2_checkData),
/* 40 */
{NULL, ""},
@ -544,8 +544,8 @@ void Inter_v2::setupOpcodes(void) {
OPCODE(o1_loadFont),
/* 4C */
OPCODE(o1_freeFont),
OPCODE(o1_readData),
OPCODE(o1_writeData),
OPCODE(o2_readData),
OPCODE(o2_writeData),
OPCODE(o1_manageDataFile),
};
@ -1271,20 +1271,175 @@ void Inter_v2::loadMult(void) {
}
}
bool Inter_v2::o2_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag) {
int16 freeVar;
int16 maxFreeVar;
freeVar = _vm->_parse->parseVarIndex();
maxFreeVar = _vm->_parse->parseVarIndex();
// HACK
WRITE_VAR_OFFSET(freeVar, 1000000);
WRITE_VAR_OFFSET(maxFreeVar, 1000000);
WRITE_VAR(16, READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4);
return false;
}
bool Inter_v2::o2_readData(char &cmdCount, int16 &counter, int16 &retFlag) {
int32 retSize;
int32 size;
int32 offset;
int16 dataVar; // si
int16 handle;
int16 index;
int16 y;
char *buf;
bool readPal;
Video::SurfaceDesc *destDesc;
Video::SurfaceDesc *srcDesc;
readPal = false;
evalExpr(0);
dataVar = _vm->_parse->parseVarIndex();
size = _vm->_parse->parseValExpr();
evalExpr(0);
offset = _vm->_global->_inter_resVal;
if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf")) {
_vm->loadGame(SAVE_CAT, dataVar, size, offset);
return false;
}
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat")) {
_vm->loadGame(SAVE_CAT, dataVar, size, offset);
return false;
}
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf")) {
_vm->loadGame(SAVE_SAV, dataVar, size, offset);
return false;
}
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf")) {
_vm->loadGame(SAVE_BLO, dataVar, size, offset);
return false;
}
if (size < 0) {
if (size < -1000) {
readPal = true;
size += 1000;
}
index = -size - 1;
assert((index >= 0) && (index < 50)); // Just to be sure...
buf = (char *) _vm->_draw->_spritesArray[index]->vidPtr;
size = _vm->_draw->getSpriteRectSize(index);
if ((_vm->_draw->_spritesArray[index]->vidMode & 0x80) == 0)
size = -size;
} else if (size == 0) {
dataVar = 0;
size = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
buf = _vm->_global->_inter_variables;
} else
buf = _vm->_global->_inter_variables + dataVar;
if (_vm->_global->_inter_resStr[0] == 0) {
if (readPal)
size += 768;
WRITE_VAR(1, size);
return false;
}
WRITE_VAR(1, 1);
handle = _vm->_dataio->openData(_vm->_global->_inter_resStr);
if (handle < 0)
return false;
_vm->_draw->animateCursor(4);
if (offset < 0)
_vm->_dataio->seekData(handle, -offset - 1, 2);
else
_vm->_dataio->seekData(handle, offset, 0);
if (readPal) {
retSize = _vm->_dataio->readData(handle, (char *) _vm->_global->_pPaletteDesc->vgaPal, 768);
_vm->_draw->_applyPal = 1;
}
if (size < 0) {
destDesc = _vm->_draw->_spritesArray[index];
srcDesc = _vm->_video->initSurfDesc(_vm->_global->_videoMode, destDesc->width, 25, 0);
for (y = 0, retSize = 0; y < destDesc->height; y += 25) {
int16 height = MIN(25, destDesc->height - y);
retSize += _vm->_dataio->readData(handle, (char *) srcDesc->vidPtr, destDesc->width * 25);
_vm->_video->drawSprite(srcDesc, destDesc, 0, 0, destDesc->width - 1, height - 1, 0, y, 0);
}
_vm->_video->freeSurfDesc(srcDesc);
} else
retSize = _vm->_dataio->readData(handle, buf, size);
if (retSize == size)
WRITE_VAR(1, 0);
_vm->_dataio->closeData(handle);
return false;
}
bool Inter_v2::o2_writeData(char &cmdCount, int16 &counter, int16 &retFlag) {
int32 offset;
int32 size;
int16 dataVar;
evalExpr(0);
dataVar = _vm->_parse->parseVarIndex();
size = _vm->_parse->parseValExpr();
evalExpr(0);
offset = _vm->_global->_inter_resVal;
if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf"))
_vm->saveGame(SAVE_CAT, dataVar, size, offset);
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat"))
_vm->saveGame(SAVE_CAT, dataVar, size, offset);
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf"))
_vm->saveGame(SAVE_SAV, dataVar, size, offset);
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf"))
_vm->saveGame(SAVE_BLO, dataVar, size, offset);
else
warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr);
return false;
}
bool Inter_v2::o2_checkData(char &cmdCount, int16 &counter, int16 &retFlag) {
int16 handle;
int16 varOff;
int32 size;
evalExpr(0);
varOff = _vm->_parse->parseVarIndex();
handle = 0;
if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf"))
size = _vm->getSaveSize(SAVE_CAT);
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat"))
size = _vm->getSaveSize(SAVE_CAT);
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf"))
size = _vm->getSaveSize(SAVE_SAV);
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf"))
size = _vm->getSaveSize(SAVE_BLO);
else {
handle = _vm->_dataio->openData(_vm->_global->_inter_resStr);
WRITE_VAR_OFFSET(varOff, handle);
if (handle >= 0) {
_vm->_dataio->closeData(handle);
WRITE_VAR(16, (uint32) _vm->_dataio->getDataSize(_vm->_global->_inter_resStr));
size = _vm->_dataio->getDataSize(_vm->_global->_inter_resStr);
} else
WRITE_VAR(16, (uint32) -1);
size = -1;
}
if (size == -1)
handle = -1;
WRITE_VAR_OFFSET(varOff, handle);
WRITE_VAR(16, (uint32) size);
return false;
}
@ -1685,7 +1840,7 @@ void Inter_v2::o2_setRenderFlags(void) {
if (expr & 0x4000)
_vm->_draw->_renderFlags &= expr & 0x3fff;
else
_vm->_draw->_renderFlags = _vm->_parse->parseValExpr();
_vm->_draw->_renderFlags = expr;
}
}