[Scummvm-cvs-logs] CVS: scummvm/sky logic.cpp,1.52,1.53 logic.h,1.17,1.18 screen.cpp,1.11,1.12 screen.h,1.2,1.3 sky.cpp,1.36,1.37 sky.h,1.24,1.25 skydefs.h,1.17,1.18

Robert G?ffringmann lavosspawn at users.sourceforge.net
Tue May 27 09:43:07 CEST 2003


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

Modified Files:
	logic.cpp logic.h screen.cpp screen.h sky.cpp sky.h skydefs.h 
Log Message:
implemented screen.asm and sprites.asm (not yet working)

Index: logic.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/logic.cpp,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -d -r1.52 -r1.53
--- logic.cpp	26 May 2003 23:28:59 -0000	1.52
+++ logic.cpp	27 May 2003 16:42:20 -0000	1.53
@@ -48,7 +48,8 @@
 	&SkyLogic::simpleAnim,	 // 16 Module anim without x,y's
 };
 
-SkyLogic::SkyLogic(SkyDisk *skyDisk, SkyGrid *skyGrid, SkyText *skyText, SkyMusicBase *skyMusic, SkyMouse *skyMouse, SkySound *skySound, uint32 gameVersion) {
+SkyLogic::SkyLogic(SkyScreen *skyScreen, SkyDisk *skyDisk, SkyGrid *skyGrid, SkyText *skyText, SkyMusicBase *skyMusic, SkyMouse *skyMouse, SkySound *skySound, uint32 gameVersion) {
+	_skyScreen = skyScreen;
 	_skyDisk = skyDisk;
 	_skyGrid = skyGrid;
 	_skyText = skyText;
@@ -1113,7 +1114,8 @@
 }
 
 bool SkyLogic::fnDrawScreen(uint32 a, uint32 b, uint32 c) {
-	warning("Stub: fnDrawScreen");
+	printf("Call: fnDrawScreen(%X, %X)\n",a,b);
+	_skyScreen->fnDrawScreen(a, b);
 	return true;
 }
 
@@ -1995,20 +1997,30 @@
 }
 
 bool SkyLogic::fnStartMusic(uint32 a, uint32 b, uint32 c) {
-	error("Stub: fnStartMusic");
+	_skyMusic->startMusic((uint16)a);
+	return true;
+	//error("Stub: fnStartMusic");
 }
 
 bool SkyLogic::fnStopMusic(uint32 a, uint32 b, uint32 c) {
-	error("Stub: fnStopMusic");
+	_skyMusic->startMusic(0);
+	return true;
+	//error("Stub: fnStopMusic");
 }
 
 bool SkyLogic::fnFadeDown(uint32 a, uint32 b, uint32 c) {
+	printf("fnFadeDown(scroll = %d);\n",a);
+	_skyScreen->fnFadeDown(a);
+	return true;
 	// this is actually already implemented in SkyScreen
-	error("Stub: fnFadeDown");
+	//error("Stub: fnFadeDown");
 }
 
 bool SkyLogic::fnFadeUp(uint32 a, uint32 b, uint32 c) {
-	error("Stub: fnFadeUp");
+	printf("fnFadeUp(scroll = %d, palette = %d);\n",a,b);
+	_skyScreen->fnFadeUp(a,b);
+	return true;
+	//error("Stub: fnFadeUp");
 }
 
 bool SkyLogic::fnQuitToDos(uint32 a, uint32 b, uint32 c) {
@@ -2027,4 +2039,3 @@
 	printf("fnPrintf: %d\n", a);
 	return true;
 }
-

Index: logic.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/logic.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- logic.h	26 May 2003 20:54:58 -0000	1.17
+++ logic.h	27 May 2003 16:42:20 -0000	1.18
@@ -28,11 +28,13 @@
 #include "sky/autoroute.h"
 #include "sky/musicbase.h"
 #include "sky/mouse.h"
+#include "sky/screen.h"
 
 enum scriptVariableOffsets {
 	RESULT = 0,
 	SCREEN = 1,
 	LOGIC_LIST_NO = 2,
+	DRAW_LIST_NO = 8,
 	CUR_ID = 12,
 	MOUSE_STATUS = 13,
 	MOUSE_STOP = 14,
@@ -42,6 +44,13 @@
 	PLAYER_MOOD = 29,
 	PLAYER_SCREEN = 30,
 	HIT_ID = 37,
+	LAYER_0_ID = 41,
+	LAYER_1_ID = 42,
+	LAYER_2_ID = 43,
+	LAYER_3_ID = 44,
+	GRID_1_ID = 45,
+	GRID_2_ID = 46,
+	GRID_3_ID = 47,
 	THE_CHOSEN_ONE = 51,
 	TEXT1 = 53,
 	MENU_LENGTH = 100,
@@ -50,9 +59,12 @@
 	CUR_SECTION = 143
 };
 
