[Scummvm-cvs-logs] CVS: scummvm/sky control.cpp,1.4,1.5 control.h,1.2,1.3 grid.cpp,1.10,1.11 logic.cpp,1.104,1.105 logic.h,1.28,1.29 screen.cpp,1.32,1.33 screen.h,1.8,1.9 sky.cpp,1.65,1.66

Robert G?ffringmann lavosspawn at users.sourceforge.net
Mon Jun 30 18:30:06 CEST 2003


Update of /cvsroot/scummvm/scummvm/sky
In directory sc8-pr-cvs1:/tmp/cvs-serv16875/sky

Modified Files:
	control.cpp control.h grid.cpp logic.cpp logic.h screen.cpp 
	screen.h sky.cpp 
Log Message:
finished loading and saving, fixed grid bugs (some debugging code not yet removed), implemented fnLincTextModule

Index: control.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/control.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- control.cpp	27 Jun 2003 13:23:01 -0000	1.4
+++ control.cpp	1 Jul 2003 01:29:29 -0000	1.5
@@ -115,15 +115,17 @@
 	_system->copy_rect(_screen + _y * GAME_SCREEN_WIDTH + _x, GAME_SCREEN_WIDTH, _x, _y, cpWidth, PAN_CHAR_HEIGHT);
 }
 
-SkyControl::SkyControl(SkyScreen *screen, SkyDisk *disk, SkyMouse *mouse, SkyText *text, SkyMusicBase *music, OSystem *system, const char *savePath) {
+SkyControl::SkyControl(SkyScreen *screen, SkyDisk *disk, SkyMouse *mouse, SkyText *text, SkyMusicBase *music, SkyLogic *logic, OSystem *system, const char *savePath) {
 
 	_skyScreen = screen;
 	_skyDisk = disk;
 	_skyMouse = mouse;
 	_skyText = text;
 	_skyMusic = music;
+	_skyLogic = logic;
 	_system = system;
 	_savePath = savePath;
+	_memListRoot = NULL;
 }
 
 SkyConResource *SkyControl::createResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, int16 pX, int16 pY, uint32 pText, uint8 pOnClick, uint8 panelType) {
@@ -351,20 +353,24 @@
 			return 0;
 
 		case REST_GAME_PANEL:
+			if (SkyState::_systemVars.systemFlags & SF_CHOOSING)
+				return CANCEL_PRESSED; // can't save/restore while choosing
 			animClick(pButton);
 			return saveRestorePanel(false); // texts can't be edited
 
 		case SAVE_GAME_PANEL:
+			if (SkyState::_systemVars.systemFlags & SF_CHOOSING)
+				return CANCEL_PRESSED; // can't save/restore while choosing
 			animClick(pButton);
 			return saveRestorePanel(true); // texts can be edited
 
 		case SAVE_A_GAME:
 			animClick(pButton);
-			return GAME_SAVED;
+			return saveGameToFile();
 
 		case RESTORE_A_GAME:
 			animClick(pButton);
-			return GAME_RESTORED;
+			return restoreGameFromFile();
 
 		case SP_CANCEL:
 			animClick(pButton);
@@ -577,14 +583,15 @@
 	return SHIFTED;
 }
 
-uint16 SkyControl::saveRestorePanel(bool allowEdit) {
+uint16 SkyControl::saveRestorePanel(bool allowSave) {
 
+	_keyPressed = 0;
 	buttonControl(NULL);
 	_text->drawToScreen(WITH_MASK); // flush text restore buffer
 
 	SkyConResource **lookList;
 	uint16 cnt;
-	if (allowEdit) lookList = _savePanLookList;
+	if (allowSave) lookList = _savePanLookList;
 	else lookList = _restorePanLookList;
 
 	uint8 *saveGameTexts = (uint8*)malloc(MAX_SAVE_GAMES * MAX_TEXT_LEN);
@@ -594,15 +601,15 @@
 	_savePanel->drawToScreen(NO_MASK);
 	_quitButton->drawToScreen(NO_MASK);
 	
-	loadSaveDescriptions(saveGameTexts);
-	uint16 selectedGame = 0;
+	loadDescriptions(saveGameTexts);
+	_selectedGame = 0;
 
 	bool quitPanel = false;
 	bool refreshNames = true;
 	uint16 clickRes = 0;
 	while (!quitPanel) {
 		if (refreshNames) {
-			setUpGameSprites(saveGameTexts, textSprites, _firstText);
+			setUpGameSprites(saveGameTexts, textSprites, _firstText, _selectedGame, allowSave);
 			showSprites(textSprites);
 			refreshNames = false;
 		}
@@ -615,6 +622,10 @@
 			_mouseClicked = false;
 			clickRes = CANCEL_PRESSED;
 			quitPanel = true;
+		} else if (allowSave && _keyPressed) {
+			handleKeyPress(_keyPressed, _selectedGame * MAX_TEXT_LEN + saveGameTexts);
+			refreshNames = true;
+			_keyPressed = 0;
 		}
 
 		bool haveButton = false;
@@ -628,11 +639,19 @@
 					
 					clickRes = handleClick(lookList[cnt]);
 
-			        if ((clickRes == CANCEL_PRESSED) || (clickRes == GAME_SAVED) || 
-						(clickRes == GAME_RESTORED) || (clickRes == NO_DISK_SPACE))
-						quitPanel = true;
-					if (clickRes == SHIFTED)
+			        if (clickRes == SHIFTED) {
+						_selectedGame = _firstText;
 						refreshNames = true;
+					}
+					if ((clickRes == CANCEL_PRESSED) || (clickRes == NO_DISK_SPACE) || 
+						(clickRes == GAME_RESTORED))
+						quitPanel = true;
+
+					if (clickRes == GAME_SAVED) {
+						saveDescriptions(saveGameTexts);
+						quitPanel = true;
+					}
+						 
 				}
 			}
 
