diff options
| -rw-r--r-- | engines/hopkins/anim.cpp | 21 | ||||
| -rw-r--r-- | engines/hopkins/computer.cpp | 46 | ||||
| -rw-r--r-- | engines/hopkins/debugger.cpp | 13 | ||||
| -rw-r--r-- | engines/hopkins/debugger.h | 2 | ||||
| -rw-r--r-- | engines/hopkins/dialogs.cpp | 23 | ||||
| -rw-r--r-- | engines/hopkins/events.cpp | 14 | ||||
| -rw-r--r-- | engines/hopkins/font.cpp | 6 | ||||
| -rw-r--r-- | engines/hopkins/graphics.cpp | 266 | ||||
| -rw-r--r-- | engines/hopkins/graphics.h | 39 | ||||
| -rw-r--r-- | engines/hopkins/hopkins.cpp | 31 | ||||
| -rw-r--r-- | engines/hopkins/objects.cpp | 22 | ||||
| -rw-r--r-- | engines/hopkins/script.cpp | 2 | 
12 files changed, 305 insertions, 180 deletions
| diff --git a/engines/hopkins/anim.cpp b/engines/hopkins/anim.cpp index 7b3c186623..ac15139cbd 100644 --- a/engines/hopkins/anim.cpp +++ b/engines/hopkins/anim.cpp @@ -100,6 +100,8 @@ void AnimationManager::playAnim(const Common::String &filename, uint32 rate1, ui  		else  			_vm->_graphicsManager.m_scroll16(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);  		_vm->_graphicsManager.unlockScreen(); + +		_vm->_graphicsManager.addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);  		_vm->_graphicsManager.updateScreen();  	}  	_vm->_eventsManager._rateCounter = 0; @@ -155,6 +157,8 @@ void AnimationManager::playAnim(const Common::String &filename, uint32 rate1, ui  					_vm->_graphicsManager.copyVideoVbe16(screenP);  				}  				_vm->_graphicsManager.unlockScreen(); + +				_vm->_graphicsManager.addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);  				_vm->_graphicsManager.updateScreen();  				_vm->_soundManager.checkSoundEnd();  			} @@ -263,6 +267,7 @@ void AnimationManager::playAnim2(const Common::String &filename, uint32 rate1, u  		_vm->_graphicsManager.lockScreen();  		_vm->_graphicsManager.clearScreen();  		_vm->_graphicsManager.unlockScreen(); +  		_vm->_graphicsManager._maxX = SCREEN_WIDTH;  		if (_vm->_graphicsManager.WinScan / 2 > SCREEN_WIDTH) {  			hasScreenCopy = true; @@ -280,7 +285,10 @@ void AnimationManager::playAnim2(const Common::String &filename, uint32 rate1, u  				_vm->_graphicsManager.m_scroll16A(screenCopy, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);  			else  				_vm->_graphicsManager.m_scroll16(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0); +  			_vm->_graphicsManager.unlockScreen(); + +			_vm->_graphicsManager.addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);  			_vm->_graphicsManager.updateScreen();  		}  		_vm->_eventsManager._rateCounter = 0; @@ -329,6 +337,8 @@ void AnimationManager::playAnim2(const Common::String &filename, uint32 rate1, u  				}  			}  			_vm->_graphicsManager.unlockScreen(); + +			_vm->_graphicsManager.addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);  			_vm->_graphicsManager.updateScreen();  			_vm->_soundManager.checkSoundEnd();  		} @@ -385,6 +395,7 @@ void AnimationManager::playAnim2(const Common::String &filename, uint32 rate1, u  	_vm->_graphicsManager.lockScreen();  	_vm->_graphicsManager.clearScreen();  	_vm->_graphicsManager.unlockScreen(); +  	_vm->_graphicsManager._scrollPosX = oldScrollPosX;  	_vm->_graphicsManager.scrollScreen(oldScrollPosX);  	if (_vm->_graphicsManager._largeScreenFl) { @@ -400,6 +411,8 @@ void AnimationManager::playAnim2(const Common::String &filename, uint32 rate1, u  		_vm->_graphicsManager.m_scroll16(_vm->_graphicsManager._vesaBuffer, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);  	}  	_vm->_graphicsManager.unlockScreen(); +	_vm->_graphicsManager.addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); +  	_vm->_graphicsManager.fadeInShort();  	_vm->_graphicsManager.updateScreen(); @@ -648,6 +661,8 @@ void AnimationManager::playSequence(const Common::String &file, uint32 rate1, ui  		else  			_vm->_graphicsManager.m_scroll16(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);  		_vm->_graphicsManager.unlockScreen(); + +		_vm->_graphicsManager.addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);  		_vm->_graphicsManager.updateScreen();  	}  	bool skipFl = false; @@ -728,6 +743,8 @@ void AnimationManager::playSequence(const Common::String &file, uint32 rate1, ui  				_vm->_graphicsManager.copyVideoVbe16a(screenP);  			}  			_vm->_graphicsManager.unlockScreen(); + +			_vm->_graphicsManager.addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);  			_vm->_graphicsManager.updateScreen();  			_vm->_soundManager.checkSoundEnd();  		} @@ -808,6 +825,8 @@ void AnimationManager::playSequence2(const Common::String &file, uint32 rate1, u  			else  				_vm->_graphicsManager.m_scroll16(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);  			_vm->_graphicsManager.unlockScreen(); + +			_vm->_graphicsManager.addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);  			_vm->_graphicsManager.updateScreen();  		}  		_vm->_eventsManager._rateCounter = 0; @@ -854,6 +873,8 @@ void AnimationManager::playSequence2(const Common::String &file, uint32 rate1, u  				_vm->_graphicsManager.copyVideoVbe16a(screenP);  			}  			_vm->_graphicsManager.unlockScreen(); + +			_vm->_graphicsManager.addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);  			_vm->_graphicsManager.updateScreen();  			_vm->_soundManager.checkSoundEnd();  		} diff --git a/engines/hopkins/computer.cpp b/engines/hopkins/computer.cpp index 82cd17a613..4e9ed83e99 100644 --- a/engines/hopkins/computer.cpp +++ b/engines/hopkins/computer.cpp @@ -127,7 +127,7 @@ void ComputerManager::setTextPosition(int yp, int xp) {   */  void ComputerManager::showComputer(ComputerEnum mode) {  	_vm->_eventsManager._escKeyFl = false; -	_vm->_graphicsManager.resetVesaSegment(); +	_vm->_graphicsManager.resetDirtyRects();  	setVideoMode();  	setTextColor(4);  	setTextPosition(2, 4); @@ -287,7 +287,7 @@ void ComputerManager::showComputer(ComputerEnum mode) {  	else // Free access or Samantha  		_vm->_globals._exitId = 14; -	_vm->_graphicsManager.resetVesaSegment(); +	_vm->_graphicsManager.resetDirtyRects();  }  static const char _englishText[] =  @@ -426,13 +426,13 @@ void ComputerManager::displayMessage(int xp, int yp, int textIdx) {  			x1 -= _vm->_fontManager._fontFixedWidth;  			x2 = x1 + 2 * _vm->_fontManager._fontFixedWidth;  			_vm->_graphicsManager.Copy_Mem(_vm->_graphicsManager._vesaScreen, x1, yp, 3 * _vm->_fontManager._fontFixedWidth, 12, _vm->_graphicsManager._vesaBuffer, x1, yp); -			_vm->_graphicsManager.addVesaSegment(x1, yp, x2, yp + 12); +			_vm->_graphicsManager.addDirtyRect(x1, yp, x2, yp + 12);  			_vm->_fontManager.displayTextVesa(x1, yp, "_", 252);  		}  		if (mappedChar != '*') {  			char newChar = mappedChar;  			_vm->_graphicsManager.Copy_Mem(_vm->_graphicsManager._vesaScreen, x1, yp, _vm->_fontManager._fontFixedWidth, 12, _vm->_graphicsManager._vesaBuffer, x1, yp); -			_vm->_graphicsManager.addVesaSegment(x1, yp, _vm->_fontManager._fontFixedWidth + x1, yp + 12); +			_vm->_graphicsManager.addDirtyRect(x1, yp, _vm->_fontManager._fontFixedWidth + x1, yp + 12);  			_inputBuf[textIndex] = newChar;  			Common::String charString = Common::String::format("%c_", newChar); @@ -444,7 +444,7 @@ void ComputerManager::displayMessage(int xp, int yp, int textIdx) {  	} while (textIndex != textIdx && curChar != 13);  	_vm->_graphicsManager.Copy_Mem(_vm->_graphicsManager._vesaScreen, x1, yp, _vm->_fontManager._fontFixedWidth, 12, _vm->_graphicsManager._vesaBuffer, x1, yp); -	_vm->_graphicsManager.addVesaSegment(x1, yp, _vm->_fontManager._fontFixedWidth + x1, yp + 12); +	_vm->_graphicsManager.addDirtyRect(x1, yp, _vm->_fontManager._fontFixedWidth + x1, yp + 12);  	_vm->_eventsManager.refreshScreenAndEvents();  	_inputBuf[textIndex] = 0; @@ -556,10 +556,12 @@ void ComputerManager::displayGamesSubMenu() {  	_breakoutSpr = _vm->_fileManager.loadFile("CASSE.SPR");  	loadHiscore();  	setModeVGA256(); +  	newLevel(); -	_vm->_graphicsManager.resetVesaSegment(); +	_vm->_graphicsManager.DD_VBL(); +  	playBreakout(); -	_vm->_graphicsManager.resetVesaSegment(); +	_vm->_graphicsManager.resetDirtyRects();  	_breakoutSpr = _vm->_globals.freeMemory(_breakoutSpr);  	_breakoutLevel = (int16 *)_vm->_globals.freeMemory((byte *)_breakoutLevel);  	_vm->_objectsManager._sprite[0]._spriteData = oldSpriteData; @@ -642,12 +644,15 @@ void ComputerManager::newLevel() {  	_breakoutLevel = (int16 *)_vm->_fileManager.loadFile(file);  	displayBricks(); +  	_vm->_objectsManager.addStaticSprite(_breakoutSpr, Common::Point(150, 192), 0, 13, 0, false, 0, 0);  	_vm->_objectsManager.addStaticSprite(_breakoutSpr, Common::Point(164, 187), 1, 14, 0, false, 0, 0); +  	_ballPosition = Common::Point(164, 187);  	_padPositionX = 150;  	_vm->_objectsManager.animateSprite(0);  	_vm->_objectsManager.animateSprite(1); +   	_vm->_eventsManager.mouseOn();  	_vm->_soundManager.playSample(3, 5);  } @@ -664,11 +669,11 @@ void ComputerManager::displayBricks() {  	int cellTop;  	int cellType;  	for (int levelIdx = 0; ; levelIdx += 6) { -		cellLeft = level[levelIdx]; +		cellLeft = (int16)FROM_LE_16(level[levelIdx]);  		if (cellLeft == -1)  			break; -		cellTop = level[levelIdx + 1]; -		cellType = level[levelIdx + 4]; +		cellTop = FROM_LE_16(level[levelIdx + 1]); +		cellType = FROM_LE_16(level[levelIdx + 4]);  		if (cellType <= 6)  			++_breakoutBrickNbr; @@ -696,8 +701,6 @@ void ComputerManager::displayBricks() {  			_vm->_graphicsManager.AFFICHE_SPEEDVGA(_breakoutSpr, cellLeft, cellTop, 23);  			break;  		} - -		levelIdx += 6;  	}  	displayScore(); @@ -712,6 +715,8 @@ void ComputerManager::displayLives() {  	for (int i = 0, xp = 10; i < _breakoutLives - 1; i++, xp += 7)  		_vm->_graphicsManager.AFFICHE_SPEEDVGA(_breakoutSpr, xp, 10, 14); + +	_vm->_graphicsManager.DD_VBL();  }  /** @@ -726,7 +731,8 @@ void ComputerManager::playBreakout() {  			_ballPosition = Common::Point(_padPositionX + 14, 187);  			_vm->_objectsManager.setSpriteY(1, 187);  			_vm->_objectsManager.setSpriteX(1, _ballPosition.x); -			_vm->_graphicsManager.resetVesaSegment(); + +			_vm->_graphicsManager.resetDirtyRects();  			_vm->_eventsManager.refreshScreenAndEvents();  			_vm->_graphicsManager.fadeInBreakout(); @@ -763,7 +769,7 @@ void ComputerManager::playBreakout() {  			} while (!_vm->shouldQuit() && !lastBreakoutEvent);  			if (lastBreakoutEvent != 1)  				break; -			_vm->_graphicsManager.fateOutBreakout(); +  			--_breakoutLives;  			if (_breakoutLives) { @@ -771,6 +777,8 @@ void ComputerManager::playBreakout() {  				if (_breakoutLives)  					continue;  			} + +			_vm->_graphicsManager.fadeOutBreakout();  			_vm->_eventsManager.mouseOn();  			_vm->_objectsManager.removeSprite(0);  			_vm->_objectsManager.removeSprite(1); @@ -791,7 +799,7 @@ void ComputerManager::playBreakout() {  		}  		if (lastBreakoutEvent != 2)  			return; -		_vm->_graphicsManager.fateOutBreakout(); +		_vm->_graphicsManager.fadeOutBreakout();  		newLevel();  	}  } @@ -801,7 +809,7 @@ void ComputerManager::playBreakout() {   * @return		The selected button index: 1 = Game, 2 = Quit   */  int ComputerManager::displayHiscores() { -	_vm->_graphicsManager.resetVesaSegment(); +	_vm->_graphicsManager.resetDirtyRects();  	loadHiscore();  	_vm->_graphicsManager.loadVgaImage("HISCORE.PCX");  	byte *ptr = _vm->_fileManager.loadFile("ALPHA.SPR"); @@ -827,7 +835,7 @@ int ComputerManager::displayHiscores() {  	}  	_vm->_graphicsManager.fadeInBreakout(); -	_vm->_graphicsManager.resetVesaSegment(); +	_vm->_graphicsManager.resetDirtyRects();  	int buttonIndex = 0;  	do {  		_vm->_eventsManager.refreshEvents(); @@ -843,7 +851,7 @@ int ComputerManager::displayHiscores() {  	} while (!buttonIndex && !_vm->shouldQuit());  	_vm->_eventsManager.mouseOff(); -	_vm->_graphicsManager.fateOutBreakout(); +	_vm->_graphicsManager.fadeOutBreakout();  	_vm->_globals.freeMemory(ptr);  	return buttonIndex;  } @@ -886,7 +894,7 @@ void ComputerManager::getScoreName() {  	for (int i = scoreLen, scorePos = 8; i >= 0; i--) {  		_score[5]._score.setChar(score[i], scorePos--);  	} -	_vm->_graphicsManager.fateOutBreakout(); +	_vm->_graphicsManager.fadeOutBreakout();  	_vm->_globals.freeMemory(ptr);  	saveScore();  } diff --git a/engines/hopkins/debugger.cpp b/engines/hopkins/debugger.cpp index 0abfd1f62e..07a0c92be6 100644 --- a/engines/hopkins/debugger.cpp +++ b/engines/hopkins/debugger.cpp @@ -30,10 +30,23 @@ namespace Hopkins {  Debugger::Debugger() : GUI::Debugger() {  	DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); +	DCmd_Register("rects", WRAP_METHOD(Debugger, cmd_DirtyRects));  }  void Debugger::setParent(HopkinsEngine *vm) {  	_vm = vm;  } +// Turns dirty rects on or off +bool Debugger::cmd_DirtyRects(int argc, const char **argv) { +	if (argc != 2) { +		DebugPrintf("%s: [on | off]\n", argv[0]); +		return true; +	} else { +		_vm->_graphicsManager._showDirtyRects = !strcmp(argv[1], "on"); +		return false; +	} +} + +  } // End of namespace Hopkins diff --git a/engines/hopkins/debugger.h b/engines/hopkins/debugger.h index aabc95c5f1..1ce018b38c 100644 --- a/engines/hopkins/debugger.h +++ b/engines/hopkins/debugger.h @@ -38,6 +38,8 @@ public:  	Debugger();  	virtual ~Debugger() {}  	void setParent(HopkinsEngine *vm); + +	bool cmd_DirtyRects(int argc, const char **argv);  };  } // End of namespace Hopkins diff --git a/engines/hopkins/dialogs.cpp b/engines/hopkins/dialogs.cpp index ad3e547508..9056101f76 100644 --- a/engines/hopkins/dialogs.cpp +++ b/engines/hopkins/dialogs.cpp @@ -303,8 +303,7 @@ void DialogsManager::showOptionsDialog() {  	_vm->_graphicsManager.copySurface(_vm->_graphicsManager._vesaScreen, scrollOffset + 164,  		107, 335, 215, _vm->_graphicsManager._vesaBuffer, scrollOffset + 164, 107); -	_vm->_graphicsManager.addVesaSegment(scrollOffset + 164, 107, -		scrollOffset + 498, 320); +	_vm->_graphicsManager.addDirtyRect(scrollOffset + 164, 107, scrollOffset + 498, 320);  	_vm->_globals._optionDialogSpr = _vm->_globals.freeMemory(_vm->_globals._optionDialogSpr);  	_vm->_globals._optionDialogFl = false; @@ -454,7 +453,7 @@ void DialogsManager::showInventory() {  	if (_inventDisplayedFl) {  		_inventDisplayedFl = false;  		_vm->_graphicsManager.copySurface(_vm->_graphicsManager._vesaScreen, _inventX, 114, _inventWidth, _inventHeight, _vm->_graphicsManager._vesaBuffer, _inventX, 114); -		_vm->_graphicsManager.addVesaSegment(_inventX, 114, _inventX + _inventWidth, _inventWidth + 114); +		_vm->_graphicsManager.addDirtyRect(_inventX, 114, _inventX + _inventWidth, _inventWidth + 114);  		_vm->_objectsManager.BOBTOUS = true;  	} @@ -486,7 +485,7 @@ void DialogsManager::inventAnim() {  	if (_vm->_objectsManager._eraseVisibleCounter && !_vm->_objectsManager._visibleFl) {  		_vm->_graphicsManager.copySurface(_vm->_graphicsManager._vesaScreen, _vm->_objectsManager._oldInventoryPosX, 27, 48, 38,  			_vm->_graphicsManager._vesaBuffer, _vm->_objectsManager._oldInventoryPosX, 27); -		_vm->_graphicsManager.addVesaSegment(_vm->_objectsManager._oldInventoryPosX, 27, _vm->_objectsManager._oldInventoryPosX + 48, 65); +		_vm->_graphicsManager.addDirtyRect(_vm->_objectsManager._oldInventoryPosX, 27, _vm->_objectsManager._oldInventoryPosX + 48, 65);  		--_vm->_objectsManager._eraseVisibleCounter;  	} @@ -496,10 +495,10 @@ void DialogsManager::inventAnim() {  		_vm->_graphicsManager.copySurface(_vm->_graphicsManager._vesaScreen, _vm->_objectsManager._oldInventoryPosX, 27, 48, 38,  			_vm->_graphicsManager._vesaBuffer, _vm->_objectsManager._oldInventoryPosX, 27); -		_vm->_graphicsManager.addVesaSegment(_vm->_objectsManager._oldInventoryPosX, 27, _vm->_objectsManager._oldInventoryPosX + 48, 65); +		_vm->_graphicsManager.addDirtyRect(_vm->_objectsManager._oldInventoryPosX, 27, _vm->_objectsManager._oldInventoryPosX + 48, 65);  		int newOffset = _vm->_graphicsManager._scrollOffset + 2;  		_vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _inventoryIcons, newOffset + 300, 327, 0); -		_vm->_graphicsManager.addVesaSegment(newOffset, 27, newOffset + 45, 62); +		_vm->_graphicsManager.addDirtyRect(newOffset, 27, newOffset + 45, 62);  		_vm->_objectsManager._oldInventoryPosX = newOffset;  	} @@ -508,17 +507,17 @@ void DialogsManager::inventAnim() {  			_vm->_graphicsManager.Affiche_Perfect(_vm->_graphicsManager._vesaBuffer, _vm->_objectsManager._headSprites, 832, 325, 0, 0, 0, false);  		if (_vm->_globals._saveData->_data[svField355] == 1)  			_vm->_graphicsManager.Affiche_Perfect(_vm->_graphicsManager._vesaBuffer, _vm->_objectsManager._headSprites, 866, 325, 1, 0, 0, false); -		_vm->_graphicsManager.addVesaSegment(532, 25, 560, 60); -		_vm->_graphicsManager.addVesaSegment(566, 25, 594, 60); +		_vm->_graphicsManager.addDirtyRect(532, 25, 560, 60); +		_vm->_graphicsManager.addDirtyRect(566, 25, 594, 60);  	}  	if (_vm->_globals._saveData->_data[svField356] == 1) {  		_vm->_graphicsManager.Affiche_Perfect(_vm->_graphicsManager._vesaBuffer, _vm->_objectsManager._headSprites, 832, 325, 0, 0, 0, false); -		_vm->_graphicsManager.addVesaSegment(532, 25, 560, 60); +		_vm->_graphicsManager.addDirtyRect(532, 25, 560, 60);  	}  	if (_vm->_globals._saveData->_data[svField354] == 1) {  		_vm->_graphicsManager.Affiche_Perfect(_vm->_graphicsManager._vesaBuffer, _vm->_objectsManager._headSprites, 832, 325, 0, 0, 0, false); -		_vm->_graphicsManager.addVesaSegment(532, 25, 560, 60); +		_vm->_graphicsManager.addDirtyRect(532, 25, 560, 60);  	}  } @@ -577,7 +576,7 @@ void DialogsManager::showLoadGame() {  	} while (!_vm->shouldQuit() && (!slotNumber || _vm->_eventsManager.getMouseButton() != 1));  	_vm->_objectsManager._saveLoadFl = false;  	_vm->_graphicsManager.copySurface(_vm->_graphicsManager._vesaScreen, _vm->_eventsManager._startPos.x + 183, 60, 274, 353, _vm->_graphicsManager._vesaBuffer, _vm->_eventsManager._startPos.x + 183, 60); -	_vm->_graphicsManager.addVesaSegment(_vm->_eventsManager._startPos.x + 183, 60, 457, 413); +	_vm->_graphicsManager.addDirtyRect(_vm->_eventsManager._startPos.x + 183, 60, 457, 413);  	_vm->_objectsManager.BOBTOUS = true;  	_vm->_objectsManager._saveLoadSprite = _vm->_globals.freeMemory(_vm->_objectsManager._saveLoadSprite);  	_vm->_objectsManager._saveLoadSprite2 = _vm->_globals.freeMemory(_vm->_objectsManager._saveLoadSprite2); @@ -606,7 +605,7 @@ void DialogsManager::showSaveGame() {  	_vm->_objectsManager._saveLoadFl = false;  	_vm->_graphicsManager.copySurface(_vm->_graphicsManager._vesaScreen, _vm->_eventsManager._startPos.x + 183, 60, 274, 353, _vm->_graphicsManager._vesaBuffer, _vm->_eventsManager._startPos.x + 183, 60); -	_vm->_graphicsManager.addVesaSegment(_vm->_eventsManager._startPos.x + 183, 60, _vm->_eventsManager._startPos.x + 457, 413); +	_vm->_graphicsManager.addDirtyRect(_vm->_eventsManager._startPos.x + 183, 60, _vm->_eventsManager._startPos.x + 457, 413);  	_vm->_objectsManager.BOBTOUS = true;  	_vm->_objectsManager._saveLoadSprite = _vm->_globals.freeMemory(_vm->_objectsManager._saveLoadSprite);  	_vm->_objectsManager._saveLoadSprite2 = _vm->_globals.freeMemory(_vm->_objectsManager._saveLoadSprite2); diff --git a/engines/hopkins/events.cpp b/engines/hopkins/events.cpp index 950ccc724d..506cb68b56 100644 --- a/engines/hopkins/events.cpp +++ b/engines/hopkins/events.cpp @@ -222,7 +222,7 @@ void EventsManager::checkForNextFrameCounter() {  	if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) {  		++_gameCounter;  		_priorFrameTime = milli; -		g_system->updateScreen(); +		_vm->_graphicsManager.DD_VBL();  		// Signal the ScummVM debugger  		_vm->_debugger.onFrame(); @@ -411,7 +411,7 @@ void EventsManager::refreshScreenAndEvents() {  		}  	} else if (yp < _vm->_graphicsManager._maxY && xp < _vm->_graphicsManager._maxX && width > 1 && height > 1) {  		_vm->_eventsManager.updateCursor(); -		_vm->_graphicsManager.addVesaSegment(xp, yp, right, bottom); +		_vm->_graphicsManager.addDirtyRect(xp, yp, right, bottom);  	}  	_vm->_globals._speed = 2; @@ -446,7 +446,7 @@ void EventsManager::refreshScreenAndEvents() {  	_vm->_globals._speed = 2;  	_rateCounter = 0;  	if (!_vm->_graphicsManager._largeScreenFl || _vm->_graphicsManager._scrollStatus == 1) { -		_vm->_graphicsManager.displayVesaSegment(); +		_vm->_graphicsManager.displayDirtyRects();  	} else {  		if (_vm->_graphicsManager._scrollStatus != 2) {  			if (getMouseX() > _vm->_graphicsManager._scrollPosX + 620) @@ -459,15 +459,17 @@ void EventsManager::refreshScreenAndEvents() {  		if (_vm->_graphicsManager._scrollPosX > SCREEN_WIDTH)  			_vm->_graphicsManager._scrollPosX = SCREEN_WIDTH;  		if (_vm->_graphicsManager._oldScrollPosX == _vm->_graphicsManager._scrollPosX) { -			_vm->_graphicsManager.displayVesaSegment(); +			_vm->_graphicsManager.displayDirtyRects();  		} else {  			_vm->_fontManager.hideText(9);  			_vm->_graphicsManager.lockScreen();  			_vm->_graphicsManager.m_scroll16(_vm->_graphicsManager._vesaBuffer, _vm->_graphicsManager._scrollPosX, 20, SCREEN_WIDTH, 440, 0, 20);  			_vm->_graphicsManager.unlockScreen(); -			_vm->_graphicsManager.dstrect[0] = Common::Rect(0, 20, SCREEN_WIDTH, 460); +			 +			_vm->_graphicsManager.resetRefreshRects(); +			_vm->_graphicsManager.addRefreshRect(0, 20, SCREEN_WIDTH, SCREEN_HEIGHT - 20); -			_vm->_graphicsManager.resetVesaSegment(); +			_vm->_graphicsManager.resetDirtyRects();  			_startPos.x = _vm->_graphicsManager._scrollPosX;  			_vm->_graphicsManager._scrollOffset = _vm->_graphicsManager._scrollPosX; diff --git a/engines/hopkins/font.cpp b/engines/hopkins/font.cpp index d0f7325710..864da4fd8d 100644 --- a/engines/hopkins/font.cpp +++ b/engines/hopkins/font.cpp @@ -182,7 +182,7 @@ void FontManager::box(int idx, int messageId, const Common::String &filename, in  				yp,  				_text[idx]._width,  				_text[idx]._height); -			_vm->_graphicsManager.addVesaSegment(xp, yp, xp + width, yp + height); +			_vm->_graphicsManager.addDirtyRect(xp, yp, xp + width, yp + height);  		}  	} else {  		int lineCount = 0; @@ -421,7 +421,7 @@ void FontManager::displayTextVesa(int xp, int yp, const Common::String &message,  		}  	} -	_vm->_graphicsManager.addVesaSegment(xp, yp, currentX, yp + 12); +	_vm->_graphicsManager.addDirtyRect(xp, yp, currentX, yp + 12);  }  /** @@ -479,7 +479,7 @@ void FontManager::renderTextDisplay(int xp, int yp, const Common::String &msg, i  			int charStartPosX = charEndPosX;  			charEndPosX += charWidth; -			_vm->_graphicsManager.addVesaSegment(charStartPosX, yp, charEndPosX, yp + 12); +			_vm->_graphicsManager.addDirtyRect(charStartPosX, yp, charEndPosX, yp + 12);  			if (_vm->_eventsManager._escKeyFl) {  				_vm->_globals.iRegul = 1;  				_vm->_eventsManager.refreshScreenAndEvents(); diff --git a/engines/hopkins/graphics.cpp b/engines/hopkins/graphics.cpp index 9f4c910ff3..09fe2f1f2a 100644 --- a/engines/hopkins/graphics.cpp +++ b/engines/hopkins/graphics.cpp @@ -47,7 +47,10 @@ GraphicsManager::GraphicsManager() {  	_scrollPosX = 0;  	_largeScreenFl = false;  	_oldScrollPosX = 0; -	NBBLOC = 0; +	_vesaScreen = NULL; +	_vesaBuffer = NULL; +	_screenBuffer = NULL; +	_showDirtyRects = false;  	_lineNbr2 = 0;  	Agr_x = Agr_y = 0; @@ -72,15 +75,12 @@ GraphicsManager::GraphicsManager() {  	Common::fill(&_colorTable[0], &_colorTable[PALETTE_EXT_BLOCK_SIZE], 0);  	Common::fill(&_palette[0], &_palette[PALETTE_EXT_BLOCK_SIZE], 0);  	Common::fill(&_oldPalette[0], &_oldPalette[PALETTE_EXT_BLOCK_SIZE], 0); - -	for (int i = 0; i < 250; ++i) -		Common::fill((byte *)&BLOC[i], (byte *)&BLOC[i] + sizeof(BlocItem), 0); -  }  GraphicsManager::~GraphicsManager() {  	_vm->_globals.freeMemory(_vesaScreen);  	_vm->_globals.freeMemory(_vesaBuffer); +	_vm->_globals.freeMemory(_screenBuffer);  }  void GraphicsManager::setParent(HopkinsEngine *vm) { @@ -107,14 +107,13 @@ void GraphicsManager::setGraphicalMode(int width, int height) {  		// Init surfaces  		_vesaScreen = _vm->_globals.allocMemory(SCREEN_WIDTH * 2 * SCREEN_HEIGHT);  		_vesaBuffer = _vm->_globals.allocMemory(SCREEN_WIDTH * 2 * SCREEN_HEIGHT); +		_screenBuffer = _vm->_globals.allocMemory(SCREEN_WIDTH * 2 * SCREEN_HEIGHT);  		_videoPtr = NULL;  		_screenWidth = width;  		_screenHeight = height; -		// Clear the screen pitch. This will be set on the first lockScreen call -		WinScan = 0; - +		WinScan = SCREEN_WIDTH * 2;  		PAL_PIXELS = SD_PIXELS;  		_lineNbr = width; @@ -128,14 +127,12 @@ void GraphicsManager::setGraphicalMode(int width, int height) {   * (try to) Lock Screen   */  void GraphicsManager::lockScreen() { -	if (_skipVideoLockFl) -		return; - -	if (_lockCounter++ == 0) { -		_videoPtr = g_system->lockScreen(); -		if (WinScan == 0) -			WinScan = _videoPtr->pitch; -	} +	if (!_skipVideoLockFl) { +		if (_lockCounter++ == 0) { +			_videoPtr = _screenBuffer; +			WinScan = SCREEN_WIDTH * 2; +		} +	}		  }  /** @@ -144,7 +141,6 @@ void GraphicsManager::lockScreen() {  void GraphicsManager::unlockScreen() {  	assert(_videoPtr);  	if (--_lockCounter == 0) { -		g_system->unlockScreen();  		_videoPtr = NULL;  	}  } @@ -154,7 +150,15 @@ void GraphicsManager::unlockScreen() {   */  void GraphicsManager::clearScreen() {  	assert(_videoPtr); -	_videoPtr->fillRect(Common::Rect(0, 0, _screenWidth, _screenHeight), 0); + +	Common::fill(_screenBuffer, _screenBuffer + WinScan * _screenHeight, 0); +	addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); +} + +void GraphicsManager::clearVesaScreen() { +	Common::fill(_vesaScreen, _vesaScreen + WinScan * _screenHeight, 0); +	Common::fill(_vesaBuffer, _vesaBuffer + WinScan * _screenHeight, 0); +	addDirtyRect(Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));  }  /** @@ -181,6 +185,7 @@ void GraphicsManager::loadVgaImage(const Common::String &file) {  	lockScreen();  	copy16bFromSurfaceScaleX2(_vesaBuffer); +	addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);  	unlockScreen();  	fadeInBreakout(); @@ -191,6 +196,7 @@ void GraphicsManager::loadVgaImage(const Common::String &file) {   */  void GraphicsManager::loadScreen(const Common::String &file) {  	Common::File f; +	assert(!_videoPtr);  	bool flag = true;  	if (_vm->_fileManager.searchCat(file, RES_PIC) == g_PTRNUL) { @@ -230,7 +236,7 @@ void GraphicsManager::loadScreen(const Common::String &file) {  		}  	} -	memcpy(_vesaBuffer, _vesaScreen, SCREEN_WIDTH * 2 * SCREEN_HEIGHT); +	memcpy(_vesaBuffer, _vesaScreen, SCREEN_WIDTH * 2 * SCREEN_HEIGHT);	  }  void GraphicsManager::initColorTable(int minIndex, int maxIndex, byte *palette) { @@ -396,14 +402,10 @@ void GraphicsManager::loadPCX320(byte *surface, const Common::String &file, byte  }  // Clear Palette -// CHECKME: Some versions of the game don't include it, some contains nothing more than  -// than a loop doing nothing, some others just map the last value. While debugging, it -// seems that this function is called once the palette is already cleared, so it would be useless -// This code could most likely be removed.  void GraphicsManager::clearPalette() { -	uint16 col0 = mapRGB(0, 0, 0); -	for (int i = 0; i < 512; i += 2) -		WRITE_LE_UINT16(&SD_PIXELS[i], col0); +	// As weird as it sounds, this is what the original Linux executable does,  +	// and not a full array clear. +	SD_PIXELS[0] = 0;  }  void GraphicsManager::setScreenWidth(int pitch) { @@ -418,7 +420,7 @@ void GraphicsManager::m_scroll16(const byte *surface, int xs, int ys, int width,  	assert(_videoPtr);  	const byte *srcP = xs + _lineNbr2 * ys + surface; -	byte *destP = (byte *)_videoPtr->pixels + destX * 2 + WinScan * destY; +	byte *destP = (byte *)_videoPtr + destX * 2 + WinScan * destY;  	for (int yp = 0; yp < height; ++yp) {  		// Copy over the line, using the source pixels as lookups into the pixels palette @@ -437,6 +439,7 @@ void GraphicsManager::m_scroll16(const byte *surface, int xs, int ys, int width,  	}  	unlockScreen(); +	addRefreshRect(destX, destY, destX + width, destY + height);  }  // TODO: See if PAL_PIXELS can be converted to a uint16 array @@ -449,7 +452,7 @@ void GraphicsManager::m_scroll16A(const byte *surface, int xs, int ys, int width  	assert(_videoPtr);  	const byte *srcP = xs + _lineNbr2 * ys + surface; -	byte *destP = (byte *)_videoPtr->pixels + destX + destX + WinScan * destY; +	byte *destP = (byte *)_videoPtr + destX + destX + WinScan * destY;  	int yNext = height;  	Agr_x = 0;  	Agr_y = 0; @@ -495,6 +498,8 @@ void GraphicsManager::m_scroll16A(const byte *surface, int xs, int ys, int width  		srcP = _lineNbr2 + srcCopyP;  		yNext = yCtr - 1;  	} while (yCtr != 1); + +	addRefreshRect(destX, destY, destX + width, destY + width);  }  void GraphicsManager::Copy_Vga16(const byte *surface, int xp, int yp, int width, int height, int destX, int destY) { @@ -507,7 +512,7 @@ void GraphicsManager::Copy_Vga16(const byte *surface, int xp, int yp, int width,  	assert(_videoPtr);  	const byte *srcP = surface + xp + 320 * yp; -	byte *destP = (byte *)_videoPtr->pixels + 30 * WinScan + destX + destX + destX + destX + WinScan * 2 * destY; +	byte *destP = (byte *)_videoPtr + 30 * WinScan + destX + destX + destX + destX + WinScan * 2 * destY;  	int yCount = height;  	int xCount = width; @@ -532,6 +537,8 @@ void GraphicsManager::Copy_Vga16(const byte *surface, int xp, int yp, int width,  		srcP = loopSrcP + 320;  		yCount = yCtr - 1;  	} while (yCtr != 1); + +	addRefreshRect(destX, destY, destX + width, destY + width);  }  /**  @@ -603,7 +610,8 @@ void GraphicsManager::fadeOut(const byte *palette, int step, const byte *surface  	setPaletteVGA256(palData);  	m_scroll16(surface, _vm->_eventsManager._startPos.x, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0); -	return updateScreen(); + +	updateScreen();  }  /**  @@ -668,7 +676,7 @@ void GraphicsManager::fadeInBreakout() {  /**    * Fade out used by for the breakout mini-game   */ -void GraphicsManager::fateOutBreakout() { +void GraphicsManager::fadeOutBreakout() {  	byte palette[PALETTE_EXT_BLOCK_SIZE];  	memset(palette, 0, PALETTE_EXT_BLOCK_SIZE); @@ -727,6 +735,11 @@ uint16 GraphicsManager::mapRGB(byte r, byte g, byte b) {  void GraphicsManager::updateScreen() {  	// TODO: Is this okay here? +	// Display any aras of the screen that need refreshing +	displayDirtyRects(); +	displayRefreshRects(); + +	// Update the screen  	g_system->updateScreen();  } @@ -817,7 +830,7 @@ void GraphicsManager::copyVideoVbe16(const byte *srcData) {  			if (srcByte == 211) {  				int pixelCount = srcP[1];  				int pixelIndex = srcP[2]; -				byte *destP = (byte *)_videoPtr->pixels + destOffset * 2; +				byte *destP = (byte *)_videoPtr + destOffset * 2;  				destOffset += pixelCount;  				while (pixelCount--) { @@ -830,7 +843,7 @@ void GraphicsManager::copyVideoVbe16(const byte *srcData) {  			} else {  				int pixelCount = srcByte - 211;  				int pixelIndex = srcP[1]; -				byte *destP = (byte *)_videoPtr->pixels + destOffset * 2; +				byte *destP = (byte *)_videoPtr + destOffset * 2;  				destOffset += pixelCount;  				while (pixelCount--) { @@ -842,7 +855,7 @@ void GraphicsManager::copyVideoVbe16(const byte *srcData) {  				srcP += 2;  			}  		} else { -			byte *destP = (byte *)_videoPtr->pixels + destOffset * 2; +			byte *destP = (byte *)_videoPtr + destOffset * 2;  			destP[0] = PAL_PIXELS[2 * srcByte];  			destP[1] = PAL_PIXELS[(2 * srcByte) + 1];  			++srcP; @@ -876,7 +889,7 @@ void GraphicsManager::copyVideoVbe16a(const byte *srcData) {  			}  		} -		WRITE_LE_UINT16((byte *)_videoPtr->pixels + destOffset * 2, READ_LE_UINT16(PAL_PIXELS + 2 * srcByte)); +		WRITE_LE_UINT16((byte *)_videoPtr + destOffset * 2, READ_LE_UINT16(PAL_PIXELS + 2 * srcByte));  		++srcP;  		++destOffset;  	} @@ -1080,86 +1093,139 @@ void GraphicsManager::displayAllBob() {  	}  } -void GraphicsManager::resetVesaSegment() { -	for (int idx = 0; idx <= NBBLOC; idx++) -		BLOC[idx]._activeFl = false; - -	NBBLOC = 0; -} - -// Add VESA Segment -void GraphicsManager::addVesaSegment(int x1, int y1, int x2, int y2) { -	int tempX = x1; -	bool addFlag = true; -	if (x2 > _maxX) -		x2 = _maxX; -	if (y2 > _maxY) -		y2 = _maxY; -	if (x1 < _minX) -		tempX = _minX; -	if (y1 < _minY) -		y1 = _minY; - -	for (int blocIndex = 0; blocIndex <= NBBLOC; blocIndex++) { -		BlocItem &bloc = BLOC[blocIndex]; -		if (bloc._activeFl && tempX >= bloc._x1 && x2 <= bloc._x2 && y1 >= bloc._y1 && y2 <= bloc._y2) -			addFlag = false; -	}; - -	if (addFlag) { -		assert(NBBLOC < 250); -		BlocItem &bloc = BLOC[++NBBLOC]; - -		bloc._activeFl = true; -		bloc._x1 = tempX; -		bloc._x2 = x2; -		bloc._y1 = y1; -		bloc._y2 = y2; +void GraphicsManager::resetDirtyRects() { +	_dirtyRects.clear(); +} + +void GraphicsManager::resetRefreshRects() { +	_refreshRects.clear(); +} + +// Add a game area dirty rectangle +void GraphicsManager::addDirtyRect(int x1, int y1, int x2, int y2) { +	x1 = CLIP(x1, _minX, _maxX); +	y1 = CLIP(y1, _minY, _maxY); +	x2 = CLIP(x2, _minX, _maxX); +	y2 = CLIP(y2, _minY, _maxY); + +	if ((x2 > x1) && (y2 > y1))	 +		addRectToArray(_dirtyRects, Common::Rect(x1, y1, x2, y2)); +} + +// Add a refresh rect +void GraphicsManager::addRefreshRect(int x1, int y1, int x2, int y2) { +	x1 = MAX(x1, 0); +	y1 = MAX(y1, 0); +	x2 = MIN(x2, SCREEN_WIDTH); +	y2 = MIN(y2, SCREEN_HEIGHT); + +	if ((x2 > x1) && (y2 > y1)) +		addRectToArray(_refreshRects, Common::Rect(x1, y1, x2, y2)); +} + +void GraphicsManager::addRectToArray(Common::Array<Common::Rect> &rects, const Common::Rect &newRect) { +	// Scan for an intersection with existing rects +	uint rectIndex; +	for (rectIndex = 0; rectIndex < rects.size(); ++rectIndex) { +		Common::Rect &r = rects[rectIndex]; +		 +		if (r.intersects(newRect)) { +			// Rect either intersects or is completely inside existing one, so extend existing one as necessary +			r.extend(newRect); +			break; +		} +	} +	if (rectIndex == rects.size()) { +		// Rect not intersecting any existing one, so add it in +		assert(rects.size() < DIRTY_RECTS_SIZE); +		rects.push_back(newRect); +	} + +	// Take care of merging the existing rect list. This is done as a separate check even if +	// a previous extending above has been done, since the merging of the new rect above may +	// result in further rects now able to be merged + +	for (int srcIndex = rects.size() - 1; srcIndex > 0; --srcIndex) { +		const Common::Rect &srcRect = rects[srcIndex]; + +		// Loop through all the other rects to see if it intersects them +		for (int destIndex = srcIndex - 1; destIndex >= 0; --destIndex) { +			if (rects[destIndex].intersects(srcRect)) { +				// Found an intersection, so extend the found one, and delete the original +				rects[destIndex].extend(srcRect); +				rects.remove_at(srcIndex); +				break; +			} +		}  	}  } -// Display VESA Segment -void GraphicsManager::displayVesaSegment() { -	if (NBBLOC == 0) +// Draw any game dirty rects onto the screen intermediate surface +void GraphicsManager::displayDirtyRects() { +	if (_dirtyRects.size() == 0)  		return;  	lockScreen(); - -	for (int idx = 1; idx <= NBBLOC; ++idx) { -		BlocItem &bloc = BLOC[idx]; -		Common::Rect &dstRect = dstrect[idx - 1]; -		if (!bloc._activeFl) -			continue; +	 +	// Refresh the entire screen  +	for (uint idx = 0; idx < _dirtyRects.size(); ++idx) { +		Common::Rect &r = _dirtyRects[idx]; +		Common::Rect dstRect;  		if (_vm->_eventsManager._breakoutFl) { -			Copy_Vga16(_vesaBuffer, bloc._x1, bloc._y1, bloc._x2 - bloc._x1, bloc._y2 - bloc._y1, bloc._x1, bloc._y1); -			dstRect.left = bloc._x1 * 2; -			dstRect.top = bloc._y1 * 2 + 30; -			dstRect.setWidth((bloc._x2 - bloc._x1) * 2); -			dstRect.setHeight((bloc._y2 - bloc._y1) * 2); -		} else if (bloc._x2 > _vm->_eventsManager._startPos.x && bloc._x1 < _vm->_eventsManager._startPos.x + SCREEN_WIDTH) { -			if (bloc._x1 < _vm->_eventsManager._startPos.x) -				bloc._x1 = _vm->_eventsManager._startPos.x; -			if (bloc._x2 > _vm->_eventsManager._startPos.x + SCREEN_WIDTH) -				bloc._x2 = _vm->_eventsManager._startPos.x + SCREEN_WIDTH; +			Copy_Vga16(_vesaBuffer, r.left, r.top, r.right - r.left, r.bottom - r.top, r.left, r.top); +			dstRect.left = r.left * 2; +			dstRect.top = r.top * 2 + 30; +			dstRect.setWidth((r.right - r.left) * 2); +			dstRect.setHeight((r.bottom - r.top) * 2); +		} else if (r.right > _vm->_eventsManager._startPos.x && r.left < _vm->_eventsManager._startPos.x + SCREEN_WIDTH) { +			if (r.left < _vm->_eventsManager._startPos.x) +				r.left = _vm->_eventsManager._startPos.x; +			if (r.right > _vm->_eventsManager._startPos.x + SCREEN_WIDTH) +				r.right = _vm->_eventsManager._startPos.x + SCREEN_WIDTH;  			// WORKAROUND: Original didn't lock the screen for access  			lockScreen(); -			m_scroll16(_vesaBuffer, bloc._x1, bloc._y1, bloc._x2 - bloc._x1, bloc._y2 - bloc._y1, bloc._x1 - _vm->_eventsManager._startPos.x, bloc._y1); +			m_scroll16(_vesaBuffer, r.left, r.top, r.right - r.left, r.bottom - r.top, r.left - _vm->_eventsManager._startPos.x, r.top); -			dstRect.left = bloc._x1 - _vm->_eventsManager._startPos.x; -			dstRect.top = bloc._y1; -			dstRect.setWidth(bloc._x2 - bloc._x1); -			dstRect.setHeight(bloc._y2 - bloc._y1); +			dstRect.left = r.left - _vm->_eventsManager._startPos.x; +			dstRect.top = r.top; +			dstRect.setWidth(r.right - r.left); +			dstRect.setHeight(r.bottom - r.top);  			unlockScreen();  		} -		BLOC[idx]._activeFl = false; +		// If it's a valid rect, then add it to the list of areas to refresh on the screen +		if (dstRect.isValidRect() && dstRect.width() > 0 && dstRect.height() > 0) +			addRectToArray(_refreshRects, dstRect);  	} -	NBBLOC = 0;  	unlockScreen(); +	resetDirtyRects(); +} + +void GraphicsManager::displayRefreshRects() { +	Graphics::Surface *screenSurface = NULL; +	if (_showDirtyRects) { +		screenSurface = g_system->lockScreen(); +		g_system->copyRectToScreen(_screenBuffer, WinScan, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); +	} +	// Loop through copying over any  specified rects to the screen +	for (uint idx = 0; idx < _refreshRects.size(); ++idx) { +		const Common::Rect &r = _refreshRects[idx]; + +		byte *srcP = _screenBuffer + WinScan * r.top + (r.left * 2); +		g_system->copyRectToScreen(srcP, WinScan, r.left, r.top, r.width(), r.height()); + +		if (_showDirtyRects) +			screenSurface->frameRect(r, 0xffffff); +	} + +	if (_showDirtyRects) +		g_system->unlockScreen(); + +	resetRefreshRects();  }  void GraphicsManager::AFFICHE_SPEEDVGA(const byte *objectData, int xp, int yp, int idx, bool addSegment) { @@ -1173,7 +1239,7 @@ void GraphicsManager::AFFICHE_SPEEDVGA(const byte *objectData, int xp, int yp, i  		Sprite_Vesa(_vesaScreen, objectData, xp + 300, yp + 300, idx);  	}  	if (addSegment) -		addVesaSegment(xp, yp, xp + width, yp + height); +		addDirtyRect(xp, yp, xp + width, yp + height);  }  /** @@ -1185,7 +1251,7 @@ void GraphicsManager::copy16bFromSurfaceScaleX2(const byte *surface) {  	assert(_videoPtr);  	const byte *curSurface = surface; -	byte *destPtr = 30 * WinScan + (byte *)_videoPtr->pixels; +	byte *destPtr = 30 * WinScan + (byte *)_videoPtr;  	for (int y = 200; y; y--) {  		byte *oldDestPtr = destPtr;  		for (int x = 320; x; x--) { @@ -1592,7 +1658,7 @@ void GraphicsManager::fastDisplay(const byte *spriteData, int xp, int yp, int sp  		Sprite_Vesa(_vesaScreen, spriteData, xp + 300, yp + 300, spriteIndex);  	}  	if (addSegment) -		addVesaSegment(xp, yp, xp + width, yp + height); +		addDirtyRect(xp, yp, xp + width, yp + height);  }  void GraphicsManager::copySurface(const byte *surface, int x1, int y1, int width, int height, byte *destSurface, int destX, int destY) { @@ -1618,7 +1684,7 @@ void GraphicsManager::copySurface(const byte *surface, int x1, int y1, int width  	if (croppedWidth > 0 && croppedHeight > 0) {  		int height2 = croppedHeight;  		Copy_Mem(surface, left, top, croppedWidth, croppedHeight, destSurface, destX, destY); -		addVesaSegment(left, top, left + croppedWidth, top + height2); +		addDirtyRect(left, top, left + croppedWidth, top + height2);  	}  } diff --git a/engines/hopkins/graphics.h b/engines/hopkins/graphics.h index 620c1b7d32..eb1a79d707 100644 --- a/engines/hopkins/graphics.h +++ b/engines/hopkins/graphics.h @@ -24,6 +24,7 @@  #define HOPKINS_GRAPHICS_H  #include "common/scummsys.h" +#include "common/array.h"  #include "common/endian.h"  #include "common/rect.h"  #include "common/str.h" @@ -31,6 +32,7 @@  namespace Hopkins { +#define DIRTY_RECTS_SIZE 250  #define PALETTE_SIZE 256  #define PALETTE_BLOCK_SIZE (PALETTE_SIZE * 3)  #define PALETTE_EXT_BLOCK_SIZE 800 @@ -45,14 +47,6 @@ struct RGB8 {  	byte b;  }; -struct BlocItem { -	uint16 _activeFl; -	int _x1; -	int _y1; -	int _x2; -	int _y2; -}; -  class HopkinsEngine;  class GraphicsManager { @@ -63,7 +57,7 @@ private:  	bool _initGraphicsFl;  	int _screenWidth;  	int _screenHeight; -	Graphics::Surface *_videoPtr; +	byte *_videoPtr;  	int _width;  	int _posXClipped, _posYClipped;  	bool _clipFl; @@ -94,6 +88,7 @@ public:  	byte _oldPalette[PALETTE_EXT_BLOCK_SIZE];  	byte *_vesaScreen;  	byte *_vesaBuffer; +	byte *_screenBuffer;  	int _scrollOffset;  	int _scrollPosX;  	bool _largeScreenFl; @@ -103,13 +98,19 @@ public:  	int _minX, _minY;  	int _maxX, _maxY;  	bool _noFadingFl; -	Common::Rect dstrect[50];  	int _scrollStatus;  	bool _skipVideoLockFl;  	int _fadeDefaultSpeed; -	int NBBLOC; -	BlocItem BLOC[250]; +	/** +	 * The _dirtyRects list contains paletted game areas that need to be redrawn.  +	 * The _dstrect array is the list of areas of the screen that ScummVM needs to be redrawn. +	 * Some areas, such as the animation managers, skip the _dirtyRects and use _dstrec directly. +	 */ +	Common::Array<Common::Rect> _dirtyRects; +	Common::Array<Common::Rect> _refreshRects; +	bool _showDirtyRects; +  	int WinScan;  	byte *PAL_PIXELS;  	bool MANU_SCROLL; @@ -123,7 +124,15 @@ public:  	void unlockScreen();  	void clearPalette();  	void clearScreen(); -	void addVesaSegment(int x1, int y1, int x2, int y2); +	void clearVesaScreen(); +	void resetDirtyRects(); +	void resetRefreshRects(); +	void addDirtyRect(int x1, int y1, int x2, int y2); +	void addDirtyRect(const Common::Rect &r) { addDirtyRect(r.left, r.top, r.right, r.bottom); } +	void addRefreshRect(int x1, int y1, int x2, int y2); +	void addRectToArray(Common::Array<Common::Rect> &rects, const Common::Rect &newRect); +	void displayDirtyRects(); +	void displayRefreshRects();  	void copySurface(const byte *surface, int x1, int y1, int width, int height, byte *destSurface, int destX, int destY);  	void loadImage(const Common::String &file);  	void loadVgaImage(const Common::String &file); @@ -132,12 +141,10 @@ public:  	void fadeInDefaultLength(const byte *surface);  	void fadeInShort();  	void fadeOutDefaultLength(const byte *surface); -	void fateOutBreakout(); +	void fadeOutBreakout();  	void fadeOutLong();  	void fadeOutShort();  	void fastDisplay(const byte *spriteData, int xp, int yp, int spriteIndex, bool addSegment = true); -	void displayVesaSegment(); -	void resetVesaSegment();  	void copyWinscanVbe3(const byte *srcData, byte *destSurface);  	void copyWinscanVbe(const byte *srcP, byte *destP);  	void copyVideoVbe16(const byte *srcData); diff --git a/engines/hopkins/hopkins.cpp b/engines/hopkins/hopkins.cpp index 55062a12a9..2821746232 100644 --- a/engines/hopkins/hopkins.cpp +++ b/engines/hopkins/hopkins.cpp @@ -172,7 +172,7 @@ bool HopkinsEngine::runWin95Demo() {  			}  		} -		if (g_system->getEventManager()->shouldQuit()) +		if (shouldQuit())  			return false;  		switch (_globals._exitId) { @@ -343,7 +343,7 @@ bool HopkinsEngine::runWin95Demo() {  			memset(_graphicsManager._vesaBuffer, 0, 307200);  			memset(_graphicsManager._vesaScreen, 0, 307200);  			_graphicsManager.clearPalette(); -			_graphicsManager.resetVesaSegment(); +			_graphicsManager.resetDirtyRects();  			break;  		case 114: @@ -452,14 +452,14 @@ bool HopkinsEngine::runLinuxDemo() {  		if (!_globals._exitId) {  			_globals._exitId = _menuManager.menu();  			if (_globals._exitId == -1) { -				if (!g_system->getEventManager()->shouldQuit()) +				if (!shouldQuit())  					endLinuxDemo();  				_globals.PERSO = _globals.freeMemory(_globals.PERSO);  				restoreSystem();  			}  		} -		if (g_system->getEventManager()->shouldQuit()) +		if (shouldQuit())  			return false;  		switch (_globals._exitId) { @@ -661,7 +661,7 @@ bool HopkinsEngine::runLinuxDemo() {  			memset(_graphicsManager._vesaBuffer, 0, 307200);  			memset(_graphicsManager._vesaScreen, 0, 307200);  			_graphicsManager.clearPalette(); -			_graphicsManager.resetVesaSegment(); +			_graphicsManager.resetDirtyRects();  			break;  		case 114: @@ -757,6 +757,7 @@ bool HopkinsEngine::runFull() {  		_graphicsManager.fadeInLong();  		_eventsManager.delay(500);  		_graphicsManager.fadeOutLong(); +		_graphicsManager.clearVesaScreen();  	} else {  		// This piece of code, though named "display_version" in the original,   		// displays a "loading please wait" screen. @@ -764,6 +765,8 @@ bool HopkinsEngine::runFull() {  		_graphicsManager.fadeInLong();  		_eventsManager.delay(500);  		_graphicsManager.fadeOutLong(); +		_graphicsManager.clearVesaScreen(); +  		_globals.iRegul = 1;  	} @@ -787,8 +790,11 @@ bool HopkinsEngine::runFull() {  		_graphicsManager.fadeOutLong();  	} -	if (!_eventsManager._escKeyFl) +	if (!_eventsManager._escKeyFl) {  		playIntro(); +		if (shouldQuit()) +			return false; +	}  	if (getPlatform() != Common::kPlatformLinux) {  		_graphicsManager.fadeOutShort();  		_graphicsManager.loadImage("H2"); @@ -816,7 +822,7 @@ bool HopkinsEngine::runFull() {  			}  		} -		if (g_system->getEventManager()->shouldQuit()) +		if (shouldQuit())  			return false;  		switch (_globals._exitId) { @@ -1434,7 +1440,7 @@ bool HopkinsEngine::runFull() {  			memset(_graphicsManager._vesaBuffer, 0, 307200);  			memset(_graphicsManager._vesaScreen, 0, 307200);  			_graphicsManager.clearPalette(); -			_graphicsManager.resetVesaSegment(); +			_graphicsManager.resetDirtyRects();  			break;  		case 114: @@ -1893,7 +1899,7 @@ void HopkinsEngine::restoreSystem() {  void HopkinsEngine::endLinuxDemo() {  	_globals._linuxEndDemoFl = true; -	_graphicsManager.resetVesaSegment(); +	_graphicsManager.resetDirtyRects();  	_objectsManager._forestFl = false;  	_eventsManager._breakoutFl = false;  	_globals._disableInventFl = true; @@ -1912,7 +1918,7 @@ void HopkinsEngine::endLinuxDemo() {  		if (_eventsManager.getMouseButton() == 1)  			mouseClicked = true; -	} while (!mouseClicked && !g_system->getEventManager()->shouldQuit()); +	} while (!mouseClicked && !shouldQuit());  	// Original tried to open a web browser link here. Since ScummVM doesn't support  	// that, it's being skipped in favor of simply exiting @@ -2505,7 +2511,7 @@ void HopkinsEngine::displayCredits() {  		_globals._creditsEndX = -1;  		_globals._creditsStartY = -1;  		_globals._creditsEndY = -1; -	} while ((_eventsManager.getMouseButton() != 1) && (!g_system->getEventManager()->shouldQuit())); +	} while ((_eventsManager.getMouseButton() != 1) && (!shouldQuit()));  	_graphicsManager.fadeOutLong();  	_globals.iRegul = 1;  	_eventsManager._mouseFl = true; @@ -2800,8 +2806,9 @@ void HopkinsEngine::handleOceanMaze(int16 curExitId, Common::String backgroundFi  			handleOceanMouseEvents();  		_linesManager.checkZone();  		setSubmarineSprites(); +  		_eventsManager.refreshScreenAndEvents(); -		if (_globals._exitId || g_system->getEventManager()->shouldQuit()) +		if (_globals._exitId || shouldQuit())  			break;  	} diff --git a/engines/hopkins/objects.cpp b/engines/hopkins/objects.cpp index d262ff653b..4c1b5949dc 100644 --- a/engines/hopkins/objects.cpp +++ b/engines/hopkins/objects.cpp @@ -414,7 +414,7 @@ void ObjectsManager::displaySprite() {  			_vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_dialogsManager._inventBuf2, _oldBorderPos.x + 300, _oldBorderPos.y + 300, _oldBorderSpriteIndex + 1);  		if (_borderPos.x && _borderPos.y)  			_vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_dialogsManager._inventBuf2, _borderPos.x + 300, _borderPos.y + 300, _borderSpriteIndex); -		_vm->_graphicsManager.addVesaSegment(_vm->_dialogsManager._inventX, _vm->_dialogsManager._inventY, _vm->_dialogsManager._inventX + _vm->_dialogsManager._inventWidth, _vm->_dialogsManager._inventY + _vm->_dialogsManager._inventHeight); +		_vm->_graphicsManager.addDirtyRect(_vm->_dialogsManager._inventX, _vm->_dialogsManager._inventY, _vm->_dialogsManager._inventX + _vm->_dialogsManager._inventWidth, _vm->_dialogsManager._inventY + _vm->_dialogsManager._inventHeight);  	}  	if (_saveLoadFl) { @@ -422,7 +422,7 @@ void ObjectsManager::displaySprite() {  		if (_saveLoadX && _saveLoadY)  			_vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _saveLoadSprite2, _saveLoadX + _vm->_eventsManager._startPos.x + 300, _saveLoadY + 300, 0); -		_vm->_graphicsManager.addVesaSegment(_vm->_eventsManager._startPos.x + 183, 60, _vm->_eventsManager._startPos.x + 457, 413); +		_vm->_graphicsManager.addDirtyRect(_vm->_eventsManager._startPos.x + 183, 60, _vm->_eventsManager._startPos.x + 457, 413);  	}  	// If the Options dialog is activated, draw the elements @@ -443,7 +443,7 @@ void ObjectsManager::displaySprite() {  			_vm->_eventsManager._startPos.x + 600, 522, _vm->_globals._menuDisplayType);  		_vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_globals._optionDialogSpr,  			_vm->_eventsManager._startPos.x + 611, 502, _vm->_globals._menuScrollSpeed); -		_vm->_graphicsManager.addVesaSegment(_vm->_eventsManager._startPos.x + 164, 107, _vm->_eventsManager._startPos.x + 498, 320); +		_vm->_graphicsManager.addDirtyRect(_vm->_eventsManager._startPos.x + 164, 107, _vm->_eventsManager._startPos.x + 498, 320);  	}  	// Loop to draw any on-screen text @@ -565,7 +565,7 @@ void ObjectsManager::setBobInfo(int idx) {  		_vm->_globals.Liste2[idx]._visibleFl = false;  	if (_vm->_globals.Liste2[idx]._visibleFl) -		_vm->_graphicsManager.addVesaSegment( +		_vm->_graphicsManager.addDirtyRect(               _vm->_globals.Liste2[idx]._posX,               _vm->_globals.Liste2[idx]._posY,               _vm->_globals.Liste2[idx]._posX + _vm->_globals.Liste2[idx]._width, @@ -808,7 +808,7 @@ void ObjectsManager::DEF_SPRITE(int idx) {  		list->_visibleFl = false;  	if (list->_visibleFl) -		_vm->_graphicsManager.addVesaSegment( list->_posX, list->_posY, list->_posX + list->_width, list->_posY + list->_height); +		_vm->_graphicsManager.addDirtyRect( list->_posX, list->_posY, list->_posX + list->_width, list->_posY + list->_height);  }  void ObjectsManager::displayHiding(int idx) { @@ -816,7 +816,7 @@ void ObjectsManager::displayHiding(int idx) {  	_vm->_graphicsManager.Sprite_Vesa(_vm->_graphicsManager._vesaBuffer, _vm->_globals._hidingItemData[1],   		hid->_x + 300, hid->_y + 300, hid->_spriteIndex); -	_vm->_graphicsManager.addVesaSegment(hid->_x, hid->_y, hid->_x + hid->_width, hid->_y + hid->_height); +	_vm->_graphicsManager.addDirtyRect(hid->_x, hid->_y, hid->_x + hid->_width, hid->_y + hid->_height);  }  // Compute Sprite @@ -1078,7 +1078,7 @@ void ObjectsManager::displayVBob() {  			_vm->_graphicsManager.restoreSurfaceRect(_vm->_graphicsManager._vesaBuffer, vbob->_surface,  				vbob->_xp, vbob->_yp, width, height); -			_vm->_graphicsManager.addVesaSegment(vbob->_xp, vbob->_yp, vbob->_xp + width, height + vbob->_yp); +			_vm->_graphicsManager.addDirtyRect(vbob->_xp, vbob->_yp, vbob->_xp + width, height + vbob->_yp);  			vbob->_surface = _vm->_globals.freeMemory(vbob->_surface);  			vbob->field4 = 0; @@ -1102,7 +1102,7 @@ void ObjectsManager::displayVBob() {  			_vm->_graphicsManager.restoreSurfaceRect(_vm->_graphicsManager._vesaBuffer, vbob->_surface,  				vbob->_oldX, vbob->_oldY, width, height); -			_vm->_graphicsManager.addVesaSegment(vbob->_oldX, vbob->_oldY, vbob->_oldX + width, vbob->_oldY + height); +			_vm->_graphicsManager.addDirtyRect(vbob->_oldX, vbob->_oldY, vbob->_oldX + width, vbob->_oldY + height);  			vbob->field4 = 1;  			vbob->_oldSpriteData = vbob->_spriteData; @@ -1141,7 +1141,7 @@ void ObjectsManager::displayVBob() {  					vbob->_xp + 300, vbob->_yp + 300, vbob->_frameIndex);  			} -			_vm->_graphicsManager.addVesaSegment(vbob->_xp, vbob->_yp , vbob->_xp + width, vbob->_yp + height); +			_vm->_graphicsManager.addDirtyRect(vbob->_xp, vbob->_yp , vbob->_xp + width, vbob->_yp + height);  			vbob->field4 = 2;  		}  	} @@ -2077,7 +2077,7 @@ void ObjectsManager::clearScreen() {  	_changeVerbFl = false;  	_vm->_linesManager._route = (RouteItem *)g_PTRNUL;  	_vm->_globals._oldDirection = DIR_NONE; -	_vm->_graphicsManager.resetVesaSegment(); +	_vm->_graphicsManager.resetDirtyRects();  }  /** @@ -2090,7 +2090,7 @@ void ObjectsManager::changeCharacterHead(PlayerCharacter oldCharacter, PlayerCha  	_changeHeadFl = true;  	_vm->_graphicsManager.copySurface(_vm->_graphicsManager._vesaScreen, 532, 25, 65, 40, _vm->_graphicsManager._vesaBuffer, 532, 25); -	_vm->_graphicsManager.addVesaSegment(532, 25, 597, 65); +	_vm->_graphicsManager.addDirtyRect(532, 25, 597, 65);  	_vm->_globals._checkDistanceFl = true;  	_vm->_linesManager._route = (RouteItem *)g_PTRNUL; diff --git a/engines/hopkins/script.cpp b/engines/hopkins/script.cpp index 92374495c6..a81a48174a 100644 --- a/engines/hopkins/script.cpp +++ b/engines/hopkins/script.cpp @@ -2353,7 +2353,7 @@ int ScriptManager::handleOpcode(byte *dataP) {  				memcpy(_vm->_graphicsManager._oldPalette, _vm->_graphicsManager._palette, 769);  				_vm->_animationManager.playAnim2("PLAN.ANM", 50, 10, 800);  			} -			_vm->_graphicsManager.NBBLOC = 0; +			_vm->_graphicsManager.resetDirtyRects();  			break;  		case 608: | 