+class SkyAutoRoute;
+class SkyScreen;
+
 class SkyLogic {
 public:
-	SkyLogic(SkyDisk *skyDisk, SkyGrid *skyGrid, SkyText *skyText, SkyMusicBase *skyMusic, SkyMouse *skyMouse, SkySound *skySound, uint32 gameVersion);
+	SkyLogic(SkyScreen *skyScreen, SkyDisk *skyDisk, SkyGrid *skyGrid, SkyText *skyText, SkyMusicBase *skyMusic, SkyMouse *skyMouse, SkySound *skySound, uint32 gameVersion);
 	void engine();
 
 	void nop();
@@ -216,6 +228,7 @@
 	
 	uint32 _gameVersion;
 	
+	SkyScreen *_skyScreen;
 	SkyDisk *_skyDisk;
 	SkyGrid *_skyGrid;
 	SkyText *_skyText;

Index: screen.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/screen.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- screen.cpp	15 May 2003 19:14:40 -0000	1.11
+++ screen.cpp	27 May 2003 16:42:20 -0000	1.12
@@ -50,8 +50,12 @@
 	uint8 tmpPal[1024];
 
 	_system->init_size(FULL_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
-	_gameGrid = (uint8 *)malloc(GRID_X * GRID_Y * 2);
+	_gameGrid = (uint8*)malloc(GRID_X * GRID_Y * 2);
+	_backScreen = (uint8*)malloc(GAME_SCREEN_WIDTH * GAME_SCREEN_HEIGHT);
+	forceRefresh();
+
 	_currentScreen = NULL;
+	_scrollScreen = NULL;
 
 	//blank the first 240 colors of the palette 
 	memset(tmpPal, 0, GAME_COLOURS * 4);
@@ -66,6 +70,7 @@
 
 	//set the palette
 	_system->set_palette(tmpPal, 0, VGA_COLOURS);
+	_currentPalette = 0;
 
 	_seqInfo.framesLeft = 0;
 	_seqInfo.seqData = _seqInfo.seqDataPos = NULL;
@@ -76,6 +81,7 @@
 
 	free(_gameGrid);
 	if (_currentScreen) free(_currentScreen);
+	if (_backScreen) free(_backScreen);
 }
 
 //set a new palette, pal is a pointer to dos vga rgb components 0..63
@@ -86,6 +92,18 @@
 	_system->update_screen();
 }
 
+void SkyScreen::halvePalette(void) {
+
+	uint8 halfPalette[1024];
+	for (uint8 cnt = 0; cnt < GAME_COLOURS; cnt++) {
+		halfPalette[(cnt << 2) | 0] = _palette[(cnt << 2) | 0] >> 1;
+		halfPalette[(cnt << 2) | 1] = _palette[(cnt << 2) | 1] >> 1;
+		halfPalette[(cnt << 2) | 2] = _palette[(cnt << 2) | 2] >> 1;
+		halfPalette[(cnt << 2) | 3] = 0;
+	}
+	_system->set_palette(halfPalette, 0, GAME_COLOURS);
+}
+
 void SkyScreen::setPalette(uint16 fileNum) {
 
 	uint8 *tmpPal = _skyDisk->loadFile(fileNum, NULL);
@@ -122,22 +140,100 @@
 	}
 }
 