@@ -640,7 +659,8 @@
 			if ((_mouseX >= GAME_NAME_X) && (_mouseX <= GAME_NAME_X + PAN_LINE_WIDTH) &&
 				(_mouseY >= GAME_NAME_Y) && (_mouseY <= GAME_NAME_Y + PAN_CHAR_HEIGHT * MAX_ON_SCREEN)) {
 
-					selectedGame = (_mouseY - GAME_NAME_Y) / PAN_CHAR_HEIGHT + _firstText;
+					_selectedGame = (_mouseY - GAME_NAME_Y) / PAN_CHAR_HEIGHT + _firstText;
+					refreshNames = true;
 			}
 		}
 		if (!haveButton) buttonControl(NULL);
@@ -654,14 +674,59 @@
     return clickRes;
 }
 
-void SkyControl::setUpGameSprites(uint8 *nameBuf, dataFileHeader **nameSprites, uint16 firstNum) {
+bool SkyControl::checkKeyList(uint8 key) {
+	static const uint8 charList[14] = " ,().='-&+!?\"";
+	for (uint chCnt = 0; chCnt < ARRAYSIZE(charList); chCnt++)
+		if (charList[chCnt] == key) return true;
+	return false;
+}
+
+void SkyControl::handleKeyPress(uint8 key, uint8 *textBuf) {
+
+	if (key == 8) { // backspace
+		for (uint8 cnt = 0; cnt < 6; cnt++)
+			if (!textBuf[cnt]) return;
+
+		while (textBuf[1])
+			textBuf++;
+		textBuf[0] = 0;
+	} else {
+        if (((key >= 'A') && (key <= 'Z')) || ((key >= 'a') && (key <= 'z')) ||
+			((key >= '0') && (key <= '9')) || checkKeyList(key)) {
+				uint8 strLen = 0;
+				while (textBuf[0]) {
+					textBuf++;
+					strLen++;
+				}
+				if (strLen < MAX_TEXT_LEN) {
+                    textBuf[0] = key;
+					textBuf[1] = 0;
+				}
+		}
+	}
+}
+
+void SkyControl::setUpGameSprites(uint8 *nameBuf, dataFileHeader **nameSprites, uint16 firstNum, uint16 selectedGame, bool allowSave) {
 
 	nameBuf += firstNum * MAX_TEXT_LEN;
 
 	for (uint16 cnt = 0; cnt < MAX_ON_SCREEN; cnt++) {
-		displayText_t textSpr = _skyText->displayText((char*)nameBuf, NULL, false, PAN_LINE_WIDTH, 37);
+		displayText_t textSpr;
+		if (firstNum + cnt == selectedGame) {
+			char tmpLine[MAX_TEXT_LEN + 2];
+			memcpy(tmpLine, nameBuf, MAX_TEXT_LEN);
+			if (allowSave)
+				strcat(tmpLine,"_");
+			textSpr = _skyText->displayText(tmpLine, NULL, false, PAN_LINE_WIDTH, 0);
+		} else {
+			textSpr = _skyText->displayText((char*)nameBuf, NULL, false, PAN_LINE_WIDTH, 37);
+		}
 		nameBuf += MAX_TEXT_LEN;
 		nameSprites[cnt] = (dataFileHeader*)textSpr.textData;
+		if (firstNum + cnt == selectedGame)
+			nameSprites[cnt]->flag = 1;
+		else
+			nameSprites[cnt]->flag = 0;
 	}
 }
 
@@ -671,17 +736,23 @@
 	for (uint16 cnt = 0; cnt < MAX_ON_SCREEN; cnt++) {
 		drawResource->setSprite(nameSprites[cnt]);
 		drawResource->setXY(GAME_NAME_X, GAME_NAME_Y + cnt * PAN_CHAR_HEIGHT);
-		drawResource->drawToScreen(NO_MASK);
+		if (nameSprites[cnt]->flag) { // name is highlighted
+			for (uint16 cnty = GAME_NAME_Y + cnt * PAN_CHAR_HEIGHT; cnty < GAME_NAME_Y + (cnt + 1) * PAN_CHAR_HEIGHT - 1; cnty++)
+				memset(_screenBuf + cnty * GAME_SCREEN_WIDTH + GAME_NAME_X, 37, PAN_LINE_WIDTH);
+			drawResource->drawToScreen(WITH_MASK);
+			_system->copy_rect(_screenBuf + (GAME_NAME_Y + cnt * PAN_CHAR_HEIGHT) * GAME_SCREEN_WIDTH + GAME_NAME_X, GAME_SCREEN_WIDTH, GAME_NAME_X, GAME_NAME_Y + cnt * PAN_CHAR_HEIGHT, PAN_LINE_WIDTH, PAN_CHAR_HEIGHT);
+		} else 
+			drawResource->drawToScreen(NO_MASK);
 	}
 	delete drawResource;
 }
 
-void SkyControl::loadSaveDescriptions(uint8 *destBuf) {
+void SkyControl::loadDescriptions(uint8 *destBuf) {
 
 	memset(destBuf, 0, MAX_SAVE_GAMES * MAX_TEXT_LEN);
 
 	File *inf = new File();
-	inf->open("SKY.SAV",_savePath);
+	inf->open("SKY-VM.SAV",_savePath);
 	if (inf->isOpen()) {
 		uint8 *tmpBuf = (uint8*)malloc(inf->size());
 		inf->read(tmpBuf, inf->size());
@@ -706,15 +777,42 @@
 	}
 }
 
-uint16 SkyControl::saveGameToFile(char *fName) {
+void SkyControl::saveDescriptions(uint8 *srcBuf) {
 
+	uint8 *tmpBuf = (uint8*)malloc(MAX_SAVE_GAMES * MAX_TEXT_LEN);
+	uint8 *tmpPos = tmpBuf;
+	uint8 *srcPos = srcBuf;
+	for (uint16 cnt = 0; cnt < MAX_SAVE_GAMES; cnt++) {
+		uint8 namePos = 5;
+		while (srcPos[namePos]) {
+			if (srcPos[namePos] != '_') {
+				*tmpPos = srcPos[namePos];
+				tmpPos++;
+			}
+			namePos++;
+		}
+		*tmpPos = 0;
+		tmpPos++;
+		srcPos += MAX_TEXT_LEN;
+	}
+	File *outf = new File();
+	outf->open("SKY-VM.SAV", _savePath, File::kFileWriteMode);
+	outf->write(tmpBuf, tmpPos - tmpBuf);
+	outf->close();
+	free(tmpBuf);	
+}
+
+uint16 SkyControl::saveGameToFile(void) {
+
+	char fName[20];
+	sprintf(fName,"SKY-VM.%03d", _selectedGame);
 	File *outf = new File();
 	if (!outf->open(fName, _savePath, File::kFileWriteMode)) {
 		delete outf;
 		return NO_DISK_SPACE;
 	}
 
-	uint8 *saveData = (uint8*)malloc(0x20000);
+	uint8 *saveData = (uint8*)malloc(0x50000);
 	uint32 fSize = prepareSaveData(saveData);
 
 	if (outf->write(saveData, fSize) != fSize) {
@@ -739,6 +837,23 @@
 	// anims, stands, turnTable
 }
 
+void SkyControl::stosStr(uint8 **destPos, uint16 *src, bool isGraf) {
+	uint16 strLen = 0;
+	if (isGraf) {
+		while (src[strLen] || src[strLen+2])
+			strLen++;
+		strLen += 3;
+	} else {
+		while (src[strLen])
+			strLen++;
+		strLen++;
+	}
+	STOSW(*destPos, strLen);
+	for (uint16 cnt = 0; cnt < strLen; cnt++) {
+		STOSW(*destPos, src[cnt]);
+	}
+}
+
 void SkyControl::stosCompact(uint8 **destPos, Compact *cpt) {
 	uint16 saveType = 0;
 	if (cpt->extCompact) {
@@ -747,8 +862,17 @@
 		if (cpt->extCompact->megaSet1) saveType |= SAVE_MEGA1;
 		if (cpt->extCompact->megaSet2) saveType |= SAVE_MEGA2;
 		if (cpt->extCompact->megaSet3) saveType |= SAVE_MEGA3;
+		if (cpt->extCompact->turnProg) saveType |= SAVE_TURNP;
 	}
+	if (cpt->grafixProg) saveType |= SAVE_GRAFX;
+
 	STOSW(*destPos, saveType);
+
+	if (saveType & SAVE_GRAFX)
+		stosStr(destPos, cpt->grafixProg, true);
+	if (saveType & SAVE_TURNP)
+		stosStr(destPos, cpt->extCompact->turnProg, false);
+
 	STOSW(*destPos, cpt->logic);
 	STOSW(*destPos, cpt->status);
 	STOSW(*destPos, cpt->sync);
@@ -815,21 +939,13 @@
 	}
 }
 
-void SkyControl::stosAR(uint8 **destPos, uint8 *arData) {
-
-	uint16 *data = (uint16*)arData;
-	for (uint8 cnt = 0; cnt < 32; cnt++)
-		STOSW(*destPos, TO_LE_16(data[cnt]));
-}
-
 uint32 SkyControl::prepareSaveData(uint8 *destBuf) {
 
 	uint32 cnt;
 	memset(destBuf, 0, 4); // space for data size
 	uint8 *destPos = destBuf + 4;
-	memcpy(destPos, SAVE_HEADER, sizeof(SAVE_HEADER));
-	destPos += sizeof(SAVE_HEADER);
-	//STOSD(destPos, SkyLogic::_scriptVariables[CUR_SECTION]);
+	STOSD(destPos, SAVE_FILE_REVISION);
+
 	STOSD(destPos, _skyMusic->giveCurrentMusic());
 
 	//TODO: save queued sfx
@@ -846,9 +962,6 @@
 	for (cnt = 0; cnt < ARRAYSIZE(_saveLoadCpts); cnt++)
 		stosCompact(&destPos, _saveLoadCpts[cnt]);
 
-	for (cnt = 0; cnt < ARRAYSIZE(_saveLoadARs); cnt++)
-		stosAR(&destPos, _saveLoadARs[cnt]);
-
 	for (cnt = 0; cnt < 3; cnt++)
 		STOSW(destPos, SkyCompact::park_table[cnt]);
 
@@ -861,6 +974,232 @@
 
 #undef STOSD
 #undef STOSW
+
+void SkyControl::appendMemList(uint16 *pMem) {
+	AllocedMem *newMem = new AllocedMem;
+	newMem->mem = pMem;
+	newMem->next = _memListRoot;
+	_memListRoot = newMem;
+}
+
+void SkyControl::freeMemList(void) {
+	AllocedMem *block = _memListRoot;
+	AllocedMem *temp;
+	while (block) {
+		temp = block;
+		free(block->mem);
+		block = block->next;
+		delete temp;
+	}
+	_memListRoot = NULL;
+}
+
+
+#define LODSD(strPtr, val) { val = READ_LE_UINT32(strPtr); (strPtr) += 4; }
+#define LODSW(strPtr, val) { val = READ_LE_UINT16(strPtr); (strPtr) += 2; }
+
+void SkyControl::lodsMegaSet(uint8 **srcPos, MegaSet *mega) {
+	LODSW(*srcPos, mega->gridWidth);
+	LODSW(*srcPos, mega->colOffset);
+	LODSW(*srcPos, mega->colWidth);
+	LODSW(*srcPos, mega->lastChr);
+	// anims, stands, turnTable
+}
+
+void SkyControl::lodsCompact(uint8 **srcPos, Compact *cpt) {
+
+	uint16 saveType, cnt;
+	LODSW(*srcPos, saveType);
+	if ((saveType & (SAVE_EXT | SAVE_TURNP)) && (cpt->extCompact == NULL))
+		error("Can't restore! SaveData is SAVE_EXT for Compact");
+	if ((saveType & SAVE_MEGA0) && (cpt->extCompact->megaSet0 == NULL))
+		error("Can't restore! SaveData is SAVE_MEGA0 for Compact");
+	if ((saveType & SAVE_MEGA1) && (cpt->extCompact->megaSet1 == NULL))
+		error("Can't restore! SaveData is SAVE_MEGA1 for Compact");
+	if ((saveType & SAVE_MEGA2) && (cpt->extCompact->megaSet2 == NULL))
+		error("Can't restore! SaveData is SAVE_MEGA2 for Compact");
+	if ((saveType & SAVE_MEGA3) && (cpt->extCompact->megaSet3 == NULL))
+		error("Can't restore! SaveData is SAVE_MEGA3 for Compact");
+
+	if (saveType & SAVE_GRAFX) {
+		uint16 grafxLen;
+		LODSW(*srcPos, grafxLen);
+		cpt->grafixProg = (uint16*)malloc(grafxLen << 1);
+		appendMemList(cpt->grafixProg);
+		for (cnt = 0; cnt < grafxLen; cnt++) {
+			LODSW(*srcPos, cpt->grafixProg[cnt]);
+		}
+	} else
+		cpt->grafixProg = NULL;
+
+	if (saveType & SAVE_TURNP) {
+		uint16 turnLen;
+		LODSW(*srcPos, turnLen);
+		cpt->extCompact->turnProg = (uint16*)malloc(turnLen << 1);
+		appendMemList(cpt->extCompact->turnProg);
+		for (cnt = 0; cnt < turnLen; cnt++)
+			LODSW(*srcPos, cpt->extCompact->turnProg[cnt]);
+	} else if (cpt->extCompact)
+		cpt->extCompact->turnProg = NULL;
+
+	LODSW(*srcPos, cpt->logic);
+	LODSW(*srcPos, cpt->status);
+	LODSW(*srcPos, cpt->sync);
+	LODSW(*srcPos, cpt->screen);
+	LODSW(*srcPos, cpt->place);
+	// getToTable
+	LODSW(*srcPos, cpt->xcood);
+	LODSW(*srcPos, cpt->ycood);
+	LODSW(*srcPos, cpt->frame);
+	LODSW(*srcPos, cpt->cursorText);
+	LODSW(*srcPos, cpt->mouseOn);
+	LODSW(*srcPos, cpt->mouseOff);
+	LODSW(*srcPos, cpt->mouseClick);
+	LODSW(*srcPos, cpt->mouseRelX);
+	LODSW(*srcPos, cpt->mouseRelY);
+	LODSW(*srcPos, cpt->mouseSizeX);
+	LODSW(*srcPos, cpt->mouseSizeY);
+	LODSW(*srcPos, cpt->actionScript);
+	LODSW(*srcPos, cpt->upFlag);
+	LODSW(*srcPos, cpt->downFlag);
+	LODSW(*srcPos, cpt->getToFlag);
+	LODSW(*srcPos, cpt->flag);
+	LODSW(*srcPos, cpt->mood);
+	// grafixProg
+	LODSW(*srcPos, cpt->offset);
+	LODSW(*srcPos, cpt->mode);
+	LODSW(*srcPos, cpt->baseSub);
+	LODSW(*srcPos, cpt->baseSub_off);
+	if (saveType & SAVE_EXT) {
+		LODSW(*srcPos, cpt->extCompact->actionSub);
+		LODSW(*srcPos, cpt->extCompact->actionSub_off);
+		LODSW(*srcPos, cpt->extCompact->getToSub);
+		LODSW(*srcPos, cpt->extCompact->getToSub_off);
+		LODSW(*srcPos, cpt->extCompact->extraSub);
+		LODSW(*srcPos, cpt->extCompact->extraSub_off);
+		LODSW(*srcPos, cpt->extCompact->dir);
+		LODSW(*srcPos, cpt->extCompact->stopScript);
+		LODSW(*srcPos, cpt->extCompact->miniBump);
+		LODSW(*srcPos, cpt->extCompact->leaving);
+		LODSW(*srcPos, cpt->extCompact->atWatch);
+		LODSW(*srcPos, cpt->extCompact->atWas);
+		LODSW(*srcPos, cpt->extCompact->alt);
+		LODSW(*srcPos, cpt->extCompact->request);
+		LODSW(*srcPos, cpt->extCompact->spWidth_xx);
+		LODSW(*srcPos, cpt->extCompact->spColour);
+		LODSW(*srcPos, cpt->extCompact->spTextId);
+		LODSW(*srcPos, cpt->extCompact->spTime);
+		LODSW(*srcPos, cpt->extCompact->arAnimIndex);
+		// turnProg
+		LODSW(*srcPos, cpt->extCompact->waitingFor);
+		LODSW(*srcPos, cpt->extCompact->arTargetX);
+		LODSW(*srcPos, cpt->extCompact->arTargetY);
+		// animScratch
+		LODSW(*srcPos, cpt->extCompact->megaSet);
+
+		if (saveType & SAVE_MEGA0)
+			lodsMegaSet(srcPos, cpt->extCompact->megaSet0);
+		if (saveType & SAVE_MEGA1)
+			lodsMegaSet(srcPos, cpt->extCompact->megaSet1);
+		if (saveType & SAVE_MEGA2)
+			lodsMegaSet(srcPos, cpt->extCompact->megaSet2);
+		if (saveType & SAVE_MEGA3)
+			lodsMegaSet(srcPos, cpt->extCompact->megaSet3);
+	}
+}
+
+uint16 SkyControl::parseSaveData(uint8 *srcBuf) {
+
+	uint32 reloadList[60];
+	uint32 oldSection = SkyLogic::_scriptVariables[CUR_SECTION];
+	
+	uint32 cnt;
+	uint8 *srcPos = srcBuf;
+	uint32 size;
+	uint32 saveRev;
+
+	LODSD(srcPos, size);
+	LODSD(srcPos, saveRev);
+	if (saveRev != SAVE_FILE_REVISION) {
+		warning("Unknown save file revision (%d)",saveRev);
+		return RESTORE_FAILED;
+	}
+	
+	freeMemList(); // memory from last restore isn't needed anymore
+
+	uint32 music, charSet, mouseType, palette;
+	LODSD(srcPos, music);
+	LODSD(srcPos, charSet);
+	LODSD(srcPos, mouseType);
+	LODSD(srcPos, palette);
+
+	for (cnt = 0; cnt < 838; cnt++)
+		LODSD(srcPos, SkyLogic::_scriptVariables[cnt]);
+
+	for (cnt = 0; cnt < 60; cnt++)
+		LODSD(srcPos, reloadList[cnt]);
+
+	for (cnt = 0; cnt < ARRAYSIZE(_saveLoadCpts); cnt++)
+		lodsCompact(&srcPos, _saveLoadCpts[cnt]);
+
+	for (cnt = 0; cnt < 3; cnt++)
+		LODSW(srcPos, SkyCompact::park_table[cnt]);
+
+	for (cnt = 0; cnt < 13; cnt++)
+		LODSW(srcPos, SkyCompact::high_floor_table[cnt]);
+
+	if (srcPos - srcBuf != size)
+		error("Restore failed! Savegame data = %d bytes. Expected size: %d.\n", srcPos-srcBuf, size);
+
+	_skyLogic->fnLeaveSection(oldSection, 0, 0);
+	_skyLogic->fnEnterSection(SkyLogic::_scriptVariables[CUR_SECTION], 0, 0);
+	_skyDisk->refreshFilesList(reloadList);
+	_skyMusic->startMusic((uint16)music);
+	_skyText->fnSetFont(charSet);
+	_skyMouse->spriteMouse((uint16)mouseType, 0, 0);
+	SkyState::_systemVars.currentPalette = palette; // will be set when doControlPanel ends
+	SkyState::_systemVars.systemFlags |= SF_GAME_RESTORED; // what's that for?
+
+	return GAME_RESTORED;
+}
+
+#undef LODSD
+#undef LODSW
+
+uint16 SkyControl::restoreGameFromFile(void) {
+	
+	char fName[20];
+	sprintf(fName,"SKY-VM.%03d", _selectedGame);
+	File *inf = new File();
+	if (!inf->open(fName, _savePath)) {
+		delete inf;
+		return RESTORE_FAILED;
+	}
+
+	uint32 fSize = inf->size();
+	uint8 *saveData = (uint8*)malloc(fSize);
+	uint32 infSize = inf->readUint32LE();
+	inf->seek(0, SEEK_SET);
+
+	if (fSize != infSize) {
+		warning("File size doesn't match expected data size!");
+		delete inf;
+		free(saveData);
+		return RESTORE_FAILED;
+	}
+	if (inf->read(saveData, fSize) != fSize) {
+		warning("Can't read from file!");
+		delete inf;
+		free(saveData);
+		return RESTORE_FAILED;
+	}
+
+	uint16 res = parseSaveData(saveData);
+	inf->close();
+	delete inf;
+	free(saveData);
+	return res;
+}
 
 void SkyControl::delay(unsigned int amount) {
 

Index: control.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/control.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- control.h	27 Jun 2003 02:54:05 -0000	1.2
+++ control.h	1 Jul 2003 01:29:29 -0000	1.3
@@ -29,6 +29,7 @@
 #include "sky/screen.h"
 #include "sky/disk.h"
 #include "sky/mouse.h"
+#include "sky/logic.h"
 
 #define MAX_SAVE_GAMES 999
 #define MAX_TEXT_LEN 80
@@ -48,8 +49,6 @@
 #define MAX_ON_SCREEN ((SP_HEIGHT - SP_TOP_GAP - SP_BOT_GAP) / PAN_CHAR_HEIGHT) // no of save games on screen
 #define CP_PANEL 60400 // main panel sprite
 
-#define CHARACTER_LIST " ,().='-&+!?\"" // list of allowed characters
-
 #define MAINPANEL 0
 #define SAVEPANEL 1
 
@@ -100,8 +99,15 @@
 #define SAVE_MEGA1	 4
 #define SAVE_MEGA2	 8
 #define SAVE_MEGA3	16
+#define SAVE_GRAFX	32
+#define SAVE_TURNP	64
 
-#define SAVE_HEADER "(C) Revolution Software Ltd 1993.\x00System 2 written by David Sykes and Tony Warriner\x0D\x0APortable implementation done by the ScummVM team\x0D\x0ASave File Revision 1\x00"
+#define SAVE_FILE_REVISION 1
+
+struct AllocedMem {
+	uint16 *mem;
+	AllocedMem *next;
+};
 
 class SkyConResource {
 public:
@@ -135,7 +141,7 @@
 
 class SkyControl {
 public:
-	SkyControl(SkyScreen *screen, SkyDisk *disk, SkyMouse *mouse, SkyText *text, SkyMusicBase *music, OSystem *system, const char *savePath);
+	SkyControl(SkyScreen *screen, SkyDisk *disk, SkyMouse *mouse, SkyText *text, SkyMusicBase *music, SkyLogic *logic, OSystem *system, const char *savePath);
 	void doControlPanel(void);
 	void showGameQuitMsg(bool useScreen = true);
     
@@ -145,9 +151,14 @@
 	void drawMainPanel(void);
 	void delay(unsigned int amount);
 	void buttonControl(SkyConResource *pButton);
-	void loadSaveDescriptions(uint8 *destBuf);
-	void setUpGameSprites(uint8 *nameBuf, dataFileHeader **nameSprites, uint16 firstNum);
+
+	void loadDescriptions(uint8 *destBuf);
+	void saveDescriptions(uint8 *srcBuf);
+	void setUpGameSprites(uint8 *nameBuf, dataFileHeader **nameSprites, uint16 firstNum, uint16 selectedGame, bool allowSave);
 	void showSprites(dataFileHeader **nameSprites);
+	bool checkKeyList(uint8 key);
+	void handleKeyPress(uint8 key, uint8 *textBuf);
+
 	void animClick(SkyConResource *pButton);
 	bool getYesNo(void);
 	uint16 doMusicSlide(void);
@@ -159,22 +170,33 @@
 	uint16 shiftUp(uint8 speed);
 	const char *_savePath;
 
-	uint16 saveGameToFile(char *fName);
+	void appendMemList(uint16 *pMem);
+	void freeMemList(void);
+
+	uint16 _selectedGame;
+	uint16 saveGameToFile(void);
 	void stosMegaSet(uint8 **destPos, MegaSet *mega);
 	void stosCompact(uint8 **destPos, Compact *cpt);
-	void stosAR(uint8 **destPos, uint8 *arData);
+	void stosStr(uint8 **destPos, uint16 *src, bool isGraph);
 	uint32 prepareSaveData(uint8 *destBuf);
-	uint16 restoreGameFromFile(char *fName);
+
+	uint16 restoreGameFromFile(void);
+	void lodsMegaSet(uint8 **srcPos, MegaSet *mega);
+	void lodsCompact(uint8 **srcPos, Compact *cpt);
+	void lodsStr(uint8 **srcPos, uint16 *src);
+	uint16 parseSaveData(uint8 *srcBuf);
+
 	static Compact *_saveLoadCpts[833]; // \  moved to sky/compacts/savedata.cpp
 	static uint8 *_saveLoadARs[18];     // /
 
-	uint16 saveRestorePanel(bool allowEdit);
+	uint16 saveRestorePanel(bool allowSave);
 
 	SkyScreen *_skyScreen;
 	SkyDisk *_skyDisk;
 	SkyMouse *_skyMouse;
 	SkyText *_skyText;
 	SkyMusicBase *_skyMusic;
+	SkyLogic *_skyLogic;
 	OSystem *_system;
 	int _mouseX, _mouseY;
 	bool _mouseClicked;
@@ -194,6 +216,8 @@
 		uint8 *slide2;
 		uint8 *musicBodge;
 	} _sprites;
+
+	AllocedMem *_memListRoot;
 
 	uint8 *_screenBuf;
 	int _lastButton;

Index: grid.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/grid.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- grid.cpp	17 Jun 2003 12:27:03 -0000	1.10
+++ grid.cpp	1 Jul 2003 01:29:29 -0000	1.11
@@ -161,23 +161,25 @@
 	if (y < TOP_LEFT_Y) return false; // off screen
 	y -= TOP_LEFT_Y;
 	y >>= 3; // convert to blocks
-	if (y >= GRID_Y) return false; // off screen
+	if (y >= GAME_SCREEN_HEIGHT >> 3) return false; // off screen
 	bitPos = y * 40;
 	width++;
 	x >>= 3; // convert to blocks
 	
-	int32 x_signed = (x - (TOP_LEFT_X >> 3));
-	if (x_signed < 0) { // at least partially off screen
-		if (x_signed + width <= 0) return false; // completely off screen
-		else width += x_signed; // adjust width to visible part and continue
-			                    // x_signed is negative, so it's +=
-	}
-    if ((GAME_SCREEN_WIDTH >> 3) <= x_signed) return false; // off screen
-	if ((GAME_SCREEN_WIDTH >> 3) < x_signed + width) { // at least partially of screen
-		if ((uint32)((GAME_SCREEN_WIDTH >> 3) - x_signed) >= width) return false; // off screen
-		else width -= (GAME_SCREEN_WIDTH >> 3) - x_signed; // adjust width
-	}
-    bitPos += x_signed;
+	if (x < (TOP_LEFT_X >> 3)) { // at least partially off screen
+		if (x + width < (TOP_LEFT_X >> 3)) return false; // completely off screen
+		else {
+			width -= (TOP_LEFT_X >> 3) - x;
+			x = 0;
+		}
+	} else
+		x -= TOP_LEFT_X >> 3;
+
+    if ((GAME_SCREEN_WIDTH >> 3) <= x) return false; // off screen
+	if ((GAME_SCREEN_WIDTH >> 3) < x + width) // partially off screen
+		width = (GAME_SCREEN_WIDTH >> 3) - x;
+
+    bitPos += x;
 	int32 screenGridOfs = _gridConvertTable[cpt->screen] * GRID_SIZE;
 	bitPos += (screenGridOfs << 3); // convert to bits
 	uint32 tmpBits = 0x1F - (bitPos&0x1F);

Index: logic.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/logic.cpp,v
retrieving revision 1.104
retrieving revision 1.105
diff -u -d -r1.104 -r1.105
--- logic.cpp	30 Jun 2003 16:59:41 -0000	1.104
+++ logic.cpp	1 Jul 2003 01:29:29 -0000	1.105
@@ -2237,8 +2237,29 @@
 	return true;
 }
 
-bool SkyLogic::fnLincTextModule(uint32 a, uint32 b, uint32 c) {
-	error("Stub: fnLincTextModule");
+bool SkyLogic::fnLincTextModule(uint32 textPos, uint32 textNo, uint32 buttonAction) {
+
+	uint16 cnt;
+	if (buttonAction & 0x8000)
+		for (cnt = LINC_DIGIT_0; cnt <= LINC_DIGIT_9; cnt++)
+			_scriptVariables[cnt] = 0;
+	buttonAction &= 0x7FFF;
+	if (buttonAction < 10)
+		_scriptVariables[LINC_DIGIT_0 + buttonAction] = textNo;
+
+	lowTextManager_t text = _skyText->lowTextManager(textNo, 220, 0, 215, false);
+
+	Compact *textCpt = SkyState::fetchCompact(text.compactNum);
+
+	if (textPos < 20) { // line number (for text)
+		textCpt->xcood = 152;
+		textCpt->ycood = (uint16)textPos * 13 + 170;
+	} else if (textPos > 20) { // x coordinate (for numbers)
+		textCpt->xcood = (uint16)textPos;
+		textCpt->ycood = 214;
+	} else warning("::fnLincTextModule: textPos == 20");
+	textCpt->getToFlag = (uint16)textNo;
+	return true;
 }
 
 bool SkyLogic::fnTextKill2(uint32 a, uint32 b, uint32 c) {

Index: logic.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/logic.h,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- logic.h	6 Jun 2003 20:54:51 -0000	1.28
+++ logic.h	1 Jul 2003 01:29:29 -0000	1.29
@@ -64,7 +64,17 @@
 	MENU = 102,
 	RND = 115,
 	CUR_SECTION = 143,
-	REICH_DOOR_FLAG = 470
+	REICH_DOOR_FLAG = 470,
+	LINC_DIGIT_0 = 646,
+	LINC_DIGIT_1 = 647,
+	LINC_DIGIT_2 = 648,
+	LINC_DIGIT_3 = 649,
+	LINC_DIGIT_4 = 650,
+	LINC_DIGIT_5 = 651,
+	LINC_DIGIT_6 = 651,
+	LINC_DIGIT_7 = 653,
+	LINC_DIGIT_8 = 654,
+	LINC_DIGIT_9 = 655,
 };
 
 class SkyAutoRoute;
@@ -215,6 +225,7 @@
 	void stdSpeak(Compact *target, uint32 textNum, uint32 animNum, uint32 base);
 	
 	static uint32 _scriptVariables[838];
+	SkyGrid *_skyGrid;
 	
 protected:
 	void push(uint32);
@@ -241,7 +252,6 @@
 	
 	SkyScreen *_skyScreen;
 	SkyDisk *_skyDisk;
-	SkyGrid *_skyGrid;
 	SkyText *_skyText;
 	SkyMusicBase *_skyMusic;
 	SkySound *_skySound;

Index: screen.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/screen.cpp,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- screen.cpp	30 Jun 2003 16:59:41 -0000	1.32
+++ screen.cpp	1 Jul 2003 01:29:29 -0000	1.33
@@ -300,9 +300,7 @@
 
 	//_currentScreen points to new screen,
 	//_scrollScreen points to graphic showing old room
-	if (scroll == 13) scroll = 123; // script bug (?) in lower area
-	if ((scroll != 123) && (scroll != 321) && (scroll)) {
-		warning("unknown scroll parameter %d",scroll);
+	if ((scroll != 123) && (scroll != 321)) {
 		scroll = 0;
 	}
 
@@ -726,5 +724,37 @@
 			gridOfs++;
 		}
 	}
+}
+
+void SkyScreen::paintBox(uint16 x, uint16 y) {
+
+	uint8 *screenPos = _currentScreen + y * GAME_SCREEN_WIDTH + x;
+	memset(screenPos, 255, 8);
+	for (uint8 cnt = 1; cnt < 8; cnt++) {
+		*(screenPos + cnt * GAME_SCREEN_WIDTH) = 255;
+		*(screenPos + cnt * GAME_SCREEN_WIDTH + 7) = 255;
+	}
+	memset(screenPos + 7 * GAME_SCREEN_WIDTH, 255, 7);
+}
+
+void SkyScreen::showGrid(uint8 *gridBuf) {
+
+	uint32 gridData = 0;
+	uint8 bitsLeft = 0;
+	for (uint16 cnty = 0; cnty < GAME_SCREEN_HEIGHT >> 3; cnty++) { 
+		for (uint16 cntx = 0; cntx < GAME_SCREEN_WIDTH >> 3; cntx++) {
+			if (!bitsLeft) {
+				bitsLeft = 32;
+				gridData = *(uint32*)gridBuf;
+				gridBuf += 4;
+			}
+			if (gridData & 0x80000000)
+				paintBox(cntx << 3, cnty << 3);
+			bitsLeft--;
+			gridData <<= 1;
+		}
+	}
+	_system->copy_rect(_currentScreen, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, GAME_SCREEN_HEIGHT);
+
 }
 

Index: screen.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/screen.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- screen.h	3 Jun 2003 18:10:32 -0000	1.8
+++ screen.h	1 Jul 2003 01:29:29 -0000	1.9
@@ -81,6 +81,9 @@
 
 	void spriteEngine(void);
 
+	void paintBox(uint16 x, uint16 y);
+	void showGrid(uint8 *gridBuf);
+
 private:
 	OSystem *_system;
 	SkyDisk *_skyDisk;

Index: sky.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/sky.cpp,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -d -r1.65 -r1.66
--- sky.cpp	27 Jun 2003 13:23:01 -0000	1.65
+++ sky.cpp	1 Jul 2003 01:29:29 -0000	1.66
@@ -105,15 +105,22 @@
 
 	while (1) {
 		delay(_systemVars.gameSpeed);
+		/*if (_key_pressed == 'g') {
+			warning("loading grid");
+			_skyLogic->_skyGrid->loadGrids();
+			_key_pressed = 0;
+		}*/
 		if ((_key_pressed == 27) || (_key_pressed == 63)) { // 27 = escape, 63 = F5
 			_key_pressed = 0;
 			_skyControl->doControlPanel();
 		}
 		_skyMouse->mouseEngine((uint16)_sdl_mouse_x, (uint16)_sdl_mouse_y);
 		_skyLogic->engine();
+		//_skyScreen->forceRefresh();
 		_skyScreen->recreate();
 		_skyScreen->spriteEngine();
 		_skyScreen->flip();
+		//_skyScreen->showGrid(_skyLogic->_skyGrid->giveGrid(SkyLogic::_scriptVariables[SCREEN]));
 		_system->update_screen();
 	}
 }
@@ -127,13 +134,13 @@
 
 	if (_detector->getMidiDriverType() == MD_ADLIB) {
 		_systemVars.systemFlags |= SF_SBLASTER;
-		_skyMusic = new SkyAdlibMusic(_mixer, _skyDisk);
+		_skyMusic = new SkyAdlibMusic(_mixer, _skyDisk, _system);
 	} else {
 		_systemVars.systemFlags |= SF_ROLAND;
 		if (_detector->_native_mt32)
-			_skyMusic = new SkyMT32Music(_detector->createMidi(), _skyDisk);
+			_skyMusic = new SkyMT32Music(_detector->createMidi(), _skyDisk, _system);
 		else
-			_skyMusic = new SkyGmMusic(_detector->createMidi(), _skyDisk);
+			_skyMusic = new SkyGmMusic(_detector->createMidi(), _skyDisk, _system);
 	}
 	if (isCDVersion())
 		_systemVars.systemFlags |= SF_ALLOW_SPEECH;
@@ -156,7 +163,7 @@
 	_timer = Engine::_timer; // initialize timer *after* _skyScreen has been initialized.
 	_timer->installProcedure(&timerHandler, 1000000 / 50); //call 50 times per second
 
-	_skyControl = new SkyControl(_skyScreen, _skyDisk, _skyMouse, _skyText, _skyMusic, _system, getSavePath());
+	_skyControl = new SkyControl(_skyScreen, _skyDisk, _skyMouse, _skyText, _skyMusic, _skyLogic, _system, getSavePath());
 }
 
 void SkyState::initItemList() {





More information about the Scummvm-git-logs mailing list