-//action = 0, simply fade out
-//action = 1, scroll left
-//action = 2, scroll right
-void SkyScreen::fnFadeDown(uint8 action) {
+void SkyScreen::recreate(void) {
 
-	if (action) {
-	
-		//do scroll
-		warning("SkyScreen::fnFadeDown: Scrolling not yet implemented!\n");
+	// check the game grid for changed blocks
+	if (!SkyLogic::_scriptVariables[LAYER_0_ID]) return ;
+	uint8 *gridPos = _gameGrid;
+	uint8 *screenData = (uint8*)SkyState::fetchItem(SkyLogic::_scriptVariables[LAYER_0_ID]);
+	if (!screenData) {
+		error("SkyScreen::recreate():\nSkyState::fetchItem(SkyLogic::_scriptVariables[LAYER_0_ID](%X)) returned NULL",SkyLogic::_scriptVariables[LAYER_0_ID]);
+	}
+	uint8 *screenPos = _backScreen;
 
+	for (uint8 cnty = 0; cnty < GRID_Y; cnty++) {
+		for (uint8 cntx = 0; cntx < GRID_X; cntx++) {
+			if (gridPos[0] & 0x80) {
+				gridPos[0] &= 0x7F; // reset recreate flag
+				gridPos[0] |= 1;    // set bit for flip routine
+				uint8 *savedScreenY = screenPos;
+				for (uint8 gridCntY = 0; gridCntY < GRID_H; gridCntY++) {
+					memcpy(screenPos, screenData, GRID_W);
+					screenPos += GAME_SCREEN_WIDTH;
+                    screenData += GRID_W;
+				}
+				screenPos = savedScreenY + GRID_W;
+			} else {
+				screenPos += GRID_W;
+				screenData += GRID_W * GRID_H;
+			}
+			gridPos++;
+		}
+		screenPos += (GRID_H - 1) * GAME_SCREEN_WIDTH;
+	}
+	showScreen(_backScreen);
+}
+
+void SkyScreen::flip(void) {
+
+	// mouse_flag |= MF_NO_UPDATE;
+	// drawMouseToBackScreen();
+	uint8 *screenPos = _currentScreen;
+	uint8 *backPos = _backScreen;
+	for (uint8 cnty = 0; cnty < GRID_Y; cnty++) {
+		for (uint8 cntx = 0; cntx < GRID_X; cntx++) {
+			if (_gameGrid[cnty * GRID_X +cntx] & 1) {
+				_gameGrid[cnty * GRID_X +cntx] &= ~1;
+				uint8 *saveBackY = backPos;
+				uint8 *saveScreenY = screenPos;
+				for (uint8 gridLineCnt = 0; gridLineCnt < GRID_H; gridLineCnt++) {
+					memcpy(screenPos, backPos, GRID_W);
+					screenPos += GAME_SCREEN_WIDTH;
+					backPos += GAME_SCREEN_WIDTH;
+				}
+				backPos = saveBackY + GRID_W;
+				screenPos = saveBackY + GRID_W;
+			} else {
+				backPos += GRID_W;
+				screenPos += GRID_W;
+			}
+		}
+		screenPos += (GRID_H - 1) * GAME_SCREEN_WIDTH;
+		backPos += (GRID_H - 1) * GAME_SCREEN_WIDTH;
+	}
+	// mouse_flag &= ~MF_NO_UPDATE;
+	// _skyMouse->restoreDataToBackScreen();
+	showScreen(_backScreen);
+}
+
+void SkyScreen::fnDrawScreen(uint32 palette, uint32 scroll) {
+
+	// set up the new screen
+	fnFadeDown(scroll);
+	forceRefresh();
+	recreate();
+	spriteEngine();
+	flip();
+	fnFadeUp(palette, scroll);
+	showScreen(_backScreen);
+}
+
+void SkyScreen::fnFadeDown(uint32 scroll) {
+
+	if (scroll) {
+		printf("warning: SkyScreen::fnFadeDown doesn't check (SYSTEM_FLAGS & SF_NO_SCROLL)\n");
+		// scrolling is performed by fnFadeUp. It's just prepared here
+		_scrollScreen = _currentScreen;
+		_currentScreen = (uint8*)malloc(FULL_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
+		// the game will draw the new room into _currentScreen which
+		// will be scrolled into the visible screen by fnFadeUp
+		// fnFadeUp also frees the _scrollScreen
 	} else {
 		for (uint8 cnt = 0; cnt < 32; cnt++) {
 			palette_fadedown_helper((uint32 *)_palette, GAME_COLOURS);
 			_system->set_palette(_palette, 0, GAME_COLOURS);
 			_system->update_screen();
-			waitForTimer();			
+			waitForTimer();
 		}
 	}
 }
@@ -189,6 +285,65 @@
 	}	
 }
 
+void SkyScreen::fnFadeUp(uint32 palNum, uint32 scroll) {
+
+	//_currentScreen points to new screen,
+	//_scrollScreen points to graphic showing old room
+	//if (!(systemFlags & SF_NO_SCROLL) && (!scroll)) {
+	if (scroll) printf("warning: fnFadeUp doesn't check (systemFlags & SF_NO_SCROLL)");
+	if (scroll == 123) {
+		// scroll left (going right)
+		if (!_currentScreen) error("SkyScreen::fnFadeUp[Scroll L]: _currentScreen is NULL!\n");
+		if (!_scrollScreen) error("SkyScreen::fnFadeUp[Scroll L]: _scrollScreen is NULL!\n");
+		uint8 *scrNewPtr, *scrOldPtr;
+		for (uint8 scrollCnt = 0; scrollCnt < (GAME_SCREEN_WIDTH / SCROLL_JUMP) - 1; scrollCnt++) {
+			scrNewPtr = _currentScreen + scrollCnt * SCROLL_JUMP;
+			scrOldPtr = _scrollScreen;
+			for (uint8 lineCnt = 0; lineCnt < GAME_SCREEN_HEIGHT; lineCnt++) {
+				memmove(scrOldPtr, scrOldPtr + SCROLL_JUMP, GAME_SCREEN_WIDTH - SCROLL_JUMP);
+				memcpy(scrOldPtr + GAME_SCREEN_WIDTH - SCROLL_JUMP, scrNewPtr, SCROLL_JUMP);
+				scrNewPtr += GAME_SCREEN_WIDTH;
+				scrOldPtr += GAME_SCREEN_WIDTH;
+			}
+			showScreen(_scrollScreen);
+			waitForTimer();
+		}
+		showScreen(_currentScreen);
+		free(_scrollScreen);
+	} else if (scroll == 321) {
+		// scroll right (going left)
+		if (!_currentScreen) error("SkyScreen::fnFadeUp[Scroll R]: _currentScreen is NULL!\n");
+		if (!_scrollScreen) error("SkyScreen::fnFadeUp[Scroll R]: _scrollScreen is NULL!\n");
+		uint8 *scrNewPtr, *scrOldPtr;
+		for (uint8 scrollCnt = 0; scrollCnt < (GAME_SCREEN_WIDTH / SCROLL_JUMP) - 1; scrollCnt++) {
+			scrNewPtr = _currentScreen + GAME_SCREEN_WIDTH - (scrollCnt + 1) * SCROLL_JUMP;
+			scrOldPtr = _scrollScreen;
+			for (uint8 lineCnt = 0; lineCnt < GAME_SCREEN_HEIGHT; lineCnt++) {
+				memmove(scrOldPtr + SCROLL_JUMP, scrOldPtr, GAME_SCREEN_WIDTH - SCROLL_JUMP);
+				memcpy(scrOldPtr, scrNewPtr, SCROLL_JUMP);
+				scrNewPtr += GAME_SCREEN_WIDTH;
+				scrOldPtr += GAME_SCREEN_WIDTH;
+			}
+			showScreen(_scrollScreen);
+			waitForTimer();
+		}
+		showScreen(_currentScreen);
+		free(_scrollScreen);
+	} else {
+		uint8 *palette = (uint8*)SkyState::fetchCompact(palNum);
+		if (palette == NULL)
+			error("SkyScreen::fnFadeUp: can't fetch compact %X.\n", palNum);
+#ifdef SCUMM_BIG_ENDIAN
+		byte tmpPal[256 * 3];
+		for (uint16 cnt = 0; cnt < 256*3; cnt++)
+			tmpPal[cnt] = palette[cnt ^ 1];
+        paletteFadeUp(tmpPal);
+#else
+		paletteFadeUp(palette);
+#endif
+	}
+}
+
 void SkyScreen::waitForTimer(void) {
 
 	_gotTick = false;
@@ -260,3 +415,262 @@
 
 	return _seqInfo.running;
 }
+
+//- sprites.asm routines
+
+void SkyScreen::spriteEngine(void) {
+
+	doSprites(BACK);
+	sortSprites();
+	doSprites(FORE);	
+}
+
+void SkyScreen::sortSprites(void) {
+
+	StSortList sortList[30];
+	uint32 currDrawList = DRAW_LIST_NO;
+	bool nextDrawList = false;
+	while (SkyLogic::_scriptVariables[currDrawList]) {
+		// big_sort_loop
+		uint32 spriteCnt = 0;
+		do { // a_new_draw_list:
+			uint16 *drawListData = (uint16*)SkyState::fetchCompact(SkyLogic::_scriptVariables[currDrawList]);
+			nextDrawList = false;
+			while ((!nextDrawList) && (drawListData[0])) {
+				if (drawListData[0] == 0xFFFF) {
+					currDrawList = drawListData[1];
+					nextDrawList = true;
+				} else {
+					// process_this_id:
+					Compact *spriteComp = SkyState::fetchCompact(drawListData[0]);
+					if ((spriteComp->status & 4) && // is it sortable playfield?(!?!)
+						(spriteComp->screen == SkyLogic::_scriptVariables[SCREEN])) { // on current screen
+							dataFileHeader *spriteData = 
+								(dataFileHeader*)SkyState::fetchItem(spriteComp->frame >> 6);
+							if (!spriteData) {
+								printf("Missing file %d!\n",spriteComp->frame >> 6);
+								spriteComp->status = 0;
+							} else {
+								sortList[spriteCnt].yCood = spriteComp->ycood + spriteData->s_offset_y + spriteData->s_height;
+								sortList[spriteCnt].compact = spriteComp;
+								sortList[spriteCnt].sprite = spriteData;
+								spriteCnt++;
+							}
+					}
+					drawListData++;
+				}
+			} 
+		} while (nextDrawList);
+		// made_list:
+		if (spriteCnt > 1) { // bubble sort
+			for (uint32 cnt1 = 0; cnt1 < spriteCnt; cnt1++)
+				for (uint32 cnt2 = cnt1 + 1; cnt2 < spriteCnt; cnt2++)
+					if (sortList[cnt1].yCood <= sortList[cnt2].yCood) {
+						StSortList tmp;
+						tmp.yCood = sortList[cnt1].yCood;
+						tmp.sprite = sortList[cnt1].sprite;
+						tmp.compact = sortList[cnt1].compact;
+						sortList[cnt1].yCood = sortList[cnt2].yCood;
+						sortList[cnt1].sprite = sortList[cnt2].sprite;
+						sortList[cnt1].compact = sortList[cnt2].compact;
+						sortList[cnt2].yCood = tmp.yCood;
+						sortList[cnt2].sprite = tmp.sprite;
+						sortList[cnt2].compact = tmp.compact;
+					}
+		}
+		for (uint32 cnt = 0; cnt < spriteCnt; cnt++) {
+			drawSprite((uint8*)sortList[cnt].sprite, sortList[cnt].compact);
+			if (sortList[cnt].compact->status & 8) vectorToGame(0x81);
+			else vectorToGame(1);
+			if (sortList[cnt].compact->status & 0x200) verticalMask();
+		}
+	}
+}
+
+void SkyScreen::doSprites(uint8 layer) {
+
+	uint16 drawListNum = DRAW_LIST_NO;
+	uint32 idNum;
+	bool getNextDrawList;
+	uint16* drawList;
+	while (SkyLogic::_scriptVariables[drawListNum]) { // std sp loop
+		idNum = SkyLogic::_scriptVariables[drawListNum];
+		drawListNum++;
+
+		drawList = (uint16*)SkyState::fetchCompact(idNum);
+		getNextDrawList = false;
+		while(drawList[0]) {
+			// new_draw_list:
+			while ((!getNextDrawList) && (drawList[0])) {
+				// back_loop:
+				if (drawList[0]) {
+					if (drawList[0] == 0xFFFF) {
+						// new_draw_list
+						idNum = drawList[1];
+						getNextDrawList = true;
+					} else {
+						// not_new_list
+						Compact *spriteData = SkyState::fetchCompact(drawList[0]);
+						drawList++;
+						if ((spriteData->status & (1 << layer)) && 
+							(spriteData->screen == SkyLogic::_scriptVariables[SCREEN])) {
+								uint8 *toBeDrawn = (uint8*)SkyState::fetchItem(spriteData->frame >> 6);
+								drawSprite(toBeDrawn, spriteData);
+								if (layer == FORE) verticalMask();
+
+								if (spriteData->status & 8) vectorToGame(0x81);
+								else vectorToGame(1);
+						}
+					}
+				}
+			}
+			if (drawList[0]) {
+				drawList = (uint16*)SkyState::fetchCompact(idNum);
+				getNextDrawList = false;
+			}
+		}
+	}
+}
+
+void SkyScreen::drawSprite(uint8 *spriteInfo, Compact *sprCompact) {
+
+	if (spriteInfo == NULL) {
+		warning("SkyScreen::drawSprite Can't draw sprite. Data %d was not loaded.\n", sprCompact->frame >> 6);
+		sprCompact->status = 0;
+		return ;
+	}
+	dataFileHeader *sprDataFile = (dataFileHeader *)spriteInfo;
+	_sprWidth = sprDataFile->s_width;
+	_sprHeight = sprDataFile->s_height;
+	_maskX1 = _maskX2 = 0;
+	uint8 *spriteData = spriteInfo + (sprCompact->frame & 0x3F) * sprDataFile->s_sp_size;
+	spriteData += sizeof(dataFileHeader);
+
+	int32 spriteY = sprCompact->ycood + sprDataFile->s_offset_y - TOP_LEFT_Y;
+	if (spriteY < 0) {
+		spriteY = ~spriteY;
+		if (_sprHeight <= (uint32)spriteY) {
+			_sprWidth = 0;
+			return ;
+		}
+		_sprHeight -= spriteY;
+		spriteData += sprDataFile->s_width * spriteY;
+		spriteY = 0;
+	} else {
+		int32 botClip = GAME_SCREEN_HEIGHT - sprDataFile->s_height - spriteY;
+		if (botClip < 0) {
+			if (botClip + _sprHeight <= 0) {
+				_sprWidth = 0;
+				return ;
+			}
+			_sprHeight += botClip;
+		}
+	}
+	_sprY = (uint32)spriteY;
+	int32 spriteX = sprCompact->xcood + sprDataFile->s_offset_x - TOP_LEFT_X;
+	if (spriteX < 0) {
+		spriteX = ~spriteX;
+		if (_sprWidth <= (uint32)spriteX) {
+			_sprWidth = 0;
+			return ;
+		}
+		_sprWidth -= spriteX;
+		_maskX1 = spriteX;
+		spriteX = 0;
+	} else {
+		int32 rightClip = GAME_SCREEN_WIDTH - sprDataFile->s_width - spriteX;
+		if (rightClip < 0) {
+			rightClip = ~rightClip;
+			if (_sprWidth <= (uint32)rightClip) {
+				_sprWidth = 0;
+				return ;
+			}
+            _sprWidth -= rightClip;
+            _maskX2 = rightClip;
+		}
+	}
+	_sprX = (uint32)spriteX;
+	uint8 *screenPtr = _backScreen + _sprY * GAME_SCREEN_WIDTH + _sprX;
+	if ((_sprX + _sprWidth >= 320) || (_sprY + _sprHeight >= 192)) {
+		warning("SkyScreen::drawSprite fatal error: got x = %d, y = %d, w = %d, h = %d\n",_sprX, _sprY, _sprWidth, _sprHeight);
+		_sprWidth = 0;
+		return ;
+	}
+	for (uint8 cnty = 0; cnty < _sprHeight; cnty++) {
+		spriteData += _maskX1;
+		for (uint8 cntx = 0; cntx < _sprWidth; cntx++)
+			if (spriteData[cntx]) screenPtr[cntx] = spriteData[cntx];
+		spriteData += _maskX2;
+		screenPtr += GAME_SCREEN_WIDTH;
+	}
+	// Convert the sprite coordinate/size values to blocks for vertical mask and/or vector to game
+	_sprWidth += _sprX + GRID_W-1;
+	_sprHeight += _sprY + GRID_H-1;
+	
+	_sprX >>= GRID_W_SHIFT;
+	_sprWidth >>= GRID_W_SHIFT;
+	_sprY >>= GRID_H_SHIFT;
+	_sprHeight >>= GRID_H_SHIFT;
+
+	_sprWidth -= _sprX;
+	_sprHeight -= _sprY;
+}
+
+void SkyScreen::vectorToGame(uint8 gridVal) {
+
+	uint8 *trgGrid = _gameGrid + _sprY * GRID_X +_sprX; // why?!?!
+	for (uint32 cnty = 0; cnty < _sprHeight; cnty++) {
+		for (uint32 cntx = 0; cntx < _sprWidth; cntx++)
+			trgGrid[cntx] |= gridVal;
+		trgGrid += GRID_X;
+	}
+}
+
+void SkyScreen::vertMaskSub(uint16 *grid, uint32 gridOfs, uint8 *screenPtr, uint32 layerId) {
+
+	for (uint32 cntx = 0; cntx < _sprHeight; cntx++) { // start_x | block_loop
+		if (grid[gridOfs]) {
+			if (!(grid[gridOfs] & 0x8000)) {
+	            uint32 gridVal = grid[gridOfs]-1;
+				gridVal *= GRID_W * GRID_H;
+				uint8 *dataSrc = (uint8*)SkyState::fetchItem(SkyLogic::_scriptVariables[layerId]) + gridVal;
+				uint8 *dataTrg = screenPtr;
+				for (uint32 grdCntY = 0; grdCntY < GRID_H; grdCntY++) {				
+					for (uint32 grdCntX = 0; grdCntX < GRID_W; grdCntX++)
+						if (dataSrc[grdCntX]) dataTrg[grdCntX] = dataSrc[grdCntX];
+					dataSrc += GRID_W;
+					dataTrg += GAME_SCREEN_WIDTH;
+				}
+			} // dummy_end:
+			screenPtr -= GRID_H * GAME_SCREEN_WIDTH;
+			gridOfs -= GRID_X;
+		} else return;
+	} // next_x
+}
+
+void SkyScreen::verticalMask(void) {
+
+	if (_sprWidth == 0) return ;
+	uint32 startGridOfs = (_sprY + _sprHeight - 1) * GRID_X + _sprX;
+	uint8 *startScreenPtr = (_sprY + _sprHeight - 1) * GRID_H * GAME_SCREEN_WIDTH + _sprX * GRID_W + _backScreen;
+
+	for (uint32 layerCnt = LAYER_1_ID; layerCnt <= LAYER_3_ID; layerCnt++) {
+		uint32 gridOfs = startGridOfs;
+		uint8 *screenPtr = startScreenPtr;
+		for (uint32 widCnt = 0; widCnt < _sprWidth; widCnt++) { // x_loop
+			uint32 nLayerCnt = layerCnt;
+			while (SkyLogic::_scriptVariables[nLayerCnt + 3]) {
+				uint16 *scrGrid;
+				scrGrid = (uint16*)SkyState::fetchItem(SkyLogic::_scriptVariables[layerCnt + 3]);
+				if (scrGrid[gridOfs]) {
+                    vertMaskSub(scrGrid, gridOfs, screenPtr, layerCnt);
+					break;
+				} else nLayerCnt++;
+			}
+			// next_x:
+			screenPtr += GRID_W;
+			gridOfs++;
+		}
+	}
+}
+

Index: screen.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/screen.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- screen.h	15 May 2003 19:14:40 -0000	1.2
+++ screen.h	27 May 2003 16:42:20 -0000	1.3
@@ -29,20 +29,31 @@
 #include "sky/disk.h"
 #include "sky/skydefs.h"
 #include "sky/sky.h"
+#include "sky/logic.h"
 
 #define SCROLL_JUMP		16
 #define VGA_COLOURS		256
 #define GAME_COLOURS		240
 #define SEQ_DELAY 3
 
+#define FORE 1
+#define BACK 0
+
+typedef struct {
+	uint16 yCood;
+	Compact *compact;
+	dataFileHeader *sprite;
+} StSortList;
+
+class SkyState;
+
 class SkyScreen {
 public:
 	SkyScreen(OSystem *pSystem, SkyDisk *pDisk);
 	~SkyScreen(void);
+//	void takeScriptVars(uint32 *pScriptVars) { _scriptVariables = pScriptVars; };
 	void setPalette(uint8 *pal);
 	void setPalette(uint16 fileNum);
-
-	void fnFadeDown(uint8 action);
 	void paletteFadeUp(uint8 *pal);
 	void paletteFadeUp(uint16 fileNr);
 
@@ -55,16 +66,31 @@
 	bool sequenceRunning(void);
 	uint32 seqFramesLeft(void) { return _seqInfo.framesLeft; };
 	uint8 *giveCurrent(void) { return _currentScreen; };
+	void halvePalette(void);
+
+	//- regular screen.asm routines
+	void forceRefresh(void) { memset(_gameGrid, 0x80, GRID_X * GRID_Y); };
+	void fnFadeUp(uint32 palNum, uint32 scroll);
+	void fnFadeDown(uint32 scroll);
+	void fnDrawScreen(uint32 palette, uint32 scroll);
+	void clearScreen(void) { memset(_currentScreen, 0, FULL_SCREEN_WIDTH * FULL_SCREEN_HEIGHT); };
+
 private:
 	OSystem *_system;
 	SkyDisk *_skyDisk;
 	static uint8 _top16Colours[16*3];
 	uint8 _palette[1024];
+	uint32 _currentPalette;
 
 	bool volatile _gotTick;
-
 	void waitForTimer(void);
+	void processSequence(void);
 
+	uint8 *_gameGrid;
+	uint8 *_currentScreen;
+	uint8 *_scrollScreen;
+	uint8 *_backScreen;
+	//uint32 *_scriptVariables;
 	struct {
 		uint32 framesLeft;
 		uint32 delay;
@@ -72,21 +98,29 @@
 		uint8 *seqDataPos;
 		bool running;
 	} _seqInfo;
-	void processSequence(void);
-
-	uint8 *_currentScreen;
-
 	//byte *_workScreen;
-	//byte *_backScreen;
 	//byte *_tempPal;
 	//byte *_workPalette;
 	//byte *_halfPalette;
 	//byte *_scrollAddr;
 	//byte *_lScreenBuf, *_lPaletteBuf;
-	byte *_gameGrid;
 
+    //- more regular screen.asm + layer.asm routines
 	void convertPalette(uint8 *inPal, uint8* outPal);
 	void palette_fadedown_helper(uint32 *pal, uint num);
+	void recreate(void);
+	void flip(void);
+
+	//- sprite.asm routines
+	// fixme: get rid of these globals
+	uint32 _sprWidth, _sprHeight, _sprX, _sprY, _maskX1, _maskX2;
+	void spriteEngine(void);
+    void doSprites(uint8 layer);
+	void sortSprites(void);
+	void drawSprite(uint8 *spriteData, Compact *sprCompact);
+	void verticalMask(void);
+	void vertMaskSub(uint16 *grid, uint32 gridOfs, uint8 *screenPtr, uint32 layerId);
+	void vectorToGame(uint8 gridVal);
 };
 
 #endif //SKYSCREEN_H

Index: sky.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/sky.cpp,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- sky.cpp	21 May 2003 21:01:12 -0000	1.36
+++ sky.cpp	27 May 2003 16:42:20 -0000	1.37
@@ -73,8 +73,51 @@
 	_introTextSave = 0;
 }
 
+void SkyState::showQuitMsg(void) {
+
+	uint8 *textBuf1 = (uint8*)calloc(GAME_SCREEN_WIDTH * 14 + sizeof(struct dataFileHeader),1);
+	uint8 *textBuf2 = (uint8*)calloc(GAME_SCREEN_WIDTH * 14 + sizeof(struct dataFileHeader),1);
+	char *vText1, *vText2;
+	uint8 *screenData = _skyScreen->giveCurrent();
+	switch (_language) {
+		case DE_DEU: vText1 = VIG_DE1; vText2 = VIG_DE2; break;
+		case FR_FRA: vText1 = VIG_FR1; vText2 = VIG_FR2; break;
+		case IT_ITA: vText1 = VIG_IT1; vText2 = VIG_IT2; break;
+		case PT_BRA: vText1 = VIG_PT1; vText2 = VIG_PT2; break;
+		default: vText1 = VIG_EN1; vText2 = VIG_EN2; break;
+	}
+	_skyText->displayText(vText1, textBuf1, true, 320, 255);
+	_skyText->displayText(vText2, textBuf2, true, 320, 255);
+	uint8 *curLine1 = textBuf1 + sizeof(struct dataFileHeader);
+	uint8 *curLine2 = textBuf2 + sizeof(struct dataFileHeader);
+	uint8 *targetLine = screenData + GAME_SCREEN_WIDTH * 80;
+	for (uint8 cnty = 0; cnty < 14; cnty++) {
+		for (uint16 cntx = 0; cntx < GAME_SCREEN_WIDTH; cntx++) {
+			if (curLine1[cntx])
+				targetLine[cntx] = curLine1[cntx];
+			if (curLine2[cntx])
+				(targetLine + 24 * GAME_SCREEN_WIDTH)[cntx] = curLine2[cntx];
+		}
+		curLine1 += GAME_SCREEN_WIDTH;
+		curLine2 += GAME_SCREEN_WIDTH;
+		targetLine += GAME_SCREEN_WIDTH;
+	}
+	_skyScreen->halvePalette();
+	_skyScreen->showScreen(screenData);
+	free(textBuf1); free(textBuf2);
+}
+
 SkyState::~SkyState() {
-	
+
+	delete _skyLogic;
+	delete _skyGrid;
+	delete _skySound;
+	delete _skyMusic;
+    showQuitMsg();	
+	delete _skyText;
+	delete _skyMouse;
+	delete _skyScreen;
+	delay(1500);
 }
 
 void SkyState::errorString(const char *buf1, char *buf2) {
@@ -98,7 +141,7 @@
 		intro();
 
 	loadBase0();
-	
+
 	while (1) {
 		delay(100);
 		_skyLogic->engine();
@@ -121,8 +164,8 @@
 	_gameVersion = _skyDisk->determineGameVersion();
 	_skyText = new SkyText(_skyDisk, _gameVersion, _language);
 	_skyMouse = new SkyMouse(_skyDisk);
-	
 	_skyScreen = new SkyScreen(_system, _skyDisk);
+
 	initVirgin();
 	//initMouse();
 	initItemList();
@@ -130,7 +173,7 @@
 	//initialiseRouter();
 	loadFixedItems();
 	_skyGrid = new SkyGrid(_skyDisk);
-	_skyLogic = new SkyLogic(_skyDisk, _skyGrid, _skyText, _skyMusic, _skyMouse, _skySound, _gameVersion);
+	_skyLogic = new SkyLogic(_skyScreen, _skyDisk, _skyGrid, _skyText, _skyMusic, _skyMouse, _skySound, _gameVersion);
 	
 	_timer = Engine::_timer; // initialize timer *after* _skyScreen has been initialized.
 	_timer->installProcedure(&timerHandler, 1000000 / 50); //call 50 times per second
@@ -188,6 +231,11 @@
 	_itemList[271] = (void **)_skyDisk->loadFile(271, NULL);
 	_itemList[272] = (void **)_skyDisk->loadFile(272, NULL);
 		
+}
+
+void **SkyState::fetchItem(uint32 num) {
+
+	return _itemList[num];
 }
 
 void SkyState::timerHandler(void *ptr) {

Index: sky.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/sky.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- sky.h	14 May 2003 22:33:39 -0000	1.24
+++ sky.h	27 May 2003 16:42:20 -0000	1.25
@@ -94,6 +94,7 @@
 	static bool isCDVersion(uint32 version);
 
 	static Compact *fetchCompact(uint32 a);
+	static void **fetchItem(uint32 num);
 	
 	static void **_itemList[300];
 
@@ -131,6 +132,8 @@
 	static int CDECL game_thread_proc(void *param);
 
 	void shutdown();
+
+	void showQuitMsg(void);
 
 	RandomSource _rnd;
 };

Index: skydefs.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sky/skydefs.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- skydefs.h	26 May 2003 17:56:17 -0000	1.17
+++ skydefs.h	27 May 2003 16:42:20 -0000	1.18
@@ -26,6 +26,19 @@
 
 //This file is incomplete, several flags still missing.
 
+#define VIG_EN1 "Game over player one"
+#define VIG_EN2 "BE VIGILANT"
+#define VIG_DE1 "Das Spiel ist aus."
+#define VIG_DE2 "SEI WACHSAM"
+#define VIG_FR1 "Game over joueur 1"
+#define VIG_FR2 "SOYEZ VIGILANTS"
+#define VIG_SE1 "Spelet r slut, Agent 1."
+#define VIG_SE2 "VAR VAKSAM"
+#define VIG_IT1 "Game over giocatore 1"
+#define VIG_IT2 "SIATE VIGILANTI"
+#define VIG_PT1 "Fim de jogo para o jogador um"
+#define VIG_PT2 "BE VIGILANT"
+
 #define ST_COLLISION_BIT	5
 
 #define S_COUNT	0





More information about the Scummvm-git-logs mailing list