[Scummvm-git-logs] scummvm branch-2-7 -> 8b1448d70dc765eb2d2370f17ff16752b2fc5f3e
neuromancer
noreply at scummvm.org
Mon Mar 20 10:08:08 UTC 2023
This automated email contains information about 47 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
486a6de365 FREESCAPE: refactor to use executeMovementConditions instead of executeLocalGlobalConditions directly
cf2e7ef2e6 FREESCAPE: read strings from dark EGA releases (and demo)
ad46a1dd29 FREESCAPE: refactor game bits handling and set bit 31 when colliding
cc0832e739 FREESCAPE: improve dark UI for dos release and demo
8b0cfe0f4b FREESCAPE: implemented area connections in dark
d207536738 FREESCAPE: implemented fullscreen messages in dark dos demo
875940674e FREESCAPE: load some? global objects in dark for dos (and demo)
7b307e562b FREESCAPE: drafted code that reads title image of driller US release for DOS
523bc141fe FREESCAPE: initial implementation of image parsing for title/borders in driller
2e652a9861 FREESCAPE: load title/borders images in driller dos directly from the game data
05f7253af3 FREESCAPE: load title/borders images in driller EGA directly from the game data
cc42bc2efb FREESCAPE: load title/borders images in dark side EGA (and demo) directly from the game data
76c2a780a4 FREESCAPE: load title/borders images in total eclipse EGA directly from the game data
94c52bf7bf FREESCAPE: implemented scr image loader and read title/borders images in driller for zx directly from the game data
71e6e2b1f1 FREESCAPE: renamed game data file for driller detection in several platforms
a62b58adca FREESCAPE: small adjustments for driller ui for zx
752d202f46 FREESCAPE: refactored deobfuscation code for driller cpc
11dfbe8b72 FREESCAPE: fixed image loader and read title in driller for ega and updated freescape.dat
caa6e9c104 FREESCAPE: refactored driller dos code into a directory
fa75a25946 FREESCAPE: refactored driller cpc code into a directory
563c6b35bd FREESCAPE: refactored driller zx code into a directory
3e5d0a3ad0 FREESCAPE: refactored driller amiga/atari code into a directory
6ae0763ee4 FREESCAPE: refactored/moved driller code for loading assets in different platforms code
edc1322b0b FREESCAPE: refactored/moved driller code specific for the atari release
c22636621e FREESCAPE: fixed artifacts when using stipple effect in opengl
366c5c6bba FREESCAPE: fixed _lastMinute initialization for driller amiga/atari
e539c32167 FREESCAPE: simplified loading of data files in driller cpc
8a0acc1440 FREESCAPE: enable some spfx effects for different platforms (zx, cpc)
8227c50b44 FREESCAPE: use managed surfaces for border and title images
9b0f5b3de3 FREESCAPE: allow to change the palette of title and border per level using managed surfaces
d909a548e4 FREESCAPE: load original images and adjust ui for driller cpc
4633fd4874 FREESCAPE: load correct border palette for certain driller releases
6dc129dc34 FREESCAPE: color and ui fixes for driller cpc
c77e280500 FREESCAPE: correctly parse images in dos driller demo and removed extra files from freescape.dat
ef1a07d8f5 FREESCAPE: removed edsk related code to parse cpc releases of driller
cc7bb7d660 FREESCAPE: load and show driller dos demo title image
b4f7bc818d FREESCAPE: moved dark side related code to its own directory
82813e11d6 FREESCAPE: moved some functions to the main freescape class and reorganized game code
98a2bbb4f0 FREESCAPE: moved more functions to the main freescape class and reorganized game code
3b135c9ed8 FREESCAPE: moved code from dark dos release into its dedicated file
0154df5c8b FREESCAPE: simplified driller cpc color handling code
35492b4673 FREESCAPE: commented unused variable
55ae8e4096 FREESCAPE: pregenerate and show stipple patterns for driller in zx, cpc and cga
3dfd360667 FREESCAPE: improved stipple generation
e6b033b409 FREESCAPE: improved and optimized stipple pattern usage
59cae6551a FREESCAPE: avoid crash selecting a missing palette in driller demo for amiga/atari
8b1448d70d FREESCAPE: disallow crossair to be outside the view area
Commit: 486a6de365539d92ee77ad4b05f1e0b9dc66a2f3
https://github.com/scummvm/scummvm/commit/486a6de365539d92ee77ad4b05f1e0b9dc66a2f3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:11:45+01:00
Commit Message:
FREESCAPE: refactor to use executeMovementConditions instead of executeLocalGlobalConditions directly
Changed paths:
engines/freescape/freescape.cpp
engines/freescape/freescape.h
engines/freescape/games/dark.cpp
engines/freescape/movement.cpp
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index af8278fcbca..c542f5ab4d6 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -517,6 +517,11 @@ void FreescapeEngine::processInput() {
}
}
+void FreescapeEngine::executeMovementConditions() {
+ // Only execute "on collision" room/global conditions
+ executeLocalGlobalConditions(false, true);
+}
+
void FreescapeEngine::updateTimeVariables() {
int seconds, minutes, hours;
getTimeFromCountdown(seconds, minutes, hours);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index b4641f73912..5747f2825aa 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -237,6 +237,7 @@ public:
bool checkCollisions(bool executeCode);
Math::Vector3d _objExecutingCodeSize;
+ virtual void executeMovementConditions();
void executeObjectConditions(GeometricObject *obj, bool shot, bool collided);
void executeLocalGlobalConditions(bool shot, bool collided);
void executeCode(FCLInstructionVector &code, bool shot, bool collided);
@@ -356,7 +357,7 @@ public:
int _lastMinute;
void getTimeFromCountdown(int &seconds, int &minutes, int &hours);
- void updateTimeVariables();
+ virtual void updateTimeVariables();
// Cheats
bool _useExtendedTimer;
@@ -438,11 +439,16 @@ public:
DarkEngine(OSystem *syst, const ADGameDescription *gd);
void loadAssets() override;
+ void initGameState() override;
+
void gotoArea(uint16 areaID, int entranceID) override;
void pressedKey(const int keycode) override;
void loadAssetsDemo();
void loadAssetsFullGame();
+ int _lastTenSeconds;
+ void updateTimeVariables() override;
+ void executeMovementConditions() override;
void drawUI() override;
Common::Error saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave = false) override;
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index cf338790f29..55d33f0bead 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -35,6 +35,7 @@ DarkEngine::DarkEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEn
_playerHeight = _playerHeights[_playerHeightNumber];
_playerWidth = 12;
_playerDepth = 32;
+ _lastTenSeconds = -1;
}
void DarkEngine::loadAssets() {
@@ -67,6 +68,31 @@ void DarkEngine::loadAssetsDemo() {
error("Invalid or unsupported render mode %s for Dark Side", Common::getRenderModeDescription(_renderMode));
}
+void DarkEngine::initGameState() {
+ _flyMode = false;
+ _noClipMode = false;
+ _shootingFrames = 0;
+ _underFireFrames = 0;
+ _yaw = 0;
+ _pitch = 0;
+
+ for (int i = 0; i < k8bitMaxVariable; i++) // TODO: check maximum variable
+ _gameStateVars[i] = 0;
+
+ for (auto &it : _areaMap) {
+ it._value->resetArea();
+ _gameStateBits[it._key] = 0;
+ }
+
+ _playerHeightNumber = 1;
+ _playerHeight = _playerHeights[_playerHeightNumber];
+ removeTimers();
+ startCountdown(_initialCountdown);
+ _lastMinute = 0;
+ _demoIndex = 0;
+ _demoEvents.clear();
+}
+
void DarkEngine::loadAssetsFullGame() {
Common::File file;
if (_renderMode == Common::kRenderEGA) {
@@ -155,6 +181,30 @@ void DarkEngine::pressedKey(const int keycode) {
}
}
+void DarkEngine::executeMovementConditions() {
+ // Only execute "on collision" room/global conditions
+ if (_currentArea->getAreaFlags() == 1)
+ executeLocalGlobalConditions(false, true);
+}
+
+void DarkEngine::updateTimeVariables() {
+ // This function only executes "on collision" room/global conditions
+ int seconds, minutes, hours;
+ getTimeFromCountdown(seconds, minutes, hours);
+ if (_lastTenSeconds != seconds / 10) {
+ _lastTenSeconds = seconds / 10;
+ if (_currentArea->getAreaFlags() == 0)
+ executeLocalGlobalConditions(false, true);
+ }
+
+ if (_lastMinute != minutes) {
+ _lastMinute = minutes;
+ _gameStateVars[0x1e] += 1;
+ _gameStateVars[0x1f] += 1;
+ executeLocalGlobalConditions(false, true);
+ }
+}
+
void DarkEngine::drawUI() {
uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index d3db2059aaf..69f7c3b1561 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -149,7 +149,7 @@ void FreescapeEngine::rise() {
_lastPosition = _position;
debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
- executeLocalGlobalConditions(false, true); // Only execute "on collision" room/global conditions
+ executeMovementConditions();
}
void FreescapeEngine::lower() {
@@ -174,7 +174,7 @@ void FreescapeEngine::lower() {
_lastPosition = _position;
debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
- executeLocalGlobalConditions(false, true); // Only execute "on collision" room/global conditions
+ executeMovementConditions();
}
void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
@@ -267,7 +267,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
//debugC(1, kFreescapeDebugMove, "player height: %f", _position.y() - areaScale * _playerHeight);
if (_currentArea->getAreaID() == previousAreaID)
- executeLocalGlobalConditions(false, true); // Only execute "on collision" room/global conditions
+ executeMovementConditions();
}
bool FreescapeEngine::checkFloor(Math::Vector3d currentPosition) {
Commit: cf2e7ef2e66cbab6719b45a84b7b03135e29f39f
https://github.com/scummvm/scummvm/commit/cf2e7ef2e66cbab6719b45a84b7b03135e29f39f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:11:58+01:00
Commit Message:
FREESCAPE: read strings from dark EGA releases (and demo)
Changed paths:
engines/freescape/games/dark.cpp
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 55d33f0bead..70307ccc113 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -53,7 +53,7 @@ void DarkEngine::loadAssetsDemo() {
if (!file.isOpen())
error("Failed to open DSIDEE.EXE");
-
+ loadMessagesFixedSize(&file, 0x4525, 16, 27);
loadFonts(&file, 0xa598);
load8bitBinary(&file, 0xa700, 16);
} else if (isDOS() && _renderMode == Common::kRenderCGA) {
@@ -103,6 +103,7 @@ void DarkEngine::loadAssetsFullGame() {
error("Failed to open DSIDEE.EXE");
loadFonts(&file, 0xa113);
+ loadMessagesFixedSize(&file, 0x4525, 16, 27);
load8bitBinary(&file, 0xa280, 16);
} else if (_renderMode == Common::kRenderCGA) {
loadBundledImages();
Commit: ad46a1dd2921a44035ee400a1375c2085911a5fa
https://github.com/scummvm/scummvm/commit/ad46a1dd2921a44035ee400a1375c2085911a5fa
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:12:06+01:00
Commit Message:
FREESCAPE: refactor game bits handling and set bit 31 when colliding
Changed paths:
engines/freescape/freescape.cpp
engines/freescape/freescape.h
engines/freescape/language/instruction.cpp
engines/freescape/movement.cpp
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index c542f5ab4d6..f02e22ff73f 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -645,6 +645,19 @@ bool FreescapeEngine::checkIfGameEnded() {
return false; // TODO
}
+void FreescapeEngine::setGameBit(int index) {
+ _gameStateBits[_currentArea->getAreaID()] |= (1 << (index - 1));
+}
+
+void FreescapeEngine::clearGameBit(int index) {
+ _gameStateBits[_currentArea->getAreaID()] &= ~(1 << (index - 1));
+}
+
+void FreescapeEngine::toggleGameBit(int index) {
+ _gameStateBits[_currentArea->getAreaID()] ^= (1 << (index - 1));
+}
+
+
void FreescapeEngine::initGameState() {
for (int i = 0; i < k8bitMaxVariable; i++) // TODO: check maximum variable
_gameStateVars[i] = 0;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 5747f2825aa..8403333de22 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -325,6 +325,10 @@ public:
// Game state
virtual void initGameState();
+ void setGameBit(int index);
+ void clearGameBit(int index);
+ void toggleGameBit(int index);
+
StateVars _gameStateVars;
StateBits _gameStateBits;
virtual bool checkIfGameEnded();
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index ef9e656ffa9..3389ca99493 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -446,23 +446,23 @@ void FreescapeEngine::executeGoto(FCLInstruction &instruction) {
}
void FreescapeEngine::executeSetBit(FCLInstruction &instruction) {
- uint16 index = instruction._source - 1; // Starts in 1
- assert(index < 32);
- _gameStateBits[_currentArea->getAreaID()] |= (1 << index);
+ uint16 index = instruction._source; // Starts at 1
+ assert(index > 0 && index <= 32);
+ setGameBit(index);
debugC(1, kFreescapeDebugCode, "Setting bit %d", index);
- // debug("v: %d", (_gameStateBits[_currentArea->getAreaID()] & (1 << index)));
}
void FreescapeEngine::executeClearBit(FCLInstruction &instruction) {
- uint16 index = instruction._source - 1; // Starts in 1
- assert(index < 32);
- _gameStateBits[_currentArea->getAreaID()] &= ~(1 << index);
+ uint16 index = instruction._source; // Starts at 1
+ assert(index > 0 && index <= 32);
+ clearGameBit(index);
debugC(1, kFreescapeDebugCode, "Clearing bit %d", index);
}
void FreescapeEngine::executeToggleBit(FCLInstruction &instruction) {
- uint16 index = instruction._source - 1; // Starts in 1
- _gameStateBits[_currentArea->getAreaID()] ^= (1 << index);
+ uint16 index = instruction._source; // Starts at 1
+ assert(index > 0 && index <= 32);
+ toggleGameBit(index);
debugC(1, kFreescapeDebugCode, "Toggling bit %d", index);
}
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 69f7c3b1561..35e537ff8d2 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -239,10 +239,12 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
playSound(3, false);
}
debugC(1, kFreescapeDebugCode, "Runing effects:");
+ if (_flyMode)
+ setGameBit(31);
checkCollisions(true); // run the effects
} else {
debugC(1, kFreescapeDebugCode, "Runing effects: at: %f, %f, %f", _position.x(), _position.y(), _position.z());
-
+ setGameBit(31);
checkCollisions(true); // run the effects
if (_currentArea->getAreaID() == previousAreaID) {
if (_flyMode)
@@ -268,6 +270,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
//debugC(1, kFreescapeDebugMove, "player height: %f", _position.y() - areaScale * _playerHeight);
if (_currentArea->getAreaID() == previousAreaID)
executeMovementConditions();
+ clearGameBit(31);
}
bool FreescapeEngine::checkFloor(Math::Vector3d currentPosition) {
Commit: cc0832e739ec82b4a4c5e4f2af47a82c22f15e13
https://github.com/scummvm/scummvm/commit/cc0832e739ec82b4a4c5e4f2af47a82c22f15e13
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:12:18+01:00
Commit Message:
FREESCAPE: improve dark UI for dos release and demo
Changed paths:
engines/freescape/freescape.h
engines/freescape/games/dark.cpp
engines/freescape/loaders/8bitBinaryLoader.cpp
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 8403333de22..1ac2e84d572 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -442,6 +442,9 @@ class DarkEngine : public FreescapeEngine {
public:
DarkEngine(OSystem *syst, const ADGameDescription *gd);
+ uint32 _initialFuel;
+ uint32 _initialShield;
+
void loadAssets() override;
void initGameState() override;
@@ -455,6 +458,7 @@ public:
void executeMovementConditions() override;
void drawUI() override;
+ void drawDOSUI(Graphics::Surface *surface);
Common::Error saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave = false) override;
Common::Error loadGameStreamExtended(Common::SeekableReadStream *stream) override;
};
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 70307ccc113..55dfb12d2a8 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -36,6 +36,16 @@ DarkEngine::DarkEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEn
_playerWidth = 12;
_playerDepth = 32;
_lastTenSeconds = -1;
+
+ _angleRotations.push_back(5);
+ _angleRotations.push_back(10);
+ _angleRotations.push_back(15);
+ _angleRotations.push_back(30);
+ _angleRotations.push_back(45);
+ _angleRotations.push_back(90);
+
+ _initialFuel = 11;
+ _initialShield = 15;
}
void DarkEngine::loadAssets() {
@@ -84,6 +94,9 @@ void DarkEngine::initGameState() {
_gameStateBits[it._key] = 0;
}
+ _gameStateVars[k8bitVariableEnergy] = _initialFuel;
+ _gameStateVars[k8bitVariableShield] = _initialShield;
+
_playerHeightNumber = 1;
_playerHeight = _playerHeights[_playerHeightNumber];
removeTimers();
@@ -206,13 +219,73 @@ void DarkEngine::updateTimeVariables() {
}
}
-void DarkEngine::drawUI() {
- uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
- uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
- uint32 black = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
+void DarkEngine::drawDOSUI(Graphics::Surface *surface) {
+ uint32 color = _renderMode == Common::kRenderCGA ? 1 : 14;
+ uint8 r, g, b;
+
+ _gfx->readFromPalette(color, r, g, b);
+ uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+ color = _currentArea->_usualBackgroundColor;
+ if (_gfx->_colorRemaps && _gfx->_colorRemaps->contains(color)) {
+ color = (*_gfx->_colorRemaps)[color];
+ }
+
+ _gfx->readFromPalette(color, r, g, b);
+ uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+ int score = _gameStateVars[k8bitVariableScore];
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 199, 137, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 199, 145, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 199, 153, front, back, surface);
+
+ drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 71, 168, front, back, surface);
+ drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 71, 177, front, back, surface);
+ drawStringInSurface(Common::String::format("%07d", score), 95, 8, front, back, surface);
+
+ int seconds, minutes, hours;
+ getTimeFromCountdown(seconds, minutes, hours);
+ // TODO: implement binary clock
+
+ Common::String message;
+ int deadline;
+ getLatestMessages(message, deadline);
+ if (deadline <= _countdown) {
+ drawStringInSurface(message, 112, 177, back, front, surface);
+ _temporaryMessages.push_back(message);
+ _temporaryMessageDeadlines.push_back(deadline);
+ } else
+ drawStringInSurface(_currentArea->_name, 112, 177, front, back, surface);
+
+ int energy = _gameStateVars[k8bitVariableEnergy]; // called fuel in this game
+ int shield = _gameStateVars[k8bitVariableShield];
+
+ _gfx->readFromPalette(9, r, g, b);
+ uint32 blue = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+ if (shield >= 0) {
+ Common::Rect shieldBar;
+ shieldBar = Common::Rect(72, 139, 151 - (k8bitMaxShield - shield), 146);
+ surface->fillRect(shieldBar, front);
+
+ shieldBar = Common::Rect(72, 140, 151 - (k8bitMaxShield - shield), 145);
+ surface->fillRect(shieldBar, blue);
+ }
+
+ if (energy >= 0) {
+ Common::Rect energyBar;
+ energyBar = Common::Rect(72, 147, 151 - (k8bitMaxEnergy - energy), 154);
+ surface->fillRect(energyBar, front);
+ energyBar = Common::Rect(72, 148, 151 - (k8bitMaxEnergy - energy), 153);
+ surface->fillRect(energyBar, blue);
+ }
+}
+
+void DarkEngine::drawUI() {
Graphics::Surface *surface = nullptr;
- if (_border) {
+ if (_border) { // This can be removed when all the borders are loaded
+ uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
surface = new Graphics::Surface();
surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
surface->fillRect(_fullscreenViewArea, gray);
@@ -220,14 +293,10 @@ void DarkEngine::drawUI() {
} else
return;
- if (_currentAreaMessages.size() == 1) {
- int score = _gameStateVars[k8bitVariableScore];
- drawStringInSurface(_currentAreaMessages[0], 112, 177, yellow, black, surface);
- drawStringInSurface(Common::String::format("%04d", 2 * int(_position.x())), 199, 137, yellow, black, surface);
- drawStringInSurface(Common::String::format("%04d", 2 * int(_position.z())), 199, 145, yellow, black, surface);
- drawStringInSurface(Common::String::format("%04d", 2 * int(_position.y())), 199, 153, yellow, black, surface);
- drawStringInSurface(Common::String::format("%07d", score), 95, 8, yellow, black, surface);
- }
+ if (isDOS())
+ drawDOSUI(surface);
+ else
+ error("UI not implemented yet");
if (!_uiTexture)
_uiTexture = _gfx->createTexture(surface);
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index ff395a1a2ce..80a5e6b6fbb 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -438,6 +438,15 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
debugC(1, kFreescapeDebugParser, "Start area: %d", startArea);
uint8 startEntrance = readField(file, 8);
debugC(1, kFreescapeDebugParser, "Entrace area: %d", startEntrance);
+ readField(file, 8); // Unknown
+
+ uint8 initialEnergy1 = readField(file, 8);
+ uint8 initialShield1 = readField(file, 8);
+ uint8 initialEnergy2 = readField(file, 8);
+ uint8 initialShield2 = readField(file, 8);
+
+ debugC(1, kFreescapeDebugParser, "Initial levels of energy: %d and shield: %d", initialEnergy1, initialShield1);
+ debugC(1, kFreescapeDebugParser, "Initial levels of energy: %d and shield: %d", initialEnergy2, initialShield2);
if (isAmiga() || isAtariST())
file->seek(offset + 0x14);
Commit: 8b0cfe0f4be35b9237a593f2bcd19a9d047a19d7
https://github.com/scummvm/scummvm/commit/8b0cfe0f4be35b9237a593f2bcd19a9d047a19d7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:12:28+01:00
Commit Message:
FREESCAPE: implemented area connections in dark
Changed paths:
A engines/freescape/objects/connections.h
engines/freescape/freescape.h
engines/freescape/games/dark.cpp
engines/freescape/loaders/8bitBinaryLoader.cpp
engines/freescape/movement.cpp
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 1ac2e84d572..a7ec3096b61 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -187,6 +187,7 @@ public:
void generateDemoInput();
virtual void pressedKey(const int keycode);
void move(CameraMovement direction, uint8 scale, float deltaTime);
+ virtual void checkIfStillInArea();
void changePlayerHeight(int index);
void increaseStepSize();
void decreaseStepSize();
@@ -449,6 +450,7 @@ public:
void initGameState() override;
void gotoArea(uint16 areaID, int entranceID) override;
+ void checkIfStillInArea() override;
void pressedKey(const int keycode) override;
void loadAssetsDemo();
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 55dfb12d2a8..60e1b86bfd0 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -23,6 +23,7 @@
#include "freescape/freescape.h"
#include "freescape/language/8bitDetokeniser.h"
+#include "freescape/objects/connections.h"
namespace Freescape {
@@ -195,6 +196,30 @@ void DarkEngine::pressedKey(const int keycode) {
}
}
+void DarkEngine::checkIfStillInArea() {
+ AreaConnections *cons = (AreaConnections *)_currentArea->entranceWithID(254);
+ if (!cons) {
+ FreescapeEngine::checkIfStillInArea();
+ return;
+ }
+
+ int nextAreaID = 0;
+
+ if (_position.z() >= 4064 - 16)
+ nextAreaID = cons->_connections[1];
+ else if (_position.x() >= 4064 - 16)
+ nextAreaID = cons->_connections[3];
+ else if (_position.z() <= 16)
+ nextAreaID = cons->_connections[5];
+ else if (_position.x() <= 16)
+ nextAreaID = cons->_connections[7];
+
+ if (nextAreaID > 0)
+ gotoArea(nextAreaID, 0);
+ else
+ FreescapeEngine::checkIfStillInArea();
+}
+
void DarkEngine::executeMovementConditions() {
// Only execute "on collision" room/global conditions
if (_currentArea->getAreaFlags() == 1)
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 80a5e6b6fbb..b0b2edefc0c 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -26,6 +26,7 @@
#include "freescape/freescape.h"
#include "freescape/language/8bitDetokeniser.h"
+#include "freescape/objects/connections.h"
#include "freescape/objects/global.h"
#include "freescape/objects/group.h"
#include "freescape/objects/sensor.h"
@@ -115,6 +116,21 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
while(--byteSizeOfObject > 0)
structureArray.push_back(file->readByte());
return new GlobalStructure(structureArray);
+ } else if (objectID == 254 && objectType == ObjectType::kEntranceType) {
+ debugC(1, kFreescapeDebugParser, "Found the area connections (objectID: 254 with size %d)", byteSizeOfObject + 6);
+ Common::Array<uint8> connectionsArray;
+ connectionsArray.push_back(uint8(position.x()));
+ connectionsArray.push_back(uint8(position.y()));
+ connectionsArray.push_back(uint8(position.z()));
+
+ connectionsArray.push_back(uint8(v.x()));
+ connectionsArray.push_back(uint8(v.y()));
+ connectionsArray.push_back(uint8(v.z()));
+
+ byteSizeOfObject++;
+ while(--byteSizeOfObject > 0)
+ connectionsArray.push_back(file->readByte());
+ return new AreaConnections(connectionsArray);
}
debugC(1, kFreescapeDebugParser, "Object %d ; type %d ; size %d", objectID, (int)objectType, byteSizeOfObject);
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 35e537ff8d2..c9055e80248 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -177,6 +177,17 @@ void FreescapeEngine::lower() {
executeMovementConditions();
}
+void FreescapeEngine::checkIfStillInArea() {
+ for (int i = 0; i < 3; i++) {
+ if (_position.getValue(i) < 0)
+ _position.setValue(i, 0);
+ else if (_position.getValue(i) > 8128)
+ _position.setValue(i, 8128);
+ }
+ if (_position.y() >= 2016)
+ _position.y() = _lastPosition.z();
+}
+
void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTime) {
debugC(1, kFreescapeDebugMove, "old player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
int previousAreaID = _currentArea->getAreaID();
@@ -207,14 +218,9 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
if (!_flyMode)
_position.set(_position.x(), positionY, _position.z());
- for (int i = 0; i < 3; i++) {
- if (_position.getValue(i) < 0)
- _position.setValue(i, 0);
- else if (_position.getValue(i) > 8128)
- _position.setValue(i, 8128);
- }
- if (_position.y() >= 2016)
- _position.y() = _lastPosition.z();
+ checkIfStillInArea();
+ if (_currentArea->getAreaID() != previousAreaID)
+ return;
bool collided = checkCollisions(false);
diff --git a/engines/freescape/objects/connections.h b/engines/freescape/objects/connections.h
new file mode 100644
index 00000000000..75e705fcceb
--- /dev/null
+++ b/engines/freescape/objects/connections.h
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef FREESCAPE_CONNECTIONS_H
+#define FREESCAPE_CONNECTIONS_H
+
+#include "freescape/objects/object.h"
+
+namespace Freescape {
+
+class AreaConnections : public Object {
+public:
+ Common::Array<byte> _connections;
+ AreaConnections(const Common::Array<byte> connections_) {
+ _objectID = 254;
+ _connections = connections_;
+ }
+
+ ObjectType getType() override { return ObjectType::kEntranceType; };
+ void draw(Freescape::Renderer *gfx) override { error("cannot render AreaConnections"); };
+ void scale(int factor) override { warning("cannot scale AreaConnections"); };
+ Object *duplicate() override { error("cannot duplicate AreaConnections"); };
+};
+
+} // End of namespace Freescape
+
+#endif // FREESCAPE_CONNECTIONS_H
\ No newline at end of file
Commit: d2075367385609ec049a3715c4934e2c79c95e2d
https://github.com/scummvm/scummvm/commit/d2075367385609ec049a3715c4934e2c79c95e2d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:12:47+01:00
Commit Message:
FREESCAPE: implemented fullscreen messages in dark dos demo
Changed paths:
engines/freescape/freescape.h
engines/freescape/games/dark.cpp
engines/freescape/loaders/8bitBinaryLoader.cpp
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index a7ec3096b61..2388a153ddc 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -263,7 +263,7 @@ public:
bool executeEndIfBitNotEqual(FCLInstruction &instruction);
bool executeEndIfVisibilityIsEqual(FCLInstruction &instruction);
void executeSwapJet(FCLInstruction &instruction);
- void executePrint(FCLInstruction &instruction);
+ virtual void executePrint(FCLInstruction &instruction);
void executeSPFX(FCLInstruction &instruction);
// Sound
@@ -448,10 +448,12 @@ public:
void loadAssets() override;
void initGameState() override;
+ void borderScreen() override;
void gotoArea(uint16 areaID, int entranceID) override;
void checkIfStillInArea() override;
void pressedKey(const int keycode) override;
+ void executePrint(FCLInstruction &instruction) override;
void loadAssetsDemo();
void loadAssetsFullGame();
@@ -461,6 +463,7 @@ public:
void drawUI() override;
void drawDOSUI(Graphics::Surface *surface);
+ void drawFullscreenMessage(Common::String message);
Common::Error saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave = false) override;
Common::Error loadGameStreamExtended(Common::SeekableReadStream *stream) override;
};
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 60e1b86bfd0..5b200097680 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -65,6 +65,7 @@ void DarkEngine::loadAssetsDemo() {
if (!file.isOpen())
error("Failed to open DSIDEE.EXE");
loadMessagesFixedSize(&file, 0x4525, 16, 27);
+ loadMessagesFixedSize(&file, 0x9959, 307, 5);
loadFonts(&file, 0xa598);
load8bitBinary(&file, 0xa700, 16);
} else if (isDOS() && _renderMode == Common::kRenderCGA) {
@@ -135,6 +136,13 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
if (!_gameStateBits.contains(areaID))
_gameStateBits[areaID] = 0;
+ if (isDemo()) {
+ if (!_areaMap.contains(areaID)) {
+ drawFullscreenMessage(_messagesList[30]);
+ return;
+ }
+ }
+
assert(_areaMap.contains(areaID));
_currentArea = _areaMap[areaID];
_currentArea->show();
@@ -336,6 +344,110 @@ void DarkEngine::drawUI() {
delete surface;
}
+void DarkEngine::borderScreen() {
+ if (_border) {
+ drawBorder();
+ if (isDemo()) {
+ drawFullscreenMessage(_messagesList[27]);
+ drawFullscreenMessage(_messagesList[28]);
+ drawFullscreenMessage(_messagesList[29]);
+ } else {
+ _gfx->flipBuffer();
+ g_system->updateScreen();
+ g_system->delayMillis(3000);
+ }
+ }
+}
+
+void DarkEngine::executePrint(FCLInstruction &instruction) {
+ uint16 index = instruction._source - 1;
+ debugC(1, kFreescapeDebugCode, "Printing message %d", index);
+ _currentAreaMessages.clear();
+ if (index > 127) {
+ index = _messagesList.size() - (index - 254) - 2;
+ drawFullscreenMessage(_messagesList[index]);
+ return;
+ }
+ _currentAreaMessages.push_back(_messagesList[index]);
+}
+
+void DarkEngine::drawFullscreenMessage(Common::String message) {
+ _savedScreen = _gfx->getScreenshot();
+
+ uint32 color = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0x00, 0x00, 0x00);
+ Graphics::Surface *surface = new Graphics::Surface();
+ surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
+ surface->fillRect(_fullscreenViewArea, color);
+
+ uint32 black = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
+ surface->fillRect(_viewArea, black);
+
+ switch (_renderMode) {
+ case Common::kRenderCGA:
+ color = 1;
+ break;
+ case Common::kRenderZX:
+ color = 6;
+ break;
+ default:
+ color = 14;
+ }
+ uint8 r, g, b;
+ _gfx->readFromPalette(color, r, g, b);
+ uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+ int x, y;
+ x = 42;
+ y = 30;
+ for (int i = 0; i < 8; i++) {
+ Common::String line = message.substr(28 * i, 28);
+ debug("'%s' %d", line.c_str(), line.size());
+ drawStringInSurface(line, x, y, front, black, surface);
+ y = y + 12;
+ }
+
+ if (!_uiTexture)
+ _uiTexture = _gfx->createTexture(surface);
+ else
+ _uiTexture->update(surface);
+
+ _gfx->setViewport(_fullscreenViewArea);
+ _gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _uiTexture);
+ _gfx->setViewport(_viewArea);
+
+ _gfx->flipBuffer();
+ g_system->updateScreen();
+
+ Common::Event event;
+ bool cont = true;
+ while (!shouldQuit() && cont) {
+ while (g_system->getEventManager()->pollEvent(event)) {
+
+ // Events
+ switch (event.type) {
+ case Common::EVENT_KEYDOWN:
+ if (event.kbd.keycode == Common::KEYCODE_SPACE) {
+ cont = false;
+ }
+ break;
+ case Common::EVENT_SCREEN_CHANGED:
+ _gfx->computeScreenViewport();
+ // TODO: properly refresh screen
+ break;
+
+ default:
+ break;
+ }
+ }
+ g_system->delayMillis(10);
+ }
+
+ _savedScreen->free();
+ delete _savedScreen;
+ surface->free();
+ delete surface;
+}
+
Common::Error DarkEngine::saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave) {
return Common::kNoError;
}
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index b0b2edefc0c..1e5a7f48126 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -659,7 +659,7 @@ void FreescapeEngine::loadMessagesFixedSize(Common::SeekableReadStream *file, in
file->read(buffer, size);
Common::String message = (const char *)buffer;
_messagesList.push_back(message);
- debugC(1, kFreescapeDebugParser, "%s", _messagesList[i].c_str());
+ debugC(1, kFreescapeDebugParser, "%s", _messagesList[_messagesList.size() - 1].c_str());
}
free(buffer);
}
Commit: 875940674e7fce6924aee9e16ae823a5182afb4c
https://github.com/scummvm/scummvm/commit/875940674e7fce6924aee9e16ae823a5182afb4c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:12:58+01:00
Commit Message:
FREESCAPE: load some? global objects in dark for dos (and demo)
Changed paths:
engines/freescape/freescape.h
engines/freescape/games/dark.cpp
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 2388a153ddc..ac30334df92 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -466,6 +466,9 @@ public:
void drawFullscreenMessage(Common::String message);
Common::Error saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave = false) override;
Common::Error loadGameStreamExtended(Common::SeekableReadStream *stream) override;
+
+private:
+ void loadGlobalObjects(Common::SeekableReadStream *file, int offset);
};
class EclipseEngine : public FreescapeEngine {
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index 5b200097680..edd1d0bcfe4 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -67,6 +67,7 @@ void DarkEngine::loadAssetsDemo() {
loadMessagesFixedSize(&file, 0x4525, 16, 27);
loadMessagesFixedSize(&file, 0x9959, 307, 5);
loadFonts(&file, 0xa598);
+ loadGlobalObjects(&file, 0x3d04);
load8bitBinary(&file, 0xa700, 16);
} else if (isDOS() && _renderMode == Common::kRenderCGA) {
//loadBundledImages();
@@ -80,6 +81,23 @@ void DarkEngine::loadAssetsDemo() {
error("Invalid or unsupported render mode %s for Dark Side", Common::getRenderModeDescription(_renderMode));
}
+
+void DarkEngine::loadGlobalObjects(Common::SeekableReadStream *file, int offset) {
+ assert(!_areaMap.contains(255));
+ ObjectMap *globalObjectsByID = new ObjectMap;
+ file->seek(offset);
+ for (int i = 0; i < 22; i++) {
+ Object *gobj = load8bitObject(file);
+ assert(gobj);
+ assert(!globalObjectsByID->contains(gobj->getObjectID()));
+ debugC(1, kFreescapeDebugParser, "Adding global object: %d", gobj->getObjectID());
+ (*globalObjectsByID)[gobj->getObjectID()] = gobj;
+ }
+
+ _areaMap[255] = new Area(255, 0, globalObjectsByID, nullptr);
+}
+
+
void DarkEngine::initGameState() {
_flyMode = false;
_noClipMode = false;
@@ -119,7 +137,14 @@ void DarkEngine::loadAssetsFullGame() {
loadFonts(&file, 0xa113);
loadMessagesFixedSize(&file, 0x4525, 16, 27);
+ loadGlobalObjects(&file, 0x3d04);
load8bitBinary(&file, 0xa280, 16);
+ // TODO: load objects
+ /*for (auto &it : _areaMap) {
+ if (!it._value->entranceWithID(255))
+ continue;
+ it._value->addStructure(_areaMap[255]);
+ }*/
} else if (_renderMode == Common::kRenderCGA) {
loadBundledImages();
file.open("DSIDEC.EXE");
Commit: 7b307e562b9dca79de2abbeee8763f4e70d76e67
https://github.com/scummvm/scummvm/commit/7b307e562b9dca79de2abbeee8763f4e70d76e67
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:13:10+01:00
Commit Message:
FREESCAPE: drafted code that reads title image of driller US release for DOS
Changed paths:
engines/freescape/freescape.h
engines/freescape/games/driller.cpp
engines/freescape/loaders/8bitBinaryLoader.cpp
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index ac30334df92..6772c476c23 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -164,6 +164,9 @@ public:
void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors);
Object *load8bitObject(Common::SeekableReadStream *file);
+ void renderPixels8bitImage(Graphics::Surface *surface, int &i, int &j, int pixels);
+ uint32 getPixel8bitImage(int index);
+ Graphics::Surface *load8bitImage(Common::SeekableReadStream *file, int ncolors, int offset);
// Areas
uint16 _startArea;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index a30e97a8087..b154dc77ee6 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -660,6 +660,12 @@ void DrillerEngine::loadAssetsFullGame() {
} else if (_renderMode == Common::kRenderCGA) {
loadBundledImages();
+ _title->free();
+ delete _title;
+ file.open("CGATITLE.RL");
+ _title = load8bitImage(&file, 4, 0x1b3);
+
+ file.close();
file.open("DRILLC.EXE");
if (!file.isOpen())
@@ -669,6 +675,7 @@ void DrillerEngine::loadAssetsFullGame() {
loadMessagesFixedSize(&file, 0x2585, 14, 20);
load8bitBinary(&file, 0x7bb0, 4);
loadGlobalObjects(&file, 0x1fa2);
+ //_border = load8bitImage(&file, 4, 0x261);
} else
error("Invalid or unsupported render mode %s for Driller", Common::getRenderModeDescription(_renderMode));
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 1e5a7f48126..7ae1b7cd240 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -298,6 +298,154 @@ static const char *eclipseRoomName[] = {
"ILLUSION",
"????????"};
+byte kCGAPalettePinkBlueWhiteData[4][3] = {
+ {0x00, 0x00, 0x00},
+ {0x55, 0xff, 0xff},
+ {0xff, 0x55, 0xff},
+ {0xff, 0xff, 0xff},
+};
+
+uint32 FreescapeEngine::getPixel8bitImage(int index) {
+ uint8 r, g, b;
+ if (index < 4) {
+ _gfx->readFromPalette(0, r, g, b);
+ return _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b);
+ }
+ _gfx->readFromPalette(index / 4, r, g, b);
+ return _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b);
+}
+
+void FreescapeEngine::renderPixels8bitImage(Graphics::Surface *surface, int &i, int &j, int pixels) {
+ int c1 = pixels >> 4;
+ int c2 = pixels & 0xf;
+
+ if (i == 320) {
+ return;
+ }
+
+ surface->setPixel(i, j, getPixel8bitImage(c1));
+ i++;
+
+ if (i == 320) {
+ return;
+ }
+
+ surface->setPixel(i, j, getPixel8bitImage(c1));
+ i++;
+
+ if (i == 320) {
+ return;
+ }
+
+ surface->setPixel(i, j, getPixel8bitImage(c2));
+ i++;
+
+ if (i == 320) {
+ return;
+ }
+
+ surface->setPixel(i, j, getPixel8bitImage(c2));
+ i++;
+}
+
+Graphics::Surface *FreescapeEngine::load8bitImage(Common::SeekableReadStream *file, int ncolors, int offset) {
+ Graphics::Surface *surface = new Graphics::Surface();
+ assert(ncolors == 4);
+ _gfx->_palette = (byte *)kCGAPalettePinkBlueWhiteData;
+ surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
+ uint32 black = _gfx->_currentPixelFormat.ARGBToColor(0xFF, 0, 0, 0);
+ surface->fillRect(Common::Rect(0, 0, 320, 200), black);
+
+ int i = 0;
+ int j = 0;
+ int command = -1;
+ int singlePixelsToProcess = 0;
+ bool repeatedPixelsToProcess = false;
+ file->seek(offset);
+ while (!file->eos()) {
+ assert(i <= 320);
+ int pixels = -1;
+ int repetition = -1;
+
+ if (singlePixelsToProcess == 0 && !repeatedPixelsToProcess) {
+ if (command < 0)
+ command = file->readByte();
+
+ //debug("reading command: %x at %lx", command, file->pos() - 1);
+
+ assert(command >= 0x7f);
+ singlePixelsToProcess = (0xff - command + 2) * 2;
+ //debug("single Pixels to process: %d", singlePixelsToProcess);
+
+ repeatedPixelsToProcess = true;
+ if (i == 320) {
+ j++;
+ i = 0;
+ }
+ command = -1;
+ continue;
+ }
+
+ if (singlePixelsToProcess > 0) {
+ singlePixelsToProcess--;
+ pixels = file->readByte();
+ //debug("reading pixels: %x at %d, %d", pixels, i, j);
+ renderPixels8bitImage(surface, i, j, pixels);
+ } else if (repeatedPixelsToProcess) {
+ repetition = file->readByte() + 1;
+ //debug("reading repetition: %x", repetition - 1);
+ assert(repetition > 0);
+ if (repetition >= 0x80) {
+ command = repetition - 1;
+ repeatedPixelsToProcess = false;
+ continue;
+ }
+
+ if (i == 320) {
+ j++;
+ i = 0;
+ continue;
+ }
+
+ int pixels1 = file->readByte();
+ //debug("reading pixels: %x", pixels1);
+
+ int pixels2 = file->readByte();
+ //debug("reading pixels: %x", pixels2);
+
+ if (repetition >= 1) {
+ while (repetition > 0) {
+ repetition--;
+
+ if (i == 320) {
+ j++;
+ i = 0;
+ }
+
+ if (j == 200)
+ return surface;
+
+ //sdebug("repeating pixels: %x at %d, %d", pixels1, i, j);
+ renderPixels8bitImage(surface, i, j, pixels1);
+
+ if (i == 320) {
+ j++;
+ i = 0;
+ }
+
+ if (j == 200)
+ return surface;
+
+ //debug("repeating pixels: %x at %d, %d", pixels2, i, j);
+ renderPixels8bitImage(surface, i, j, pixels2);
+ }
+ }
+ }
+ }
+
+ return surface;
+}
+
Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
Common::String name;
Commit: 523bc141fe4c922d59600ef9d2bd7f18ab0a8938
https://github.com/scummvm/scummvm/commit/523bc141fe4c922d59600ef9d2bd7f18ab0a8938
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:13:18+01:00
Commit Message:
FREESCAPE: initial implementation of image parsing for title/borders in driller
Changed paths:
engines/freescape/freescape.h
engines/freescape/games/driller.cpp
engines/freescape/loaders/8bitBinaryLoader.cpp
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 6772c476c23..9e876ddf56d 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -164,9 +164,13 @@ public:
void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors);
Object *load8bitObject(Common::SeekableReadStream *file);
- void renderPixels8bitImage(Graphics::Surface *surface, int &i, int &j, int pixels);
+ void renderPixels8bitTitleImage(Graphics::Surface *surface, int &i, int &j, int pixels);
+ void renderPixels8bitBinImage(Graphics::Surface *surface, int &i, int &j, int pixels, int color);
+
uint32 getPixel8bitImage(int index);
- Graphics::Surface *load8bitImage(Common::SeekableReadStream *file, int ncolors, int offset);
+ Graphics::Surface *load8bitBinImage(Common::SeekableReadStream *file, int ncolors, int offset);
+ Graphics::Surface *load8bitTitleImage(Common::SeekableReadStream *file, int ncolors, int offset);
+
// Areas
uint16 _startArea;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index b154dc77ee6..73cc894f7cb 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -663,7 +663,7 @@ void DrillerEngine::loadAssetsFullGame() {
_title->free();
delete _title;
file.open("CGATITLE.RL");
- _title = load8bitImage(&file, 4, 0x1b3);
+ _title = load8bitTitleImage(&file, 4, 0x1b3);
file.close();
file.open("DRILLC.EXE");
@@ -675,7 +675,7 @@ void DrillerEngine::loadAssetsFullGame() {
loadMessagesFixedSize(&file, 0x2585, 14, 20);
load8bitBinary(&file, 0x7bb0, 4);
loadGlobalObjects(&file, 0x1fa2);
- //_border = load8bitImage(&file, 4, 0x261);
+ _border = load8bitBinImage(&file, 4, 0x210);
} else
error("Invalid or unsupported render mode %s for Driller", Common::getRenderModeDescription(_renderMode));
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 7ae1b7cd240..33ac4291d90 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -308,14 +308,14 @@ byte kCGAPalettePinkBlueWhiteData[4][3] = {
uint32 FreescapeEngine::getPixel8bitImage(int index) {
uint8 r, g, b;
if (index < 4) {
- _gfx->readFromPalette(0, r, g, b);
+ _gfx->readFromPalette(index, r, g, b);
return _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b);
}
_gfx->readFromPalette(index / 4, r, g, b);
return _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b);
}
-void FreescapeEngine::renderPixels8bitImage(Graphics::Surface *surface, int &i, int &j, int pixels) {
+void FreescapeEngine::renderPixels8bitTitleImage(Graphics::Surface *surface, int &i, int &j, int pixels) {
int c1 = pixels >> 4;
int c2 = pixels & 0xf;
@@ -323,7 +323,7 @@ void FreescapeEngine::renderPixels8bitImage(Graphics::Surface *surface, int &i,
return;
}
- surface->setPixel(i, j, getPixel8bitImage(c1));
+ surface->setPixel(i, j, getPixel8bitImage(c1 / 4));
i++;
if (i == 320) {
@@ -337,7 +337,7 @@ void FreescapeEngine::renderPixels8bitImage(Graphics::Surface *surface, int &i,
return;
}
- surface->setPixel(i, j, getPixel8bitImage(c2));
+ surface->setPixel(i, j, getPixel8bitImage(c2 / 4));
i++;
if (i == 320) {
@@ -348,7 +348,7 @@ void FreescapeEngine::renderPixels8bitImage(Graphics::Surface *surface, int &i,
i++;
}
-Graphics::Surface *FreescapeEngine::load8bitImage(Common::SeekableReadStream *file, int ncolors, int offset) {
+Graphics::Surface *FreescapeEngine::load8bitTitleImage(Common::SeekableReadStream *file, int ncolors, int offset) {
Graphics::Surface *surface = new Graphics::Surface();
assert(ncolors == 4);
_gfx->_palette = (byte *)kCGAPalettePinkBlueWhiteData;
@@ -390,7 +390,7 @@ Graphics::Surface *FreescapeEngine::load8bitImage(Common::SeekableReadStream *fi
singlePixelsToProcess--;
pixels = file->readByte();
//debug("reading pixels: %x at %d, %d", pixels, i, j);
- renderPixels8bitImage(surface, i, j, pixels);
+ renderPixels8bitTitleImage(surface, i, j, pixels);
} else if (repeatedPixelsToProcess) {
repetition = file->readByte() + 1;
//debug("reading repetition: %x", repetition - 1);
@@ -426,7 +426,7 @@ Graphics::Surface *FreescapeEngine::load8bitImage(Common::SeekableReadStream *fi
return surface;
//sdebug("repeating pixels: %x at %d, %d", pixels1, i, j);
- renderPixels8bitImage(surface, i, j, pixels1);
+ renderPixels8bitTitleImage(surface, i, j, pixels1);
if (i == 320) {
j++;
@@ -437,7 +437,7 @@ Graphics::Surface *FreescapeEngine::load8bitImage(Common::SeekableReadStream *fi
return surface;
//debug("repeating pixels: %x at %d, %d", pixels2, i, j);
- renderPixels8bitImage(surface, i, j, pixels2);
+ renderPixels8bitTitleImage(surface, i, j, pixels2);
}
}
}
@@ -446,6 +446,104 @@ Graphics::Surface *FreescapeEngine::load8bitImage(Common::SeekableReadStream *fi
return surface;
}
+void FreescapeEngine::renderPixels8bitBinImage(Graphics::Surface *surface, int &i, int &j, int pixels, int color) {
+ if (i >= 320) {
+ //debug("cannot continue, stopping here at row %d!", j);
+ return;
+ }
+
+ int acc = 1 << 7;
+ while (acc > 0) {
+ assert(i < 320);
+ if (acc & pixels)
+ surface->setPixel(i, j, getPixel8bitImage(color));
+ i++;
+ acc = acc >> 1;
+ }
+
+}
+
+Graphics::Surface *FreescapeEngine::load8bitBinImage(Common::SeekableReadStream *file, int ncolors, int offset) {
+ Graphics::Surface *surface = new Graphics::Surface();
+ assert(ncolors == 4);
+ _gfx->_palette = (byte *)kCGAPalettePinkBlueWhiteData;
+ surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
+ uint32 black = _gfx->_currentPixelFormat.ARGBToColor(0xFF, 0, 0, 0);
+ surface->fillRect(Common::Rect(0, 0, 320, 200), black);
+
+ file->seek(offset);
+ int imageSize = file->readUint16BE();
+
+ int i = 0;
+ int j = 0;
+ int hPixelsWritten = 0;
+ int color = 1;
+ int command = 0;
+ while (file->pos() <= offset + imageSize) {
+ debug("pos: %lx", file->pos());
+ command = file->readByte();
+
+ color = hPixelsWritten < 320 ? 1 : 2;
+ //debug("command: %x with j: %d", command, j);
+ if (j >= 200)
+ return surface;
+
+ if (command <= 0x7f) {
+ //debug("starting singles at i: %d j: %d", i, j);
+ int start = i;
+ while (command-- >= 0) {
+ int pixels = file->readByte();
+ //debug("single pixels command: %d with pixels: %x", command, pixels);
+ renderPixels8bitBinImage(surface, i, j, pixels, color);
+ }
+ hPixelsWritten = hPixelsWritten + i - start;
+ } else if (command <= 0xff && command >= 0xf0) {
+ int size = 136 - 8*(command - 0xf0);
+ int start = i;
+ int pixels = file->readByte();
+ //debug("starting 0xfX: at i: %d j: %d with pixels: %x", i, j, pixels);
+ while (size > 0) {
+ renderPixels8bitBinImage(surface, i, j, pixels, color);
+ size = size - 8;
+ }
+ hPixelsWritten = hPixelsWritten + i - start;
+ assert(i <= 320);
+ } else if (command <= 0xef && command >= 0xe0) {
+ int size = 264 - 8*(command - 0xe0);
+ int start = i;
+ int pixels = file->readByte();
+ //debug("starting 0xeX: at i: %d j: %d with pixels: %x", i, j, pixels);
+ while (size > 0) {
+ renderPixels8bitBinImage(surface, i, j, pixels, color);
+ size = size - 8;
+ }
+ hPixelsWritten = hPixelsWritten + i - start;
+ } else if (command <= 0xdf && command >= 0xd0) {
+ int size = 272 + 8*(0xdf - command);
+ int start = i;
+ int pixels = file->readByte();
+ while (size > 0) {
+ renderPixels8bitBinImage(surface, i, j, pixels, color);
+ size = size - 8;
+ }
+ hPixelsWritten = hPixelsWritten + i - start;
+ } else {
+ error("unknown command: %x", command);
+ }
+
+ if (i >= 320) {
+ i = 0;
+ if (hPixelsWritten >= 640) {
+ j++;
+ hPixelsWritten = 0;
+ }
+ }
+
+
+ }
+ return surface;
+}
+
Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 ncolors) {
Common::String name;
Commit: 2e652a9861b67b02fc273e1ee3d0b32f960d0f1e
https://github.com/scummvm/scummvm/commit/2e652a9861b67b02fc273e1ee3d0b32f960d0f1e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:13:26+01:00
Commit Message:
FREESCAPE: load title/borders images in driller dos directly from the game data
Changed paths:
engines/freescape/games/driller.cpp
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 73cc894f7cb..c68f09aa60c 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -659,12 +659,15 @@ void DrillerEngine::loadAssetsFullGame() {
load8bitBinary(&file, 0x9b40, 16);
} else if (_renderMode == Common::kRenderCGA) {
- loadBundledImages();
- _title->free();
- delete _title;
+ file.open("SCN1C.DAT");
+ if (file.isOpen()) {
+ _title = load8bitBinImage(&file, 4, 0x0);
+ }
+ file.close();
file.open("CGATITLE.RL");
- _title = load8bitTitleImage(&file, 4, 0x1b3);
-
+ if (file.isOpen()) {
+ _title = load8bitTitleImage(&file, 4, 0x1b3);
+ }
file.close();
file.open("DRILLC.EXE");
Commit: 05f7253af33c40b02d6a35d4b67de47ac8ca4920
https://github.com/scummvm/scummvm/commit/05f7253af33c40b02d6a35d4b67de47ac8ca4920
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:13:33+01:00
Commit Message:
FREESCAPE: load title/borders images in driller EGA directly from the game data
Changed paths:
engines/freescape/freescape.h
engines/freescape/games/driller.cpp
engines/freescape/loaders/8bitBinaryLoader.cpp
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 9e876ddf56d..1e177654887 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -165,11 +165,14 @@ public:
Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors);
Object *load8bitObject(Common::SeekableReadStream *file);
void renderPixels8bitTitleImage(Graphics::Surface *surface, int &i, int &j, int pixels);
- void renderPixels8bitBinImage(Graphics::Surface *surface, int &i, int &j, int pixels, int color);
+ void renderPixels8bitBinImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color);
+
+ void renderPixels8bitBinCGAImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color);
+ void renderPixels8bitBinEGAImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color);
uint32 getPixel8bitImage(int index);
- Graphics::Surface *load8bitBinImage(Common::SeekableReadStream *file, int ncolors, int offset);
- Graphics::Surface *load8bitTitleImage(Common::SeekableReadStream *file, int ncolors, int offset);
+ Graphics::Surface *load8bitBinImage(Common::SeekableReadStream *file, int offset);
+ Graphics::Surface *load8bitTitleImage(Common::SeekableReadStream *file, int offset);
// Areas
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index c68f09aa60c..902000f563d 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -647,7 +647,11 @@ void DrillerEngine::loadAssetsFullGame() {
loadGlobalObjects(&file, 0x1855 - 0x400);
}
} else if (_renderMode == Common::kRenderEGA) {
- loadBundledImages();
+ file.open("SCN1E.DAT");
+ if (file.isOpen()) {
+ _title = load8bitBinImage(&file, 0x0);
+ }
+ file.close();
file.open("DRILLE.EXE");
if (!file.isOpen())
@@ -657,16 +661,16 @@ void DrillerEngine::loadAssetsFullGame() {
loadFonts(&file, 0x99dd);
loadGlobalObjects(&file, 0x3b42);
load8bitBinary(&file, 0x9b40, 16);
-
+ _border = load8bitBinImage(&file, 0x210);
} else if (_renderMode == Common::kRenderCGA) {
file.open("SCN1C.DAT");
if (file.isOpen()) {
- _title = load8bitBinImage(&file, 4, 0x0);
+ _title = load8bitBinImage(&file, 0x0);
}
file.close();
file.open("CGATITLE.RL");
if (file.isOpen()) {
- _title = load8bitTitleImage(&file, 4, 0x1b3);
+ _title = load8bitTitleImage(&file, 0x1b3);
}
file.close();
file.open("DRILLC.EXE");
@@ -678,7 +682,7 @@ void DrillerEngine::loadAssetsFullGame() {
loadMessagesFixedSize(&file, 0x2585, 14, 20);
load8bitBinary(&file, 0x7bb0, 4);
loadGlobalObjects(&file, 0x1fa2);
- _border = load8bitBinImage(&file, 4, 0x210);
+ _border = load8bitBinImage(&file, 0x210);
} else
error("Invalid or unsupported render mode %s for Driller", Common::getRenderModeDescription(_renderMode));
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 33ac4291d90..1f29750bbff 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -305,6 +305,24 @@ byte kCGAPalettePinkBlueWhiteData[4][3] = {
{0xff, 0xff, 0xff},
};
+byte kEGADefaultPaletteData[16][3] = {
+ {0x00, 0x00, 0x00},
+ {0x00, 0x00, 0xaa},
+ {0x00, 0xaa, 0x00},
+ {0xaa, 0x00, 0x00},
+ {0xaa, 0x00, 0xaa},
+ {0xaa, 0x55, 0x00},
+ {0x55, 0xff, 0x55},
+ {0xff, 0x55, 0x55},
+ {0x12, 0x34, 0x56},
+ {0xff, 0xff, 0x55},
+ {0xff, 0xff, 0xff},
+ {0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00}
+};
+
uint32 FreescapeEngine::getPixel8bitImage(int index) {
uint8 r, g, b;
if (index < 4) {
@@ -348,9 +366,9 @@ void FreescapeEngine::renderPixels8bitTitleImage(Graphics::Surface *surface, int
i++;
}
-Graphics::Surface *FreescapeEngine::load8bitTitleImage(Common::SeekableReadStream *file, int ncolors, int offset) {
+Graphics::Surface *FreescapeEngine::load8bitTitleImage(Common::SeekableReadStream *file, int offset) {
Graphics::Surface *surface = new Graphics::Surface();
- assert(ncolors == 4);
+ assert(_renderMode == Common::kRenderCGA);
_gfx->_palette = (byte *)kCGAPalettePinkBlueWhiteData;
surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
uint32 black = _gfx->_currentPixelFormat.ARGBToColor(0xFF, 0, 0, 0);
@@ -446,7 +464,7 @@ Graphics::Surface *FreescapeEngine::load8bitTitleImage(Common::SeekableReadStrea
return surface;
}
-void FreescapeEngine::renderPixels8bitBinImage(Graphics::Surface *surface, int &i, int &j, int pixels, int color) {
+void FreescapeEngine::renderPixels8bitBinImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color) {
if (i >= 320) {
//debug("cannot continue, stopping here at row %d!", j);
return;
@@ -455,18 +473,30 @@ void FreescapeEngine::renderPixels8bitBinImage(Graphics::Surface *surface, int &
int acc = 1 << 7;
while (acc > 0) {
assert(i < 320);
- if (acc & pixels)
- surface->setPixel(i, j, getPixel8bitImage(color));
+ if (acc & pixels) {
+ uint8 r, g, b;
+ uint32 previousPixel = surface->getPixel(i, j);
+ _gfx->_currentPixelFormat.colorToRGB(previousPixel, r, g, b);
+ int previousColor = _gfx->indexFromColor(r, g, b);
+ //debug("index: %d", previousColor + color);
+ _gfx->readFromPalette(previousColor + color, r, g, b);
+ surface->setPixel(i, j, _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b));
+ }
i++;
acc = acc >> 1;
}
}
-Graphics::Surface *FreescapeEngine::load8bitBinImage(Common::SeekableReadStream *file, int ncolors, int offset) {
+Graphics::Surface *FreescapeEngine::load8bitBinImage(Common::SeekableReadStream *file, int offset) {
Graphics::Surface *surface = new Graphics::Surface();
- assert(ncolors == 4);
- _gfx->_palette = (byte *)kCGAPalettePinkBlueWhiteData;
+ if (_renderMode == Common::kRenderCGA)
+ _gfx->_palette = (byte *)kCGAPalettePinkBlueWhiteData;
+ else if (_renderMode == Common::kRenderEGA)
+ _gfx->_palette = (byte *)kEGADefaultPaletteData;
+ else
+ error("Invalid render mode: %d", _renderMode);
+
surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
uint32 black = _gfx->_currentPixelFormat.ARGBToColor(0xFF, 0, 0, 0);
surface->fillRect(Common::Rect(0, 0, 320, 200), black);
@@ -480,10 +510,10 @@ Graphics::Surface *FreescapeEngine::load8bitBinImage(Common::SeekableReadStream
int color = 1;
int command = 0;
while (file->pos() <= offset + imageSize) {
- debug("pos: %lx", file->pos());
+ //debug("pos: %lx", file->pos());
command = file->readByte();
- color = hPixelsWritten < 320 ? 1 : 2;
+ color = 1 + hPixelsWritten / 320;
//debug("command: %x with j: %d", command, j);
if (j >= 200)
return surface;
@@ -498,33 +528,33 @@ Graphics::Surface *FreescapeEngine::load8bitBinImage(Common::SeekableReadStream
}
hPixelsWritten = hPixelsWritten + i - start;
} else if (command <= 0xff && command >= 0xf0) {
- int size = 136 - 8*(command - 0xf0);
+ int size = (136 - 8*(command - 0xf0)) / 2;
int start = i;
int pixels = file->readByte();
//debug("starting 0xfX: at i: %d j: %d with pixels: %x", i, j, pixels);
while (size > 0) {
renderPixels8bitBinImage(surface, i, j, pixels, color);
- size = size - 8;
+ size = size - 4;
}
hPixelsWritten = hPixelsWritten + i - start;
assert(i <= 320);
} else if (command <= 0xef && command >= 0xe0) {
- int size = 264 - 8*(command - 0xe0);
+ int size = (264 - 8*(command - 0xe0)) / 2;
int start = i;
int pixels = file->readByte();
//debug("starting 0xeX: at i: %d j: %d with pixels: %x", i, j, pixels);
while (size > 0) {
renderPixels8bitBinImage(surface, i, j, pixels, color);
- size = size - 8;
+ size = size - 4;
}
hPixelsWritten = hPixelsWritten + i - start;
} else if (command <= 0xdf && command >= 0xd0) {
- int size = 272 + 8*(0xdf - command);
+ int size = (272 + 8*(0xdf - command)) / 2;
int start = i;
int pixels = file->readByte();
while (size > 0) {
renderPixels8bitBinImage(surface, i, j, pixels, color);
- size = size - 8;
+ size = size - 4;
}
hPixelsWritten = hPixelsWritten + i - start;
} else {
@@ -533,7 +563,7 @@ Graphics::Surface *FreescapeEngine::load8bitBinImage(Common::SeekableReadStream
if (i >= 320) {
i = 0;
- if (hPixelsWritten >= 640) {
+ if (hPixelsWritten >= (_renderMode == Common::kRenderCGA ? 640 : 1280)) {
j++;
hPixelsWritten = 0;
}
Commit: cc42bc2efbbe01a625a4aea090dd07fe7fd928f8
https://github.com/scummvm/scummvm/commit/cc42bc2efbbe01a625a4aea090dd07fe7fd928f8
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:13:44+01:00
Commit Message:
FREESCAPE: load title/borders images in dark side EGA (and demo) directly from the game data
Changed paths:
engines/freescape/freescape.h
engines/freescape/games/dark.cpp
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 1e177654887..1bd2c977df9 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -459,6 +459,7 @@ public:
void loadAssets() override;
void initGameState() override;
void borderScreen() override;
+ void titleScreen() override;
void gotoArea(uint16 areaID, int entranceID) override;
void checkIfStillInArea() override;
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark.cpp
index edd1d0bcfe4..1a10368adb1 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark.cpp
@@ -49,6 +49,18 @@ DarkEngine::DarkEngine(OSystem *syst, const ADGameDescription *gd) : FreescapeEn
_initialShield = 15;
}
+void DarkEngine::titleScreen() {
+ if (isAmiga() || isAtariST()) // These releases has their own screens
+ return;
+
+ if (_title) {
+ drawTitle();
+ _gfx->flipBuffer();
+ g_system->updateScreen();
+ g_system->delayMillis(3000);
+ }
+}
+
void DarkEngine::loadAssets() {
if (isDemo())
loadAssetsDemo();
@@ -59,7 +71,10 @@ void DarkEngine::loadAssets() {
void DarkEngine::loadAssetsDemo() {
Common::File file;
if (isDOS() && _renderMode == Common::kRenderEGA) {
- loadBundledImages();
+ file.open("SCN1E.DAT");
+ if (file.isOpen())
+ _title = load8bitBinImage(&file, 0x0);
+ file.close();
file.open("DSIDEE.EXE");
if (!file.isOpen())
@@ -69,6 +84,7 @@ void DarkEngine::loadAssetsDemo() {
loadFonts(&file, 0xa598);
loadGlobalObjects(&file, 0x3d04);
load8bitBinary(&file, 0xa700, 16);
+ _border = load8bitBinImage(&file, 0x210);
} else if (isDOS() && _renderMode == Common::kRenderCGA) {
//loadBundledImages();
file.open("DSIDEC.EXE");
@@ -129,7 +145,10 @@ void DarkEngine::initGameState() {
void DarkEngine::loadAssetsFullGame() {
Common::File file;
if (_renderMode == Common::kRenderEGA) {
- loadBundledImages();
+ file.open("SCN1E.DAT");
+ if (file.isOpen())
+ _title = load8bitBinImage(&file, 0x0);
+ file.close();
file.open("DSIDEE.EXE");
if (!file.isOpen())
@@ -139,6 +158,8 @@ void DarkEngine::loadAssetsFullGame() {
loadMessagesFixedSize(&file, 0x4525, 16, 27);
loadGlobalObjects(&file, 0x3d04);
load8bitBinary(&file, 0xa280, 16);
+ _border = load8bitBinImage(&file, 0x210);
+
// TODO: load objects
/*for (auto &it : _areaMap) {
if (!it._value->entranceWithID(255))
Commit: 76c2a780a4ba09c22996e01dd1137600688e379c
https://github.com/scummvm/scummvm/commit/76c2a780a4ba09c22996e01dd1137600688e379c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:13:50+01:00
Commit Message:
FREESCAPE: load title/borders images in total eclipse EGA directly from the game data
Changed paths:
engines/freescape/freescape.h
engines/freescape/games/eclipse.cpp
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 1bd2c977df9..975f8c9d5e3 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -487,6 +487,7 @@ public:
EclipseEngine(OSystem *syst, const ADGameDescription *gd);
void loadAssets() override;
+ void titleScreen() override;
void gotoArea(uint16 areaID, int entranceID) override;
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 9e4e47a2d00..56baa42f46b 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -99,10 +99,26 @@ EclipseEngine::EclipseEngine(OSystem *syst, const ADGameDescription *gd) : Frees
}
}
+void EclipseEngine::titleScreen() {
+ if (isAmiga() || isAtariST()) // These releases has their own screens
+ return;
+
+ if (_title) {
+ drawTitle();
+ _gfx->flipBuffer();
+ g_system->updateScreen();
+ g_system->delayMillis(3000);
+ }
+}
+
void EclipseEngine::loadAssets() {
Common::File file;
if (_renderMode == Common::kRenderEGA) {
- loadBundledImages();
+ file.open("SCN1E.DAT");
+ if (file.isOpen()) {
+ _title = load8bitBinImage(&file, 0x0);
+ }
+ file.close();
file.open("TOTEE.EXE");
if (!file.isOpen())
@@ -112,7 +128,7 @@ void EclipseEngine::loadAssets() {
load8bitBinary(&file, 0x3ce0, 16);
for (auto &it : _areaMap)
it._value->addStructure(_areaMap[255]);
-
+ _border = load8bitBinImage(&file, 0x210);
} else if (_renderMode == Common::kRenderCGA) {
loadBundledImages();
file.open("TOTEC.EXE");
Commit: 94c52bf7bf0b76f68d1b05aceb6a46fb7d99a0f9
https://github.com/scummvm/scummvm/commit/94c52bf7bf0b76f68d1b05aceb6a46fb7d99a0f9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:13:58+01:00
Commit Message:
FREESCAPE: implemented scr image loader and read title/borders images in driller for zx directly from the game data
Changed paths:
A engines/freescape/scr.cpp
A engines/freescape/scr.h
engines/freescape/freescape.cpp
engines/freescape/freescape.h
engines/freescape/games/driller.cpp
engines/freescape/module.mk
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index f02e22ff73f..851ed926571 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -30,6 +30,7 @@
#include "freescape/freescape.h"
#include "freescape/language/8bitDetokeniser.h"
#include "freescape/neo.h"
+#include "freescape/scr.h"
#include "freescape/objects/sensor.h"
namespace Freescape {
@@ -185,7 +186,6 @@ void FreescapeEngine::drawBorder() {
return;
_gfx->setViewport(_fullscreenViewArea);
-
assert(_borderTexture);
_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _borderTexture);
_gfx->setViewport(_viewArea);
@@ -879,6 +879,16 @@ Graphics::Surface *FreescapeEngine::loadAndConvertNeoImage(Common::SeekableReadS
return surface;
}
+Graphics::Surface *FreescapeEngine::loadAndCenterScrImage(Common::SeekableReadStream *stream) {
+ ScrDecoder decoder;
+ decoder.loadStream(*stream);
+ Graphics::Surface *surface = new Graphics::Surface();
+ const Graphics::Surface *decoded = decoder.getSurface();
+ surface->create(320, 200, decoded->format);
+ surface->copyRectToSurface(*decoded, (320 - decoded->w) / 2, (200 - decoded->h) / 2, Common::Rect(decoded->w, decoded->h));
+ return surface;
+}
+
void FreescapeEngine::getTimeFromCountdown(int &seconds, int &minutes, int &hours) {
int countdown = _countdown;
int h = countdown <= 0 ? 0 : countdown / 3600;
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 975f8c9d5e3..5a255ca3b3d 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -140,6 +140,7 @@ public:
void loadBundledImages();
byte *getPaletteFromNeoImage(Common::SeekableReadStream *stream, int offset);
Graphics::Surface *loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte *palette = nullptr);
+ Graphics::Surface *loadAndCenterScrImage(Common::SeekableReadStream *stream);
void loadPalettes(Common::SeekableReadStream *file, int offset);
void swapPalette(uint16 areaID);
Common::HashMap<uint16, byte *> _paletteByArea;
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 902000f563d..5650a51e3a5 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -538,7 +538,21 @@ void DrillerEngine::loadAssetsFullGame() {
loadPalettes(&file, 0x296fa);
loadSoundsFx(&file, 0x30da6, 25);
} else if (isSpectrum()) {
- loadBundledImages();
+ file.open("driller.zx.title");
+ if (file.isOpen()) {
+ _title = loadAndCenterScrImage(&file);
+ } else
+ error("Unable to find driller.zx.title");
+
+ file.close();
+
+ file.open("driller.zx.border");
+ if (file.isOpen()) {
+ _border = loadAndCenterScrImage(&file);
+ } else
+ error("Unable to find driller.zx.border");
+ file.close();
+
file.open("driller.zx.extracted");
if (!file.isOpen())
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 9b3b656ce6c..556a28f6efa 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -18,6 +18,7 @@ MODULE_OBJS := \
neo.o \
objects/geometricobject.o \
objects/sensor.o \
+ scr.o \
sound.o
ifdef USE_TINYGL
diff --git a/engines/freescape/scr.cpp b/engines/freescape/scr.cpp
new file mode 100644
index 00000000000..1621363fe30
--- /dev/null
+++ b/engines/freescape/scr.cpp
@@ -0,0 +1,105 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/stream.h"
+#include "common/textconsole.h"
+#include "graphics/pixelformat.h"
+#include "graphics/surface.h"
+
+#include "freescape/scr.h"
+
+namespace Freescape {
+
+ScrDecoder::ScrDecoder() {
+ _surface = nullptr;
+}
+
+ScrDecoder::~ScrDecoder() {
+ destroy();
+}
+
+void ScrDecoder::destroy() {
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ _surface = nullptr;
+ }
+}
+
+uint32 ScrDecoder::getPixelAddress(int x, int y) {
+ uint32 y76 = y & 0xc0;
+ uint32 y53 = y & 0x38;
+ uint32 y20 = y & 0x07;
+ return (y76 << 5) + (y20 << 8) + (y53 << 2) + (x >> 3);
+}
+
+uint32 ScrDecoder::getAttributeAddress(int x, int y) {
+ uint32 y73 = y & 0xf8;
+ return (y73 << 2) + (x >> 3);
+}
+
+bool ScrDecoder::loadStream(Common::SeekableReadStream &stream) {
+ destroy();
+
+ if (stream.size() != 6912)
+ warning("Header check failed for reading scr image");
+
+ byte *data = (byte *)malloc(6144 * sizeof(byte));
+ byte *attributes = (byte *)malloc(768 * sizeof(byte));
+
+ stream.read(data, 6144);
+ stream.read(attributes, 768);
+
+ int width = 256;
+ int height = 192;
+ Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
+
+ _surface = new Graphics::Surface();
+ _surface->create(width, height, format);
+
+ for (int y = 0; y < height; y++) {
+ for (int col = 0; col < width >> 3; col++) {
+ int x = col << 3;
+ byte byt = data[getPixelAddress(x, y)];
+ byte attr = attributes[getAttributeAddress(x, y)];
+ byte ink = attr & 0x07;
+ byte paper = (attr >> 3) & 0x07;
+ byte bright = (attr >> 6) & 1;
+ byte val = bright ? 0xff : 0xcd;
+ for (int bit = 0; bit < 8; bit++) {
+ bool set = (byt >> (7 - bit)) & 1;
+ int color = set ? ink : paper;
+
+ byte r = val * (color >> 1 & 1);
+ byte g = val * (color >> 2 & 1);
+ byte b = val * (color >> 0 & 1);
+
+ _surface->setPixel(x + bit, y, format.ARGBToColor(0xFF, r, g, b));
+ }
+ }
+ }
+
+ free(data);
+ free(attributes);
+ return true;
+}
+
+} // End of namespace Freescape
diff --git a/engines/freescape/scr.h b/engines/freescape/scr.h
new file mode 100644
index 00000000000..054dc0a16de
--- /dev/null
+++ b/engines/freescape/scr.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef FREESCAPE_SCR_H
+#define FREESCAPE_SCR_H
+
+#include "image/image_decoder.h"
+
+/*
+ZX-Spectrum SCREEN$ decoder based on:
+https://gist.github.com/alexanderk23/f459c76847d9412548f7
+*/
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace Freescape {
+
+class ScrDecoder : public Image::ImageDecoder {
+public:
+ ScrDecoder();
+ virtual ~ScrDecoder();
+
+ // ImageDecoder API
+ void destroy();
+ virtual bool loadStream(Common::SeekableReadStream &stream);
+ virtual const Graphics::Surface *getSurface() const { return _surface; }
+private:
+ Graphics::Surface *_surface;
+ uint32 getPixelAddress(int x, int y);
+ uint32 getAttributeAddress(int x, int y);
+};
+} // End of namespace Freescape
+
+#endif // FREESCAPE_SCR_H
Commit: 71e6e2b1f13530693ff75772512b50564b25a412
https://github.com/scummvm/scummvm/commit/71e6e2b1f13530693ff75772512b50564b25a412
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:15:38+01:00
Commit Message:
FREESCAPE: renamed game data file for driller detection in several platforms
Changed paths:
engines/freescape/detection.cpp
engines/freescape/games/driller.cpp
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 7dd8000c377..f3faa281ae6 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -39,7 +39,7 @@ static const ADGameDescription gameDescriptions[] = {
"driller",
"",
{
- {"DRILLER.ZX.EXTRACTED", 0, "396c1789a7da3db5058d18eb8d2d35a3", 37590},
+ {"DRILLER.ZX.DATA", 0, "396c1789a7da3db5058d18eb8d2d35a3", 37590},
AD_LISTEND
},
Common::EN_ANY,
@@ -51,7 +51,7 @@ static const ADGameDescription gameDescriptions[] = {
"driller",
"",
{
- {"DRILLER.ZX.EXTRACTED", 0, "6876fc03e754137f428bd4d5f16452b5", 37888},
+ {"DRILLER.ZX.DATA", 0, "6876fc03e754137f428bd4d5f16452b5", 37888},
AD_LISTEND
},
Common::EN_ANY,
@@ -63,7 +63,7 @@ static const ADGameDescription gameDescriptions[] = {
"driller",
"",
{
- {"DRILLER.ZX.EXTRACTED", 0, "2b996ab877f45414f8e2ae4c862746f3", 35214},
+ {"DRILLER.ZX.DATA", 0, "2b996ab877f45414f8e2ae4c862746f3", 35214},
AD_LISTEND
},
Common::EN_ANY,
@@ -123,7 +123,7 @@ static const ADGameDescription gameDescriptions[] = {
"spacestationoblivion",
"",
{
- {"SPACESTATIONOBLIVION.C64.EXTRACTED", 0, "85680576865e211f868885e9997a08b8", 22782},
+ {"SPACESTATIONOBLIVION.C64.DATA", 0, "85680576865e211f868885e9997a08b8", 22782},
AD_LISTEND
},
Common::EN_ANY,
@@ -136,7 +136,7 @@ static const ADGameDescription gameDescriptions[] = {
"spacestationoblivion",
"",
{
- {"SPACESTATIONOBLIVION.C64.EXTRACTED", 0, "2b3537e21b8b871ec074df2962999781", 64514},
+ {"SPACESTATIONOBLIVION.C64.DATA", 0, "2b3537e21b8b871ec074df2962999781", 64514},
AD_LISTEND
},
Common::EN_ANY,
@@ -148,7 +148,7 @@ static const ADGameDescription gameDescriptions[] = {
"driller", // Commodore Force - Jan 94
"",
{
- {"DRILLER.C64.EXTRACTED", 0, "511778d3167ff7504d905df507a03ac5", 63490},
+ {"DRILLER.C64.DATA", 0, "511778d3167ff7504d905df507a03ac5", 63490},
AD_LISTEND
},
Common::EN_ANY,
@@ -160,7 +160,7 @@ static const ADGameDescription gameDescriptions[] = {
"driller",
"",
{
- {"DRILLER.C64.EXTRACTED", 0, "73a6f206e54fb13245fe6d92f60fbb34", 41071},
+ {"DRILLER.C64.DATA", 0, "73a6f206e54fb13245fe6d92f60fbb34", 41071},
AD_LISTEND
},
Common::EN_ANY,
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 5650a51e3a5..ba40a2a0975 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -553,10 +553,10 @@ void DrillerEngine::loadAssetsFullGame() {
error("Unable to find driller.zx.border");
file.close();
- file.open("driller.zx.extracted");
+ file.open("driller.zx.data");
if (!file.isOpen())
- error("Failed to open driller.zx.extracted");
+ error("Failed to open driller.zx.data");
if (_variant & GF_ZX_DISC)
loadMessagesFixedSize(&file, 0x2164, 14, 20);
@@ -648,13 +648,13 @@ void DrillerEngine::loadAssetsFullGame() {
} else if (isC64()) {
if (_targetName.hasPrefix("spacestationoblivion")) {
loadBundledImages();
- file.open("spacestationoblivion.c64.extracted");
+ file.open("spacestationoblivion.c64.data");
loadMessagesFixedSize(&file, 0x167a, 14, 20);
//loadFonts(&file, 0xae54);
load8bitBinary(&file, 0x8e02, 4);
loadGlobalObjects(&file, 0x1855);
} else if (_targetName.hasPrefix("driller")) {
- file.open("driller.c64.extracted");
+ file.open("driller.c64.data");
loadMessagesFixedSize(&file, 0x167a - 0x400, 14, 20);
//loadFonts(&file, 0xae54);
load8bitBinary(&file, 0x8e02 - 0x400, 4);
Commit: a62b58adcaaa520dff292ce7500e204dd176a79b
https://github.com/scummvm/scummvm/commit/a62b58adcaaa520dff292ce7500e204dd176a79b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:15:47+01:00
Commit Message:
FREESCAPE: small adjustments for driller ui for zx
Changed paths:
engines/freescape/games/driller.cpp
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index ba40a2a0975..ddc463130ce 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -106,7 +106,7 @@ DrillerEngine::DrillerEngine(OSystem *syst, const ADGameDescription *gd) : Frees
else if (isAmiga() || isAtariST())
_viewArea = Common::Rect(36, 16, 284, 118);
else if (isSpectrum())
- _viewArea = Common::Rect(58, 20, 266, 124);
+ _viewArea = Common::Rect(56, 20, 264, 124);
else if (isCPC())
_viewArea = Common::Rect(36, 19, 284, 120);
else if (isC64())
@@ -1037,30 +1037,30 @@ void DrillerEngine::drawZXUI(Graphics::Surface *surface) {
uint32 white = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0xFF);
int score = _gameStateVars[k8bitVariableScore];
- drawStringInSurface(_currentArea->_name, 176, 188, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 152, 149, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 152, 157, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 152, 165, front, back, surface);
+ drawStringInSurface(_currentArea->_name, 174, 188, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 150, 149, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 150, 157, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 150, 165, front, back, surface);
if (_playerHeightNumber >= 0)
- drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 74, 165, front, back, surface);
+ drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 72, 165, front, back, surface);
else
- drawStringInSurface(Common::String::format("%s", "J"), 74, 165, front, back, surface);
+ drawStringInSurface(Common::String::format("%s", "J"), 72, 165, front, back, surface);
- drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 64, 149, front, back, surface);
- drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 65, 157, front, back, surface);
- drawStringInSurface(Common::String::format("%07d", score), 217, 133, white, back, surface);
+ drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 62, 149, front, back, surface);
+ drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 63, 157, front, back, surface);
+ drawStringInSurface(Common::String::format("%07d", score), 215, 133, white, back, surface);
int seconds, minutes, hours;
getTimeFromCountdown(seconds, minutes, hours);
- drawStringInSurface(Common::String::format("%02d", hours), 187, 12, front, back, surface);
- drawStringInSurface(Common::String::format("%02d", minutes), 209, 12, front, back, surface);
- drawStringInSurface(Common::String::format("%02d", seconds), 232, 12, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", hours), 185, 12, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", minutes), 207, 12, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", seconds), 230, 12, front, back, surface);
Common::String message;
int deadline;
getLatestMessages(message, deadline);
if (deadline <= _countdown) {
- drawStringInSurface(message, 169, 181, back, front, surface);
+ drawStringInSurface(message, 167, 181, back, front, surface);
_temporaryMessages.push_back(message);
_temporaryMessageDeadlines.push_back(deadline);
} else {
@@ -1071,24 +1071,24 @@ void DrillerEngine::drawZXUI(Graphics::Surface *surface) {
else
message = _messagesList[1];
- drawStringInSurface(message, 169, 181, front, back, surface);
+ drawStringInSurface(message, 167, 181, front, back, surface);
}
int energy = _gameStateVars[k8bitVariableEnergy];
int shield = _gameStateVars[k8bitVariableShield];
if (energy >= 0) {
- Common::Rect backBar(45, 188, 109 - energy, 194);
+ Common::Rect backBar(43, 188, 107 - energy, 194);
surface->fillRect(backBar, back);
- Common::Rect energyBar(108 - energy, 188, 108, 194);
+ Common::Rect energyBar(106 - energy, 188, 106, 194);
surface->fillRect(energyBar, front);
}
if (shield >= 0) {
- Common::Rect backBar(45, 181, 109 - shield, 187);
+ Common::Rect backBar(43, 181, 107 - shield, 187);
surface->fillRect(backBar, back);
- Common::Rect shieldBar(108 - shield, 181, 108, 187);
+ Common::Rect shieldBar(106 - shield, 181, 106, 187);
surface->fillRect(shieldBar, front);
}
}
Commit: 752d202f4622df93620ec46581449753a488a422
https://github.com/scummvm/scummvm/commit/752d202f4622df93620ec46581449753a488a422
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:16:06+01:00
Commit Message:
FREESCAPE: refactored deobfuscation code for driller cpc
Changed paths:
engines/freescape/games/driller.cpp
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index ddc463130ce..e6de67e06f7 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -393,7 +393,6 @@ void DrillerEngine::loadAssetsDemo() {
_angleRotationIndex = 0;
}
-
byte *parseEDSK(const Common::String filename, int &size) {
debugC(1, kFreescapeDebugParser, "Trying to parse edsk file: %s", filename.c_str());
Common::File file;
@@ -457,6 +456,38 @@ byte *parseEDSK(const Common::String filename, int &size) {
return memBuffer;
}
+void deobfuscateDrillerCPCVirtualWorlds(byte *memBuffer) {
+ // Deofuscation / loader code
+ for (int j = 0; j < 0x200; j++) {
+ memBuffer[0x14000 + j] = memBuffer[0x14200 + j];
+ memBuffer[0x14200 + j] = memBuffer[0x13400 + j];
+ memBuffer[0x14400 + j] = memBuffer[0x13800 + j];
+ memBuffer[0x14600 + j] = memBuffer[0x13c00 + j];
+ }
+
+ for (int j = 0; j < 0x200; j++) {
+ memBuffer[0x13c00 + j] = memBuffer[0x13a00 + j];
+ memBuffer[0x13a00 + j] = memBuffer[0x13600 + j];
+ memBuffer[0x13800 + j] = memBuffer[0x13200 + j];
+ memBuffer[0x13600 + j] = memBuffer[0x12e00 + j];
+ memBuffer[0x12e00 + j] = memBuffer[0x13000 + j];
+ memBuffer[0x13000 + j] = memBuffer[0x12200 + j];
+ memBuffer[0x13200 + j] = memBuffer[0x12600 + j];
+ memBuffer[0x13400 + j] = memBuffer[0x12a00 + j];
+ }
+
+ for (int i = 6; i >= 0; i--) {
+ //debug("copying 0x200 bytes to %x from %x", 0x12000 + 0x200*i, 0x11400 + 0x400*i);
+ for (int j = 0; j < 0x200; j++) {
+ memBuffer[0x12000 + 0x200*i + j] = memBuffer[0x11400 + 0x400*i + j];
+ }
+ }
+
+ for (int j = 0; j < 0x200; j++) {
+ memBuffer[0x11c00 + j] = memBuffer[0x11e00 + j];
+ memBuffer[0x11e00 + j] = memBuffer[0x11000 + j];
+ }
+}
void DrillerEngine::loadAssetsFullGame() {
Common::File file;
@@ -590,37 +621,7 @@ void DrillerEngine::loadAssetsFullGame() {
int memSize = 0;
if (_variant & GF_CPC_VIRTUALWORLDS) {
memBuffer = parseEDSK("virtualworlds.A.cpc.edsk", memSize);
-
- // Deofuscation / loader code
- for (int j = 0; j < 0x200; j++) {
- memBuffer[0x14000 + j] = memBuffer[0x14200 + j];
- memBuffer[0x14200 + j] = memBuffer[0x13400 + j];
- memBuffer[0x14400 + j] = memBuffer[0x13800 + j];
- memBuffer[0x14600 + j] = memBuffer[0x13c00 + j];
- }
-
- for (int j = 0; j < 0x200; j++) {
- memBuffer[0x13c00 + j] = memBuffer[0x13a00 + j];
- memBuffer[0x13a00 + j] = memBuffer[0x13600 + j];
- memBuffer[0x13800 + j] = memBuffer[0x13200 + j];
- memBuffer[0x13600 + j] = memBuffer[0x12e00 + j];
- memBuffer[0x12e00 + j] = memBuffer[0x13000 + j];
- memBuffer[0x13000 + j] = memBuffer[0x12200 + j];
- memBuffer[0x13200 + j] = memBuffer[0x12600 + j];
- memBuffer[0x13400 + j] = memBuffer[0x12a00 + j];
- }
-
- for (int i = 6; i >= 0; i--) {
- //debug("copying 0x200 bytes to %x from %x", 0x12000 + 0x200*i, 0x11400 + 0x400*i);
- for (int j = 0; j < 0x200; j++) {
- memBuffer[0x12000 + 0x200*i + j] = memBuffer[0x11400 + 0x400*i + j];
- }
- }
-
- for (int j = 0; j < 0x200; j++) {
- memBuffer[0x11c00 + j] = memBuffer[0x11e00 + j];
- memBuffer[0x11e00 + j] = memBuffer[0x11000 + j];
- }
+ deobfuscateDrillerCPCVirtualWorlds(memBuffer);
} else
memBuffer = parseEDSK("driller.cpc.edsk", memSize);
assert(memSize > 0);
Commit: 11dfbe8b7245d9e2e41bbbfd4af9d6dcc2d8db12
https://github.com/scummvm/scummvm/commit/11dfbe8b7245d9e2e41bbbfd4af9d6dcc2d8db12
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:16:17+01:00
Commit Message:
FREESCAPE: fixed image loader and read title in driller for ega and updated freescape.dat
Changed paths:
R devtools/create_freescape/darkside_ega.bmp
R devtools/create_freescape/driller_cga_title.bmp
R devtools/create_freescape/driller_ega.bmp
R devtools/create_freescape/driller_ega_title.bmp
R devtools/create_freescape/driller_zx.bmp
R devtools/create_freescape/driller_zx_title.bmp
R devtools/create_freescape/spacestationoblivion_cga.bmp
R devtools/create_freescape/spacestationoblivion_cga_title.bmp
R devtools/create_freescape/spacestationoblivion_ega.bmp
R devtools/create_freescape/spacestationoblivion_ega_title.bmp
R devtools/create_freescape/totaleclipse_ega.bmp
devtools/create_freescape/version
dists/engine-data/freescape.dat
engines/freescape/freescape.cpp
engines/freescape/freescape.h
engines/freescape/games/driller.cpp
engines/freescape/loaders/8bitBinaryLoader.cpp
diff --git a/devtools/create_freescape/darkside_ega.bmp b/devtools/create_freescape/darkside_ega.bmp
deleted file mode 100644
index 7622c9e58b2..00000000000
Binary files a/devtools/create_freescape/darkside_ega.bmp and /dev/null differ
diff --git a/devtools/create_freescape/driller_cga_title.bmp b/devtools/create_freescape/driller_cga_title.bmp
deleted file mode 100644
index 2741613f4a5..00000000000
Binary files a/devtools/create_freescape/driller_cga_title.bmp and /dev/null differ
diff --git a/devtools/create_freescape/driller_ega.bmp b/devtools/create_freescape/driller_ega.bmp
deleted file mode 100644
index ec3df6b4bb7..00000000000
Binary files a/devtools/create_freescape/driller_ega.bmp and /dev/null differ
diff --git a/devtools/create_freescape/driller_ega_title.bmp b/devtools/create_freescape/driller_ega_title.bmp
deleted file mode 100644
index b0ad1adc1f8..00000000000
Binary files a/devtools/create_freescape/driller_ega_title.bmp and /dev/null differ
diff --git a/devtools/create_freescape/driller_zx.bmp b/devtools/create_freescape/driller_zx.bmp
deleted file mode 100644
index 6cc207a6913..00000000000
Binary files a/devtools/create_freescape/driller_zx.bmp and /dev/null differ
diff --git a/devtools/create_freescape/driller_zx_title.bmp b/devtools/create_freescape/driller_zx_title.bmp
deleted file mode 100644
index 6421d62d97c..00000000000
Binary files a/devtools/create_freescape/driller_zx_title.bmp and /dev/null differ
diff --git a/devtools/create_freescape/spacestationoblivion_cga.bmp b/devtools/create_freescape/spacestationoblivion_cga.bmp
deleted file mode 100644
index 26efd4ce64a..00000000000
Binary files a/devtools/create_freescape/spacestationoblivion_cga.bmp and /dev/null differ
diff --git a/devtools/create_freescape/spacestationoblivion_cga_title.bmp b/devtools/create_freescape/spacestationoblivion_cga_title.bmp
deleted file mode 100644
index 2cdb371cde7..00000000000
Binary files a/devtools/create_freescape/spacestationoblivion_cga_title.bmp and /dev/null differ
diff --git a/devtools/create_freescape/spacestationoblivion_ega.bmp b/devtools/create_freescape/spacestationoblivion_ega.bmp
deleted file mode 100644
index 5965512fc9e..00000000000
Binary files a/devtools/create_freescape/spacestationoblivion_ega.bmp and /dev/null differ
diff --git a/devtools/create_freescape/spacestationoblivion_ega_title.bmp b/devtools/create_freescape/spacestationoblivion_ega_title.bmp
deleted file mode 100644
index 41c667015b6..00000000000
Binary files a/devtools/create_freescape/spacestationoblivion_ega_title.bmp and /dev/null differ
diff --git a/devtools/create_freescape/totaleclipse_ega.bmp b/devtools/create_freescape/totaleclipse_ega.bmp
deleted file mode 100644
index 738d6af20b4..00000000000
Binary files a/devtools/create_freescape/totaleclipse_ega.bmp and /dev/null differ
diff --git a/devtools/create_freescape/version b/devtools/create_freescape/version
index 56a6051ca2b..d8263ee9860 100644
--- a/devtools/create_freescape/version
+++ b/devtools/create_freescape/version
@@ -1 +1 @@
-1
\ No newline at end of file
+2
\ No newline at end of file
diff --git a/dists/engine-data/freescape.dat b/dists/engine-data/freescape.dat
index 301c12a46c6..322725f9b14 100644
Binary files a/dists/engine-data/freescape.dat and b/dists/engine-data/freescape.dat differ
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 851ed926571..2c5b96da6aa 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -833,7 +833,7 @@ void FreescapeEngine::loadDataBundle() {
char *versionData = (char *)malloc((versionFile->size() + 1) * sizeof(char));
versionFile->read(versionData, versionFile->size());
versionData[versionFile->size()] = '\0';
- Common::String expectedVersion = "1";
+ Common::String expectedVersion = "2";
if (versionData != expectedVersion)
error("Unexpected version number for freescape.dat: expecting '%s' but found '%s'", expectedVersion.c_str(), versionData);
free(versionData);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 5a255ca3b3d..058551b1981 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -171,7 +171,7 @@ public:
void renderPixels8bitBinCGAImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color);
void renderPixels8bitBinEGAImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color);
- uint32 getPixel8bitImage(int index);
+ uint32 getPixel8bitTitleImage(int index);
Graphics::Surface *load8bitBinImage(Common::SeekableReadStream *file, int offset);
Graphics::Surface *load8bitTitleImage(Common::SeekableReadStream *file, int offset);
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index e6de67e06f7..3c172bff970 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -667,6 +667,12 @@ void DrillerEngine::loadAssetsFullGame() {
_title = load8bitBinImage(&file, 0x0);
}
file.close();
+ file.open("EGATITLE.RL");
+ if (file.isOpen()) {
+ _title = load8bitTitleImage(&file, 0x1b3);
+ }
+ file.close();
+
file.open("DRILLE.EXE");
if (!file.isOpen())
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 1f29750bbff..e22eaad1f00 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -323,9 +323,9 @@ byte kEGADefaultPaletteData[16][3] = {
{0x00, 0x00, 0x00}
};
-uint32 FreescapeEngine::getPixel8bitImage(int index) {
+uint32 FreescapeEngine::getPixel8bitTitleImage(int index) {
uint8 r, g, b;
- if (index < 4) {
+ if (index < 4 || _renderMode == Common::kRenderEGA) {
_gfx->readFromPalette(index, r, g, b);
return _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b);
}
@@ -341,35 +341,42 @@ void FreescapeEngine::renderPixels8bitTitleImage(Graphics::Surface *surface, int
return;
}
- surface->setPixel(i, j, getPixel8bitImage(c1 / 4));
- i++;
-
- if (i == 320) {
- return;
+ if (_renderMode == Common::kRenderCGA) {
+ surface->setPixel(i, j, getPixel8bitTitleImage(c1 / 4));
+ i++;
+ if (i == 320) {
+ return;
+ }
}
- surface->setPixel(i, j, getPixel8bitImage(c1));
+ surface->setPixel(i, j, getPixel8bitTitleImage(c1));
i++;
if (i == 320) {
return;
}
- surface->setPixel(i, j, getPixel8bitImage(c2 / 4));
- i++;
+ if (_renderMode == Common::kRenderCGA) {
+ surface->setPixel(i, j, getPixel8bitTitleImage(c2 / 4));
+ i++;
- if (i == 320) {
- return;
+ if (i == 320) {
+ return;
+ }
}
- surface->setPixel(i, j, getPixel8bitImage(c2));
+ surface->setPixel(i, j, getPixel8bitTitleImage(c2));
i++;
}
Graphics::Surface *FreescapeEngine::load8bitTitleImage(Common::SeekableReadStream *file, int offset) {
Graphics::Surface *surface = new Graphics::Surface();
- assert(_renderMode == Common::kRenderCGA);
- _gfx->_palette = (byte *)kCGAPalettePinkBlueWhiteData;
+ if (_renderMode == Common::kRenderCGA)
+ _gfx->_palette = (byte *)kCGAPalettePinkBlueWhiteData;
+ else if (_renderMode == Common::kRenderEGA)
+ _gfx->_palette = (byte *)kEGADefaultPaletteData;
+ else
+ error("Invalid render mode: %d", _renderMode);
surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
uint32 black = _gfx->_currentPixelFormat.ARGBToColor(0xFF, 0, 0, 0);
surface->fillRect(Common::Rect(0, 0, 320, 200), black);
Commit: caa6e9c104faf9d8a81bdbd5f9d18e98bbb8df0b
https://github.com/scummvm/scummvm/commit/caa6e9c104faf9d8a81bdbd5f9d18e98bbb8df0b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:16:26+01:00
Commit Message:
FREESCAPE: refactored driller dos code into a directory
Changed paths:
A engines/freescape/games/driller/dos.cpp
A engines/freescape/games/driller/driller.cpp
R engines/freescape/games/driller.cpp
engines/freescape/freescape.h
engines/freescape/loaders/8bitBinaryLoader.cpp
engines/freescape/module.mk
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 058551b1981..f45c683dfc4 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -165,16 +165,12 @@ public:
void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors);
Object *load8bitObject(Common::SeekableReadStream *file);
- void renderPixels8bitTitleImage(Graphics::Surface *surface, int &i, int &j, int pixels);
void renderPixels8bitBinImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color);
void renderPixels8bitBinCGAImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color);
void renderPixels8bitBinEGAImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color);
- uint32 getPixel8bitTitleImage(int index);
Graphics::Surface *load8bitBinImage(Common::SeekableReadStream *file, int offset);
- Graphics::Surface *load8bitTitleImage(Common::SeekableReadStream *file, int offset);
-
// Areas
uint16 _startArea;
@@ -448,6 +444,10 @@ private:
void drawCPCUI(Graphics::Surface *surface);
void drawC64UI(Graphics::Surface *surface);
void drawAmigaAtariSTUI(Graphics::Surface *surface);
+
+ Graphics::Surface *load8bitTitleImage(Common::SeekableReadStream *file, int offset);
+ uint32 getPixel8bitTitleImage(int index);
+ void renderPixels8bitTitleImage(Graphics::Surface *surface, int &i, int &j, int pixels);
};
class DarkEngine : public FreescapeEngine {
diff --git a/engines/freescape/games/driller/dos.cpp b/engines/freescape/games/driller/dos.cpp
new file mode 100644
index 00000000000..ad61fa078d0
--- /dev/null
+++ b/engines/freescape/games/driller/dos.cpp
@@ -0,0 +1,254 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "freescape/freescape.h"
+#include "freescape/language/8bitDetokeniser.h"
+
+namespace Freescape {
+
+extern byte kCGAPalettePinkBlueWhiteData[4][3];
+extern byte kEGADefaultPaletteData[16][3];
+
+/*
+ The following functions are only used for decoding title images for
+ the US release of Driller ("Space Station Oblivion")
+*/
+
+uint32 DrillerEngine::getPixel8bitTitleImage(int index) {
+ uint8 r, g, b;
+ if (index < 4 || _renderMode == Common::kRenderEGA) {
+ _gfx->readFromPalette(index, r, g, b);
+ return _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b);
+ }
+ _gfx->readFromPalette(index / 4, r, g, b);
+ return _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b);
+}
+
+void DrillerEngine::renderPixels8bitTitleImage(Graphics::Surface *surface, int &i, int &j, int pixels) {
+ int c1 = pixels >> 4;
+ int c2 = pixels & 0xf;
+
+ if (i == 320) {
+ return;
+ }
+
+ if (_renderMode == Common::kRenderCGA) {
+ surface->setPixel(i, j, getPixel8bitTitleImage(c1 / 4));
+ i++;
+ if (i == 320) {
+ return;
+ }
+ }
+
+ surface->setPixel(i, j, getPixel8bitTitleImage(c1));
+ i++;
+
+ if (i == 320) {
+ return;
+ }
+
+ if (_renderMode == Common::kRenderCGA) {
+ surface->setPixel(i, j, getPixel8bitTitleImage(c2 / 4));
+ i++;
+
+ if (i == 320) {
+ return;
+ }
+ }
+
+ surface->setPixel(i, j, getPixel8bitTitleImage(c2));
+ i++;
+}
+
+Graphics::Surface *DrillerEngine::load8bitTitleImage(Common::SeekableReadStream *file, int offset) {
+ Graphics::Surface *surface = new Graphics::Surface();
+ if (_renderMode == Common::kRenderCGA)
+ _gfx->_palette = (byte *)kCGAPalettePinkBlueWhiteData;
+ else if (_renderMode == Common::kRenderEGA)
+ _gfx->_palette = (byte *)kEGADefaultPaletteData;
+ else
+ error("Invalid render mode: %d", _renderMode);
+ surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
+ uint32 black = _gfx->_currentPixelFormat.ARGBToColor(0xFF, 0, 0, 0);
+ surface->fillRect(Common::Rect(0, 0, 320, 200), black);
+
+ int i = 0;
+ int j = 0;
+ int command = -1;
+ int singlePixelsToProcess = 0;
+ bool repeatedPixelsToProcess = false;
+ file->seek(offset);
+ while (!file->eos()) {
+ assert(i <= 320);
+ int pixels = -1;
+ int repetition = -1;
+
+ if (singlePixelsToProcess == 0 && !repeatedPixelsToProcess) {
+ if (command < 0)
+ command = file->readByte();
+
+ //debug("reading command: %x at %lx", command, file->pos() - 1);
+
+ assert(command >= 0x7f);
+ singlePixelsToProcess = (0xff - command + 2) * 2;
+ //debug("single Pixels to process: %d", singlePixelsToProcess);
+
+ repeatedPixelsToProcess = true;
+ if (i == 320) {
+ j++;
+ i = 0;
+ }
+ command = -1;
+ continue;
+ }
+
+ if (singlePixelsToProcess > 0) {
+ singlePixelsToProcess--;
+ pixels = file->readByte();
+ //debug("reading pixels: %x at %d, %d", pixels, i, j);
+ renderPixels8bitTitleImage(surface, i, j, pixels);
+ } else if (repeatedPixelsToProcess) {
+ repetition = file->readByte() + 1;
+ //debug("reading repetition: %x", repetition - 1);
+ assert(repetition > 0);
+ if (repetition >= 0x80) {
+ command = repetition - 1;
+ repeatedPixelsToProcess = false;
+ continue;
+ }
+
+ if (i == 320) {
+ j++;
+ i = 0;
+ continue;
+ }
+
+ int pixels1 = file->readByte();
+ //debug("reading pixels: %x", pixels1);
+
+ int pixels2 = file->readByte();
+ //debug("reading pixels: %x", pixels2);
+
+ if (repetition >= 1) {
+ while (repetition > 0) {
+ repetition--;
+
+ if (i == 320) {
+ j++;
+ i = 0;
+ }
+
+ if (j == 200)
+ return surface;
+
+ //sdebug("repeating pixels: %x at %d, %d", pixels1, i, j);
+ renderPixels8bitTitleImage(surface, i, j, pixels1);
+
+ if (i == 320) {
+ j++;
+ i = 0;
+ }
+
+ if (j == 200)
+ return surface;
+
+ //debug("repeating pixels: %x at %d, %d", pixels2, i, j);
+ renderPixels8bitTitleImage(surface, i, j, pixels2);
+ }
+ }
+ }
+ }
+ return surface;
+}
+
+void DrillerEngine::drawDOSUI(Graphics::Surface *surface) {
+ uint32 color = _renderMode == Common::kRenderCGA ? 1 : 14;
+ uint8 r, g, b;
+
+ _gfx->readFromPalette(color, r, g, b);
+ uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+ color = _currentArea->_usualBackgroundColor;
+ if (_gfx->_colorRemaps && _gfx->_colorRemaps->contains(color)) {
+ color = (*_gfx->_colorRemaps)[color];
+ }
+
+ _gfx->readFromPalette(color, r, g, b);
+ uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+ int score = _gameStateVars[k8bitVariableScore];
+ drawStringInSurface(_currentArea->_name, 196, 185, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 150, 145, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 150, 153, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 150, 161, front, back, surface);
+ if (_playerHeightNumber >= 0)
+ drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 57, 161, front, back, surface);
+ else
+ drawStringInSurface(Common::String::format("%s", "J"), 57, 161, front, back, surface);
+
+ drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 46, 145, front, back, surface);
+ drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), _renderMode == Common::kRenderCGA ? 44 : 46, 153, front, back, surface);
+ drawStringInSurface(Common::String::format("%07d", score), 238, 129, front, back, surface);
+
+ int seconds, minutes, hours;
+ getTimeFromCountdown(seconds, minutes, hours);
+ drawStringInSurface(Common::String::format("%02d", hours), 208, 8, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", minutes), 230, 8, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", seconds), 254, 8, front, back, surface);
+
+ Common::String message;
+ int deadline;
+ getLatestMessages(message, deadline);
+ if (deadline <= _countdown) {
+ drawStringInSurface(message, 190, 177, back, front, surface);
+ _temporaryMessages.push_back(message);
+ _temporaryMessageDeadlines.push_back(deadline);
+ } else {
+ if (_currentArea->_gasPocketRadius == 0)
+ message = _messagesList[2];
+ else if (_drillStatusByArea[_currentArea->getAreaID()])
+ message = _messagesList[0];
+ else
+ message = _messagesList[1];
+
+ drawStringInSurface(message, 191, 177, front, back, surface);
+ }
+
+ int energy = _gameStateVars[k8bitVariableEnergy];
+ int shield = _gameStateVars[k8bitVariableShield];
+
+ if (energy >= 0) {
+ Common::Rect backBar(20, 185, 88 - energy, 191);
+ surface->fillRect(backBar, back);
+ Common::Rect energyBar(87 - energy, 185, 88, 191);
+ surface->fillRect(energyBar, front);
+ }
+
+ if (shield >= 0) {
+ Common::Rect backBar(20, 177, 88 - shield, 183);
+ surface->fillRect(backBar, back);
+
+ Common::Rect shieldBar(87 - shield, 177, 88, 183);
+ surface->fillRect(shieldBar, front);
+ }
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller/driller.cpp
similarity index 94%
rename from engines/freescape/games/driller.cpp
rename to engines/freescape/games/driller/driller.cpp
index 3c172bff970..06fe7489531 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -811,78 +811,6 @@ void DrillerEngine::drawUI() {
delete surface;
}
-void DrillerEngine::drawDOSUI(Graphics::Surface *surface) {
- uint32 color = _renderMode == Common::kRenderCGA ? 1 : 14;
- uint8 r, g, b;
-
- _gfx->readFromPalette(color, r, g, b);
- uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
-
- color = _currentArea->_usualBackgroundColor;
- if (_gfx->_colorRemaps && _gfx->_colorRemaps->contains(color)) {
- color = (*_gfx->_colorRemaps)[color];
- }
-
- _gfx->readFromPalette(color, r, g, b);
- uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
-
- int score = _gameStateVars[k8bitVariableScore];
- drawStringInSurface(_currentArea->_name, 196, 185, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 150, 145, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 150, 153, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 150, 161, front, back, surface);
- if (_playerHeightNumber >= 0)
- drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 57, 161, front, back, surface);
- else
- drawStringInSurface(Common::String::format("%s", "J"), 57, 161, front, back, surface);
-
- drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 46, 145, front, back, surface);
- drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), _renderMode == Common::kRenderCGA ? 44 : 46, 153, front, back, surface);
- drawStringInSurface(Common::String::format("%07d", score), 238, 129, front, back, surface);
-
- int seconds, minutes, hours;
- getTimeFromCountdown(seconds, minutes, hours);
- drawStringInSurface(Common::String::format("%02d", hours), 208, 8, front, back, surface);
- drawStringInSurface(Common::String::format("%02d", minutes), 230, 8, front, back, surface);
- drawStringInSurface(Common::String::format("%02d", seconds), 254, 8, front, back, surface);
-
- Common::String message;
- int deadline;
- getLatestMessages(message, deadline);
- if (deadline <= _countdown) {
- drawStringInSurface(message, 190, 177, back, front, surface);
- _temporaryMessages.push_back(message);
- _temporaryMessageDeadlines.push_back(deadline);
- } else {
- if (_currentArea->_gasPocketRadius == 0)
- message = _messagesList[2];
- else if (_drillStatusByArea[_currentArea->getAreaID()])
- message = _messagesList[0];
- else
- message = _messagesList[1];
-
- drawStringInSurface(message, 191, 177, front, back, surface);
- }
-
- int energy = _gameStateVars[k8bitVariableEnergy];
- int shield = _gameStateVars[k8bitVariableShield];
-
- if (energy >= 0) {
- Common::Rect backBar(20, 185, 88 - energy, 191);
- surface->fillRect(backBar, back);
- Common::Rect energyBar(87 - energy, 185, 88, 191);
- surface->fillRect(energyBar, front);
- }
-
- if (shield >= 0) {
- Common::Rect backBar(20, 177, 88 - shield, 183);
- surface->fillRect(backBar, back);
-
- Common::Rect shieldBar(87 - shield, 177, 88, 183);
- surface->fillRect(shieldBar, front);
- }
-}
-
void DrillerEngine::drawCPCUI(Graphics::Surface *surface) {
uint32 color = 1;
uint8 r, g, b;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index e22eaad1f00..b39cd64c2e3 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -323,154 +323,6 @@ byte kEGADefaultPaletteData[16][3] = {
{0x00, 0x00, 0x00}
};
-uint32 FreescapeEngine::getPixel8bitTitleImage(int index) {
- uint8 r, g, b;
- if (index < 4 || _renderMode == Common::kRenderEGA) {
- _gfx->readFromPalette(index, r, g, b);
- return _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b);
- }
- _gfx->readFromPalette(index / 4, r, g, b);
- return _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b);
-}
-
-void FreescapeEngine::renderPixels8bitTitleImage(Graphics::Surface *surface, int &i, int &j, int pixels) {
- int c1 = pixels >> 4;
- int c2 = pixels & 0xf;
-
- if (i == 320) {
- return;
- }
-
- if (_renderMode == Common::kRenderCGA) {
- surface->setPixel(i, j, getPixel8bitTitleImage(c1 / 4));
- i++;
- if (i == 320) {
- return;
- }
- }
-
- surface->setPixel(i, j, getPixel8bitTitleImage(c1));
- i++;
-
- if (i == 320) {
- return;
- }
-
- if (_renderMode == Common::kRenderCGA) {
- surface->setPixel(i, j, getPixel8bitTitleImage(c2 / 4));
- i++;
-
- if (i == 320) {
- return;
- }
- }
-
- surface->setPixel(i, j, getPixel8bitTitleImage(c2));
- i++;
-}
-
-Graphics::Surface *FreescapeEngine::load8bitTitleImage(Common::SeekableReadStream *file, int offset) {
- Graphics::Surface *surface = new Graphics::Surface();
- if (_renderMode == Common::kRenderCGA)
- _gfx->_palette = (byte *)kCGAPalettePinkBlueWhiteData;
- else if (_renderMode == Common::kRenderEGA)
- _gfx->_palette = (byte *)kEGADefaultPaletteData;
- else
- error("Invalid render mode: %d", _renderMode);
- surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
- uint32 black = _gfx->_currentPixelFormat.ARGBToColor(0xFF, 0, 0, 0);
- surface->fillRect(Common::Rect(0, 0, 320, 200), black);
-
- int i = 0;
- int j = 0;
- int command = -1;
- int singlePixelsToProcess = 0;
- bool repeatedPixelsToProcess = false;
- file->seek(offset);
- while (!file->eos()) {
- assert(i <= 320);
- int pixels = -1;
- int repetition = -1;
-
- if (singlePixelsToProcess == 0 && !repeatedPixelsToProcess) {
- if (command < 0)
- command = file->readByte();
-
- //debug("reading command: %x at %lx", command, file->pos() - 1);
-
- assert(command >= 0x7f);
- singlePixelsToProcess = (0xff - command + 2) * 2;
- //debug("single Pixels to process: %d", singlePixelsToProcess);
-
- repeatedPixelsToProcess = true;
- if (i == 320) {
- j++;
- i = 0;
- }
- command = -1;
- continue;
- }
-
- if (singlePixelsToProcess > 0) {
- singlePixelsToProcess--;
- pixels = file->readByte();
- //debug("reading pixels: %x at %d, %d", pixels, i, j);
- renderPixels8bitTitleImage(surface, i, j, pixels);
- } else if (repeatedPixelsToProcess) {
- repetition = file->readByte() + 1;
- //debug("reading repetition: %x", repetition - 1);
- assert(repetition > 0);
- if (repetition >= 0x80) {
- command = repetition - 1;
- repeatedPixelsToProcess = false;
- continue;
- }
-
- if (i == 320) {
- j++;
- i = 0;
- continue;
- }
-
- int pixels1 = file->readByte();
- //debug("reading pixels: %x", pixels1);
-
- int pixels2 = file->readByte();
- //debug("reading pixels: %x", pixels2);
-
- if (repetition >= 1) {
- while (repetition > 0) {
- repetition--;
-
- if (i == 320) {
- j++;
- i = 0;
- }
-
- if (j == 200)
- return surface;
-
- //sdebug("repeating pixels: %x at %d, %d", pixels1, i, j);
- renderPixels8bitTitleImage(surface, i, j, pixels1);
-
- if (i == 320) {
- j++;
- i = 0;
- }
-
- if (j == 200)
- return surface;
-
- //debug("repeating pixels: %x at %d, %d", pixels2, i, j);
- renderPixels8bitTitleImage(surface, i, j, pixels2);
- }
- }
- }
- }
-
- return surface;
-}
-
void FreescapeEngine::renderPixels8bitBinImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color) {
if (i >= 320) {
//debug("cannot continue, stopping here at row %d!", j);
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 556a28f6efa..52433360c8e 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -6,7 +6,8 @@ MODULE_OBJS := \
freescape.o \
games/castle.o \
games/dark.o \
- games/driller.o \
+ games/driller/dos.o \
+ games/driller/driller.o \
games/eclipse.o \
games/palettes.o \
gfx.o \
Commit: fa75a25946e15f39912ea0ae26ed40ff38b85407
https://github.com/scummvm/scummvm/commit/fa75a25946e15f39912ea0ae26ed40ff38b85407
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:16:41+01:00
Commit Message:
FREESCAPE: refactored driller cpc code into a directory
Changed paths:
A engines/freescape/games/driller/cpc.cpp
engines/freescape/games/driller/driller.cpp
engines/freescape/module.mk
diff --git a/engines/freescape/games/driller/cpc.cpp b/engines/freescape/games/driller/cpc.cpp
new file mode 100644
index 00000000000..dce9d4a6110
--- /dev/null
+++ b/engines/freescape/games/driller/cpc.cpp
@@ -0,0 +1,197 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/file.h"
+
+#include "freescape/freescape.h"
+#include "freescape/language/8bitDetokeniser.h"
+
+namespace Freescape {
+
+byte *parseEDSK(const Common::String filename, int &size) {
+ debugC(1, kFreescapeDebugParser, "Trying to parse edsk file: %s", filename.c_str());
+ Common::File file;
+ file.open(filename);
+ if (!file.isOpen())
+ error("Failed to open %s", filename.c_str());
+
+ int totalSize = file.size();
+ byte *edskBuffer = (byte *)malloc(totalSize);
+ file.read(edskBuffer, totalSize);
+ file.close();
+
+ // We don't know the final size, but we allocate enough
+ byte *memBuffer = (byte *)malloc(totalSize);
+
+ byte nsides = edskBuffer[49];
+ assert(nsides == 1);
+ int ntracks = 0;
+ int i = 256;
+ int j = 0;
+ while (i + 1 < totalSize) {
+ byte ssize = edskBuffer[i + 0x14];
+ debugC(1, kFreescapeDebugParser, "i: %x ssize: %d, number: %d", i, ssize, edskBuffer[i + 0x10]);
+ assert(ssize == 3 || edskBuffer[i + 0x0] == 'T');
+ assert(ssize == 3 || edskBuffer[i + 0x1] == 'r');
+ assert(ssize == 3 || edskBuffer[i + 0x2] == 'a');
+ //assert(ssize == 3 || ntracks == edskBuffer[i + 0x10]);
+ int start = i + 0x100;
+ debugC(1, kFreescapeDebugParser, "sector size: %d", ssize);
+ if (ssize == 2) {
+ i = i + 9 * 512 + 256;
+ } else if (ssize == 5) {
+ i = i + 8 * 512 + 256;
+ } else if (ssize == 0) {
+ i = totalSize - 1;
+ } else if (ssize == 3) {
+ break; // Not sure
+ } else {
+ error("ssize: %d", ssize);
+ }
+ int osize = i - start;
+ debugC(1, kFreescapeDebugParser, "copying track %d start: %x size: %x, dest: %x", ntracks, start, osize, j);
+ memcpy(memBuffer + j, edskBuffer + start, osize);
+ j = j + osize;
+ ntracks++;
+ }
+ size = j;
+
+ if (0) { // Useful to debug where exactly each object is located in memory once it is parsed
+ i = 0;
+ while(i < j) {
+ debugN("%05x: ", i);
+ for (int k = 0; k <= 16; k++) {
+ debugN("%02x ", memBuffer[i]);
+ i++;
+ }
+ debugN("\n");
+ }
+ }
+ free(edskBuffer);
+ return memBuffer;
+}
+
+void deobfuscateDrillerCPCVirtualWorlds(byte *memBuffer) {
+ // Deofuscation / loader code
+ for (int j = 0; j < 0x200; j++) {
+ memBuffer[0x14000 + j] = memBuffer[0x14200 + j];
+ memBuffer[0x14200 + j] = memBuffer[0x13400 + j];
+ memBuffer[0x14400 + j] = memBuffer[0x13800 + j];
+ memBuffer[0x14600 + j] = memBuffer[0x13c00 + j];
+ }
+
+ for (int j = 0; j < 0x200; j++) {
+ memBuffer[0x13c00 + j] = memBuffer[0x13a00 + j];
+ memBuffer[0x13a00 + j] = memBuffer[0x13600 + j];
+ memBuffer[0x13800 + j] = memBuffer[0x13200 + j];
+ memBuffer[0x13600 + j] = memBuffer[0x12e00 + j];
+ memBuffer[0x12e00 + j] = memBuffer[0x13000 + j];
+ memBuffer[0x13000 + j] = memBuffer[0x12200 + j];
+ memBuffer[0x13200 + j] = memBuffer[0x12600 + j];
+ memBuffer[0x13400 + j] = memBuffer[0x12a00 + j];
+ }
+
+ for (int i = 6; i >= 0; i--) {
+ //debug("copying 0x200 bytes to %x from %x", 0x12000 + 0x200*i, 0x11400 + 0x400*i);
+ for (int j = 0; j < 0x200; j++) {
+ memBuffer[0x12000 + 0x200*i + j] = memBuffer[0x11400 + 0x400*i + j];
+ }
+ }
+
+ for (int j = 0; j < 0x200; j++) {
+ memBuffer[0x11c00 + j] = memBuffer[0x11e00 + j];
+ memBuffer[0x11e00 + j] = memBuffer[0x11000 + j];
+ }
+}
+
+void DrillerEngine::drawCPCUI(Graphics::Surface *surface) {
+ uint32 color = 1;
+ uint8 r, g, b;
+
+ _gfx->selectColorFromFourColorPalette(color, r, g, b);
+ uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+ color = 0;
+ if (_gfx->_colorRemaps && _gfx->_colorRemaps->contains(color)) {
+ color = (*_gfx->_colorRemaps)[color];
+ }
+
+ _gfx->readFromPalette(color, r, g, b);
+ uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+ int score = _gameStateVars[k8bitVariableScore];
+ drawStringInSurface(_currentArea->_name, 200, 188, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 149, 148, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 149, 156, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 149, 164, front, back, surface);
+ if (_playerHeightNumber >= 0)
+ drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 54, 164, front, back, surface);
+ else
+ drawStringInSurface(Common::String::format("%s", "J"), 54, 164, front, back, surface);
+
+ drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 46, 148, front, back, surface);
+ drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 44, 156, front, back, surface);
+ drawStringInSurface(Common::String::format("%07d", score), 239, 132, front, back, surface);
+
+ int seconds, minutes, hours;
+ getTimeFromCountdown(seconds, minutes, hours);
+ drawStringInSurface(Common::String::format("%02d", hours), 209, 11, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", minutes), 232, 11, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", seconds), 254, 11, front, back, surface);
+
+ Common::String message;
+ int deadline;
+ getLatestMessages(message, deadline);
+ if (deadline <= _countdown) {
+ drawStringInSurface(message, 191, 180, back, front, surface);
+ _temporaryMessages.push_back(message);
+ _temporaryMessageDeadlines.push_back(deadline);
+ } else if (_messagesList.size() > 0) {
+ if (_currentArea->_gasPocketRadius == 0)
+ message = _messagesList[2];
+ else if (_drillStatusByArea[_currentArea->getAreaID()])
+ message = _messagesList[0];
+ else
+ message = _messagesList[1];
+
+ drawStringInSurface(message, 191, 180, front, back, surface);
+ }
+
+ int energy = _gameStateVars[k8bitVariableEnergy];
+ int shield = _gameStateVars[k8bitVariableShield];
+
+ if (energy >= 0) {
+ Common::Rect backBar(25, 187, 89 - energy, 194);
+ surface->fillRect(backBar, back);
+ Common::Rect energyBar(88 - energy, 187, 88, 194);
+ surface->fillRect(energyBar, front);
+ }
+
+ if (shield >= 0) {
+ Common::Rect backBar(25, 180, 89 - shield, 186);
+ surface->fillRect(backBar, back);
+
+ Common::Rect shieldBar(88 - shield, 180, 88, 186);
+ surface->fillRect(shieldBar, front);
+ }
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 06fe7489531..4e8f5cab455 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -393,101 +393,8 @@ void DrillerEngine::loadAssetsDemo() {
_angleRotationIndex = 0;
}
-byte *parseEDSK(const Common::String filename, int &size) {
- debugC(1, kFreescapeDebugParser, "Trying to parse edsk file: %s", filename.c_str());
- Common::File file;
- file.open(filename);
- if (!file.isOpen())
- error("Failed to open %s", filename.c_str());
-
- int totalSize = file.size();
- byte *edskBuffer = (byte *)malloc(totalSize);
- file.read(edskBuffer, totalSize);
- file.close();
-
- // We don't know the final size, but we allocate enough
- byte *memBuffer = (byte *)malloc(totalSize);
-
- byte nsides = edskBuffer[49];
- assert(nsides == 1);
- int ntracks = 0;
- int i = 256;
- int j = 0;
- while (i + 1 < totalSize) {
- byte ssize = edskBuffer[i + 0x14];
- debug("i: %x ssize: %d, number: %d", i, ssize, edskBuffer[i + 0x10]);
- assert(ssize == 3 || edskBuffer[i + 0x0] == 'T');
- assert(ssize == 3 || edskBuffer[i + 0x1] == 'r');
- assert(ssize == 3 || edskBuffer[i + 0x2] == 'a');
- //assert(ssize == 3 || ntracks == edskBuffer[i + 0x10]);
- int start = i + 0x100;
- debugC(1, kFreescapeDebugParser, "sector size: %d", ssize);
- if (ssize == 2) {
- i = i + 9 * 512 + 256;
- } else if (ssize == 5) {
- i = i + 8 * 512 + 256;
- } else if (ssize == 0) {
- i = totalSize - 1;
- } else if (ssize == 3) {
- break; // Not sure
- } else {
- error("ssize: %d", ssize);
- }
- int osize = i - start;
- debugC(1, kFreescapeDebugParser, "copying track %d start: %x size: %x, dest: %x", ntracks, start, osize, j);
- memcpy(memBuffer + j, edskBuffer + start, osize);
- j = j + osize;
- ntracks++;
- }
- size = j;
-
- if (0) { // Useful to debug where exactly each object is located in memory once it is parsed
- i = 0;
- while(i < j) {
- debugN("%05x: ", i);
- for (int k = 0; k <= 16; k++) {
- debugN("%02x ", memBuffer[i]);
- i++;
- }
- debugN("\n");
- }
- }
- free(edskBuffer);
- return memBuffer;
-}
-
-void deobfuscateDrillerCPCVirtualWorlds(byte *memBuffer) {
- // Deofuscation / loader code
- for (int j = 0; j < 0x200; j++) {
- memBuffer[0x14000 + j] = memBuffer[0x14200 + j];
- memBuffer[0x14200 + j] = memBuffer[0x13400 + j];
- memBuffer[0x14400 + j] = memBuffer[0x13800 + j];
- memBuffer[0x14600 + j] = memBuffer[0x13c00 + j];
- }
-
- for (int j = 0; j < 0x200; j++) {
- memBuffer[0x13c00 + j] = memBuffer[0x13a00 + j];
- memBuffer[0x13a00 + j] = memBuffer[0x13600 + j];
- memBuffer[0x13800 + j] = memBuffer[0x13200 + j];
- memBuffer[0x13600 + j] = memBuffer[0x12e00 + j];
- memBuffer[0x12e00 + j] = memBuffer[0x13000 + j];
- memBuffer[0x13000 + j] = memBuffer[0x12200 + j];
- memBuffer[0x13200 + j] = memBuffer[0x12600 + j];
- memBuffer[0x13400 + j] = memBuffer[0x12a00 + j];
- }
-
- for (int i = 6; i >= 0; i--) {
- //debug("copying 0x200 bytes to %x from %x", 0x12000 + 0x200*i, 0x11400 + 0x400*i);
- for (int j = 0; j < 0x200; j++) {
- memBuffer[0x12000 + 0x200*i + j] = memBuffer[0x11400 + 0x400*i + j];
- }
- }
-
- for (int j = 0; j < 0x200; j++) {
- memBuffer[0x11c00 + j] = memBuffer[0x11e00 + j];
- memBuffer[0x11e00 + j] = memBuffer[0x11000 + j];
- }
-}
+extern byte *parseEDSK(const Common::String filename, int &size);
+extern void deobfuscateDrillerCPCVirtualWorlds(byte *memBuffer);
void DrillerEngine::loadAssetsFullGame() {
Common::File file;
@@ -811,78 +718,6 @@ void DrillerEngine::drawUI() {
delete surface;
}
-void DrillerEngine::drawCPCUI(Graphics::Surface *surface) {
- uint32 color = 1;
- uint8 r, g, b;
-
- _gfx->selectColorFromFourColorPalette(color, r, g, b);
- uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
-
- color = 0;
- if (_gfx->_colorRemaps && _gfx->_colorRemaps->contains(color)) {
- color = (*_gfx->_colorRemaps)[color];
- }
-
- _gfx->readFromPalette(color, r, g, b);
- uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
-
- int score = _gameStateVars[k8bitVariableScore];
- drawStringInSurface(_currentArea->_name, 200, 188, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 149, 148, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 149, 156, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 149, 164, front, back, surface);
- if (_playerHeightNumber >= 0)
- drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 54, 164, front, back, surface);
- else
- drawStringInSurface(Common::String::format("%s", "J"), 54, 164, front, back, surface);
-
- drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 46, 148, front, back, surface);
- drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 44, 156, front, back, surface);
- drawStringInSurface(Common::String::format("%07d", score), 239, 132, front, back, surface);
-
- int seconds, minutes, hours;
- getTimeFromCountdown(seconds, minutes, hours);
- drawStringInSurface(Common::String::format("%02d", hours), 209, 11, front, back, surface);
- drawStringInSurface(Common::String::format("%02d", minutes), 232, 11, front, back, surface);
- drawStringInSurface(Common::String::format("%02d", seconds), 254, 11, front, back, surface);
-
- Common::String message;
- int deadline;
- getLatestMessages(message, deadline);
- if (deadline <= _countdown) {
- drawStringInSurface(message, 191, 180, back, front, surface);
- _temporaryMessages.push_back(message);
- _temporaryMessageDeadlines.push_back(deadline);
- } else if (_messagesList.size() > 0) {
- if (_currentArea->_gasPocketRadius == 0)
- message = _messagesList[2];
- else if (_drillStatusByArea[_currentArea->getAreaID()])
- message = _messagesList[0];
- else
- message = _messagesList[1];
-
- drawStringInSurface(message, 191, 180, front, back, surface);
- }
-
- int energy = _gameStateVars[k8bitVariableEnergy];
- int shield = _gameStateVars[k8bitVariableShield];
-
- if (energy >= 0) {
- Common::Rect backBar(25, 187, 89 - energy, 194);
- surface->fillRect(backBar, back);
- Common::Rect energyBar(88 - energy, 187, 88, 194);
- surface->fillRect(energyBar, front);
- }
-
- if (shield >= 0) {
- Common::Rect backBar(25, 180, 89 - shield, 186);
- surface->fillRect(backBar, back);
-
- Common::Rect shieldBar(88 - shield, 180, 88, 186);
- surface->fillRect(shieldBar, front);
- }
-}
-
void DrillerEngine::drawC64UI(Graphics::Surface *surface) {
uint32 color = 1;
uint8 r, g, b;
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 52433360c8e..bb36272aaa4 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS := \
freescape.o \
games/castle.o \
games/dark.o \
+ games/driller/cpc.o \
games/driller/dos.o \
games/driller/driller.o \
games/eclipse.o \
Commit: 563c6b35bd1f6b07c7e42781e0dd92dc188d07db
https://github.com/scummvm/scummvm/commit/563c6b35bd1f6b07c7e42781e0dd92dc188d07db
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:16:52+01:00
Commit Message:
FREESCAPE: refactored driller zx code into a directory
Changed paths:
A engines/freescape/games/driller/zx.cpp
engines/freescape/games/driller/driller.cpp
engines/freescape/module.mk
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 4e8f5cab455..0ece48d0123 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -790,79 +790,6 @@ void DrillerEngine::drawC64UI(Graphics::Surface *surface) {
}
}
-void DrillerEngine::drawZXUI(Graphics::Surface *surface) {
- uint32 color = 5;
- uint8 r, g, b;
-
- _gfx->readFromPalette(color, r, g, b);
- uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
-
- color = _currentArea->_usualBackgroundColor;
- if (_gfx->_colorRemaps && _gfx->_colorRemaps->contains(color)) {
- color = (*_gfx->_colorRemaps)[color];
- }
-
- _gfx->readFromPalette(color, r, g, b);
- uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
- uint32 white = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0xFF);
-
- int score = _gameStateVars[k8bitVariableScore];
- drawStringInSurface(_currentArea->_name, 174, 188, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 150, 149, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 150, 157, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 150, 165, front, back, surface);
- if (_playerHeightNumber >= 0)
- drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 72, 165, front, back, surface);
- else
- drawStringInSurface(Common::String::format("%s", "J"), 72, 165, front, back, surface);
-
- drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 62, 149, front, back, surface);
- drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 63, 157, front, back, surface);
- drawStringInSurface(Common::String::format("%07d", score), 215, 133, white, back, surface);
-
- int seconds, minutes, hours;
- getTimeFromCountdown(seconds, minutes, hours);
- drawStringInSurface(Common::String::format("%02d", hours), 185, 12, front, back, surface);
- drawStringInSurface(Common::String::format("%02d", minutes), 207, 12, front, back, surface);
- drawStringInSurface(Common::String::format("%02d", seconds), 230, 12, front, back, surface);
-
- Common::String message;
- int deadline;
- getLatestMessages(message, deadline);
- if (deadline <= _countdown) {
- drawStringInSurface(message, 167, 181, back, front, surface);
- _temporaryMessages.push_back(message);
- _temporaryMessageDeadlines.push_back(deadline);
- } else {
- if (_currentArea->_gasPocketRadius == 0)
- message = _messagesList[2];
- else if (_drillStatusByArea[_currentArea->getAreaID()])
- message = _messagesList[0];
- else
- message = _messagesList[1];
-
- drawStringInSurface(message, 167, 181, front, back, surface);
- }
-
- int energy = _gameStateVars[k8bitVariableEnergy];
- int shield = _gameStateVars[k8bitVariableShield];
-
- if (energy >= 0) {
- Common::Rect backBar(43, 188, 107 - energy, 194);
- surface->fillRect(backBar, back);
- Common::Rect energyBar(106 - energy, 188, 106, 194);
- surface->fillRect(energyBar, front);
- }
-
- if (shield >= 0) {
- Common::Rect backBar(43, 181, 107 - shield, 187);
- surface->fillRect(backBar, back);
-
- Common::Rect shieldBar(106 - shield, 181, 106, 187);
- surface->fillRect(shieldBar, front);
- }
-}
-
void DrillerEngine::drawAmigaAtariSTUI(Graphics::Surface *surface) {
uint32 white = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0xFF);
uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
diff --git a/engines/freescape/games/driller/zx.cpp b/engines/freescape/games/driller/zx.cpp
new file mode 100644
index 00000000000..482bde642bc
--- /dev/null
+++ b/engines/freescape/games/driller/zx.cpp
@@ -0,0 +1,100 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "freescape/freescape.h"
+#include "freescape/language/8bitDetokeniser.h"
+
+namespace Freescape {
+
+void DrillerEngine::drawZXUI(Graphics::Surface *surface) {
+ uint32 color = 5;
+ uint8 r, g, b;
+
+ _gfx->readFromPalette(color, r, g, b);
+ uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+ color = _currentArea->_usualBackgroundColor;
+ if (_gfx->_colorRemaps && _gfx->_colorRemaps->contains(color)) {
+ color = (*_gfx->_colorRemaps)[color];
+ }
+
+ _gfx->readFromPalette(color, r, g, b);
+ uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+ uint32 white = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0xFF);
+
+ int score = _gameStateVars[k8bitVariableScore];
+ drawStringInSurface(_currentArea->_name, 174, 188, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 150, 149, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 150, 157, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 150, 165, front, back, surface);
+ if (_playerHeightNumber >= 0)
+ drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 72, 165, front, back, surface);
+ else
+ drawStringInSurface(Common::String::format("%s", "J"), 72, 165, front, back, surface);
+
+ drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 62, 149, front, back, surface);
+ drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 63, 157, front, back, surface);
+ drawStringInSurface(Common::String::format("%07d", score), 215, 133, white, back, surface);
+
+ int seconds, minutes, hours;
+ getTimeFromCountdown(seconds, minutes, hours);
+ drawStringInSurface(Common::String::format("%02d", hours), 185, 12, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", minutes), 207, 12, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", seconds), 230, 12, front, back, surface);
+
+ Common::String message;
+ int deadline;
+ getLatestMessages(message, deadline);
+ if (deadline <= _countdown) {
+ drawStringInSurface(message, 167, 181, back, front, surface);
+ _temporaryMessages.push_back(message);
+ _temporaryMessageDeadlines.push_back(deadline);
+ } else {
+ if (_currentArea->_gasPocketRadius == 0)
+ message = _messagesList[2];
+ else if (_drillStatusByArea[_currentArea->getAreaID()])
+ message = _messagesList[0];
+ else
+ message = _messagesList[1];
+
+ drawStringInSurface(message, 167, 181, front, back, surface);
+ }
+
+ int energy = _gameStateVars[k8bitVariableEnergy];
+ int shield = _gameStateVars[k8bitVariableShield];
+
+ if (energy >= 0) {
+ Common::Rect backBar(43, 188, 107 - energy, 194);
+ surface->fillRect(backBar, back);
+ Common::Rect energyBar(106 - energy, 188, 106, 194);
+ surface->fillRect(energyBar, front);
+ }
+
+ if (shield >= 0) {
+ Common::Rect backBar(43, 181, 107 - shield, 187);
+ surface->fillRect(backBar, back);
+
+ Common::Rect shieldBar(106 - shield, 181, 106, 187);
+ surface->fillRect(shieldBar, front);
+ }
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index bb36272aaa4..fd52dedacf2 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -9,6 +9,7 @@ MODULE_OBJS := \
games/driller/cpc.o \
games/driller/dos.o \
games/driller/driller.o \
+ games/driller/zx.o \
games/eclipse.o \
games/palettes.o \
gfx.o \
Commit: 3e5d0a3ad047d7148cb0246b1e3d26df6419f0a7
https://github.com/scummvm/scummvm/commit/3e5d0a3ad047d7148cb0246b1e3d26df6419f0a7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:17:01+01:00
Commit Message:
FREESCAPE: refactored driller amiga/atari code into a directory
Changed paths:
A engines/freescape/games/driller/amiga.cpp
engines/freescape/games/driller/driller.cpp
engines/freescape/module.mk
diff --git a/engines/freescape/games/driller/amiga.cpp b/engines/freescape/games/driller/amiga.cpp
new file mode 100644
index 00000000000..913c267c33b
--- /dev/null
+++ b/engines/freescape/games/driller/amiga.cpp
@@ -0,0 +1,114 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "freescape/freescape.h"
+#include "freescape/language/8bitDetokeniser.h"
+
+/*
+This file contains specific code for both Ammiga and AtariST implementations of Driller
+*/
+
+namespace Freescape {
+
+void DrillerEngine::drawAmigaAtariSTUI(Graphics::Surface *surface) {
+ uint32 white = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0xFF);
+ uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
+ uint32 brownish = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x9E, 0x80, 0x20);
+ uint32 brown = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x7E, 0x60, 0x19);
+ uint32 black = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
+ uint32 transparent = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0x00, 0x00, 0x00);
+
+ int score = _gameStateVars[k8bitVariableScore];
+ Common::String coords;
+
+ if (!isDemo()) { // It seems demos will not include the complete font?
+ drawStringInSurface("x", 37, 18, white, transparent, surface, 82);
+ coords = Common::String::format("%04d", 2 * int(_position.x()));
+ for (int i = 0; i < 4; i++)
+ drawStringInSurface(Common::String(coords[i]), 47 + 6*i, 18, white, transparent, surface, 112);
+
+ drawStringInSurface("y", 37, 26, white, transparent, surface, 82);
+ coords = Common::String::format("%04d", 2 * int(_position.z())); // Coords y and z are swapped!
+ for (int i = 0; i < 4; i++)
+ drawStringInSurface(Common::String(coords[i]), 47 + 6*i, 26, white, transparent, surface, 112);
+
+ drawStringInSurface("z", 37, 34, white, transparent, surface, 82);
+ coords = Common::String::format("%04d", 2 * int(_position.y())); // Coords y and z are swapped!
+ for (int i = 0; i < 4; i++)
+ drawStringInSurface(Common::String(coords[i]), 47 + 6*i, 34, white, transparent, surface, 112);
+ }
+
+ drawStringInSurface(_currentArea->_name, 188, 185, yellow, black, surface);
+ drawStringInSurface(Common::String::format("%07d", score), 240, 129, yellow, black, surface);
+
+ int seconds, minutes, hours;
+ getTimeFromCountdown(seconds, minutes, hours);
+ drawStringInSurface(Common::String::format("%02d:", hours), 208, 7, yellow, black, surface);
+ drawStringInSurface(Common::String::format("%02d:", minutes), 230, 7, yellow, black, surface);
+ drawStringInSurface(Common::String::format("%02d", seconds), 254, 7, yellow, black, surface);
+
+ Common::String message;
+ int deadline;
+ getLatestMessages(message, deadline);
+ if (deadline <= _countdown) {
+ drawStringInSurface(message, 188, 177, black, yellow, surface);
+ _temporaryMessages.push_back(message);
+ _temporaryMessageDeadlines.push_back(deadline);
+ } else {
+ if (_currentArea->_gasPocketRadius == 0)
+ message = _messagesList[2];
+ else if (_drillStatusByArea[_currentArea->getAreaID()])
+ message = _messagesList[0];
+ else
+ message = _messagesList[1];
+
+ drawStringInSurface(message, 188, 177, yellow, black, surface);
+ }
+
+ int energy = _gameStateVars[k8bitVariableEnergy];
+ int shield = _gameStateVars[k8bitVariableShield];
+
+ if (shield >= 0) {
+ Common::Rect shieldBar;
+ shieldBar = Common::Rect(11, 178, 76 - (k8bitMaxShield - shield), 184);
+ surface->fillRect(shieldBar, brown);
+
+ shieldBar = Common::Rect(11, 179, 76 - (k8bitMaxShield - shield), 183);
+ surface->fillRect(shieldBar, brownish);
+
+ shieldBar = Common::Rect(11, 180, 76 - (k8bitMaxShield - shield), 182);
+ surface->fillRect(shieldBar, yellow);
+ }
+
+ if (energy >= 0) {
+ Common::Rect energyBar;
+ energyBar = Common::Rect(11, 186, 75 - (k8bitMaxEnergy - energy), 192);
+ surface->fillRect(energyBar, brown);
+
+ energyBar = Common::Rect(11, 187, 75 - (k8bitMaxEnergy - energy), 191);
+ surface->fillRect(energyBar, brownish);
+
+ energyBar = Common::Rect(11, 188, 75 - (k8bitMaxEnergy - energy), 190);
+ surface->fillRect(energyBar, yellow);
+ }
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 0ece48d0123..73179d250e4 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -790,89 +790,6 @@ void DrillerEngine::drawC64UI(Graphics::Surface *surface) {
}
}
-void DrillerEngine::drawAmigaAtariSTUI(Graphics::Surface *surface) {
- uint32 white = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0xFF);
- uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
- uint32 brownish = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x9E, 0x80, 0x20);
- uint32 brown = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x7E, 0x60, 0x19);
- uint32 black = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
- uint32 transparent = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0x00, 0x00, 0x00);
-
- int score = _gameStateVars[k8bitVariableScore];
- Common::String coords;
-
- if (!isDemo()) { // It seems demos will not include the complete font?
- drawStringInSurface("x", 37, 18, white, transparent, surface, 82);
- coords = Common::String::format("%04d", 2 * int(_position.x()));
- for (int i = 0; i < 4; i++)
- drawStringInSurface(Common::String(coords[i]), 47 + 6*i, 18, white, transparent, surface, 112);
-
- drawStringInSurface("y", 37, 26, white, transparent, surface, 82);
- coords = Common::String::format("%04d", 2 * int(_position.z())); // Coords y and z are swapped!
- for (int i = 0; i < 4; i++)
- drawStringInSurface(Common::String(coords[i]), 47 + 6*i, 26, white, transparent, surface, 112);
-
- drawStringInSurface("z", 37, 34, white, transparent, surface, 82);
- coords = Common::String::format("%04d", 2 * int(_position.y())); // Coords y and z are swapped!
- for (int i = 0; i < 4; i++)
- drawStringInSurface(Common::String(coords[i]), 47 + 6*i, 34, white, transparent, surface, 112);
- }
-
- drawStringInSurface(_currentArea->_name, 188, 185, yellow, black, surface);
- drawStringInSurface(Common::String::format("%07d", score), 240, 129, yellow, black, surface);
-
- int seconds, minutes, hours;
- getTimeFromCountdown(seconds, minutes, hours);
- drawStringInSurface(Common::String::format("%02d:", hours), 208, 7, yellow, black, surface);
- drawStringInSurface(Common::String::format("%02d:", minutes), 230, 7, yellow, black, surface);
- drawStringInSurface(Common::String::format("%02d", seconds), 254, 7, yellow, black, surface);
-
- Common::String message;
- int deadline;
- getLatestMessages(message, deadline);
- if (deadline <= _countdown) {
- drawStringInSurface(message, 188, 177, black, yellow, surface);
- _temporaryMessages.push_back(message);
- _temporaryMessageDeadlines.push_back(deadline);
- } else {
- if (_currentArea->_gasPocketRadius == 0)
- message = _messagesList[2];
- else if (_drillStatusByArea[_currentArea->getAreaID()])
- message = _messagesList[0];
- else
- message = _messagesList[1];
-
- drawStringInSurface(message, 188, 177, yellow, black, surface);
- }
-
- int energy = _gameStateVars[k8bitVariableEnergy];
- int shield = _gameStateVars[k8bitVariableShield];
-
- if (shield >= 0) {
- Common::Rect shieldBar;
- shieldBar = Common::Rect(11, 178, 76 - (k8bitMaxShield - shield), 184);
- surface->fillRect(shieldBar, brown);
-
- shieldBar = Common::Rect(11, 179, 76 - (k8bitMaxShield - shield), 183);
- surface->fillRect(shieldBar, brownish);
-
- shieldBar = Common::Rect(11, 180, 76 - (k8bitMaxShield - shield), 182);
- surface->fillRect(shieldBar, yellow);
- }
-
- if (energy >= 0) {
- Common::Rect energyBar;
- energyBar = Common::Rect(11, 186, 75 - (k8bitMaxEnergy - energy), 192);
- surface->fillRect(energyBar, brown);
-
- energyBar = Common::Rect(11, 187, 75 - (k8bitMaxEnergy - energy), 191);
- surface->fillRect(energyBar, brownish);
-
- energyBar = Common::Rect(11, 188, 75 - (k8bitMaxEnergy - energy), 190);
- surface->fillRect(energyBar, yellow);
- }
-}
-
void DrillerEngine::drawInfoMenu() {
_savedScreen = _gfx->getScreenshot();
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index fd52dedacf2..b3baab38526 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS := \
freescape.o \
games/castle.o \
games/dark.o \
+ games/driller/amiga.o \
games/driller/cpc.o \
games/driller/dos.o \
games/driller/driller.o \
Commit: 6ae0763ee4ee42897071b9ed68b63226fe9aab6d
https://github.com/scummvm/scummvm/commit/6ae0763ee4ee42897071b9ed68b63226fe9aab6d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:17:11+01:00
Commit Message:
FREESCAPE: refactored/moved driller code for loading assets in different platforms code
Changed paths:
engines/freescape/freescape.h
engines/freescape/games/driller/amiga.cpp
engines/freescape/games/driller/cpc.cpp
engines/freescape/games/driller/dos.cpp
engines/freescape/games/driller/driller.cpp
engines/freescape/games/driller/zx.cpp
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index f45c683dfc4..8b05dd4291b 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -439,6 +439,18 @@ private:
void loadAssetsDemo();
void loadAssetsFullGame();
+ void loadAssetsAmigaFullGame();
+ void loadAssetsAmigaDemo();
+
+ void loadAssetsDOSFullGame();
+ void loadAssetsDOSDemo();
+
+ void loadAssetsZXFullGame();
+ void loadAssetsZXDemo();
+
+ void loadAssetsCPCFullGame();
+ void loadAssetsCPCDemo();
+
void drawDOSUI(Graphics::Surface *surface);
void drawZXUI(Graphics::Surface *surface);
void drawCPCUI(Graphics::Surface *surface);
diff --git a/engines/freescape/games/driller/amiga.cpp b/engines/freescape/games/driller/amiga.cpp
index 913c267c33b..f1a6e01b542 100644
--- a/engines/freescape/games/driller/amiga.cpp
+++ b/engines/freescape/games/driller/amiga.cpp
@@ -18,16 +18,122 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+#include "common/file.h"
#include "freescape/freescape.h"
#include "freescape/language/8bitDetokeniser.h"
+namespace Freescape {
+
+void DrillerEngine::loadAssetsAmigaFullGame() {
+ Common::File file;
+ if (_variant & GF_AMIGA_RETAIL) {
+ file.open("driller");
+
+ if (!file.isOpen())
+ error("Failed to open 'driller' executable for Amiga");
+
+ _border = loadAndConvertNeoImage(&file, 0x137f4);
+ byte *palette = (byte *)malloc(16 * 3);
+ for (int i = 0; i < 16; i++) { // gray scale palette
+ palette[i * 3 + 0] = i * (255 / 16);
+ palette[i * 3 + 1] = i * (255 / 16);
+ palette[i * 3 + 2] = i * (255 / 16);
+ }
+ _title = loadAndConvertNeoImage(&file, 0x10, palette);
+
+ loadFonts(&file, 0x8940);
+ loadMessagesFixedSize(&file, 0xc66e, 14, 20);
+ loadGlobalObjects(&file, 0xbd62);
+ load8bitBinary(&file, 0x29c16, 16);
+ loadPalettes(&file, 0x297d4);
+ loadSoundsFx(&file, 0x30e80, 25);
+ } else if (_variant & GF_AMIGA_BUDGET) {
+ file.open("lift.neo");
+ if (!file.isOpen())
+ error("Failed to open 'lift.neo' file");
+
+ _title = loadAndConvertNeoImage(&file, 0);
+
+ file.close();
+ file.open("console.neo");
+ if (!file.isOpen())
+ error("Failed to open 'console.neo' file");
+
+ _border = loadAndConvertNeoImage(&file, 0);
+
+ file.close();
+ file.open("driller");
+ if (!file.isOpen())
+ error("Failed to open 'driller' executable for Amiga");
+
+ loadFonts(&file, 0xa62);
+ loadMessagesFixedSize(&file, 0x499a, 14, 20);
+ loadGlobalObjects(&file, 0x4098);
+ load8bitBinary(&file, 0x21a3e, 16);
+ loadPalettes(&file, 0x215fc);
+
+ file.close();
+ file.open("soundfx");
+ if (!file.isOpen())
+ error("Failed to open 'soundfx' executable for Amiga");
+
+ loadSoundsFx(&file, 0, 25);
+ } else
+ error("Invalid or unknown Amiga release");
+}
+
+void DrillerEngine::loadAssetsAmigaDemo() {
+ Common::File file;
+ file.open("lift.neo");
+ if (!file.isOpen())
+ error("Failed to open 'lift.neo' file");
+
+ _title = loadAndConvertNeoImage(&file, 0);
+
+ file.close();
+ file.open("console.neo");
+ if (!file.isOpen())
+ error("Failed to open 'console.neo' file");
+
+ _border = loadAndConvertNeoImage(&file, 0);
+
+ file.close();
+ file.open("demo.cmd");
+ if (!file.isOpen())
+ error("Failed to open 'demo.cmd' file");
+
+ loadDemoData(&file, 0, 0x1000);
+
+ file.close();
+ file.open("data");
+ if (!file.isOpen())
+ error("Failed to open 'data' file");
+
+ load8bitBinary(&file, 0x442, 16);
+ loadPalettes(&file, 0x0);
+
+ file.close();
+ file.open("driller");
+ if (!file.isOpen())
+ error("Failed to open 'driller' file");
+
+ loadFonts(&file, 0xa30);
+ loadMessagesFixedSize(&file, 0x3960, 14, 20);
+ loadGlobalObjects(&file, 0x3716);
+
+ file.close();
+ file.open("soundfx");
+ if (!file.isOpen())
+ error("Failed to open 'soundfx' executable for Amiga");
+
+ loadSoundsFx(&file, 0, 25);
+}
+
/*
-This file contains specific code for both Ammiga and AtariST implementations of Driller
+The following function contains specific UI code for both Amiga and AtariST
*/
-namespace Freescape {
-
void DrillerEngine::drawAmigaAtariSTUI(Graphics::Surface *surface) {
uint32 white = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0xFF);
uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55);
diff --git a/engines/freescape/games/driller/cpc.cpp b/engines/freescape/games/driller/cpc.cpp
index dce9d4a6110..8bf22b5df99 100644
--- a/engines/freescape/games/driller/cpc.cpp
+++ b/engines/freescape/games/driller/cpc.cpp
@@ -20,6 +20,7 @@
*/
#include "common/file.h"
+#include "common/memstream.h"
#include "freescape/freescape.h"
#include "freescape/language/8bitDetokeniser.h"
@@ -122,6 +123,41 @@ void deobfuscateDrillerCPCVirtualWorlds(byte *memBuffer) {
}
}
+void DrillerEngine::loadAssetsCPCFullGame() {
+ Common::File file;
+
+ loadBundledImages();
+ byte *memBuffer;
+ int memSize = 0;
+ if (_variant & GF_CPC_VIRTUALWORLDS) {
+ memBuffer = parseEDSK("virtualworlds.A.cpc.edsk", memSize);
+ deobfuscateDrillerCPCVirtualWorlds(memBuffer);
+ } else
+ memBuffer = parseEDSK("driller.cpc.edsk", memSize);
+ assert(memSize > 0);
+ Common::SeekableReadStream *stream = new Common::MemoryReadStream((const byte*)memBuffer, memSize);
+
+ if (_variant & GF_CPC_RETAIL) {
+ loadMessagesFixedSize(stream, 0xb0f7, 14, 20);
+ loadFonts(stream, 0xeb14);
+ load8bitBinary(stream, 0xec76, 4);
+ loadGlobalObjects(stream, 0xacb2);
+ } else if (_variant & GF_CPC_RETAIL2) {
+ loadMessagesFixedSize(stream, 0xb0f7 - 0x3fab, 14, 20);
+ loadFonts(stream, 0xeb14 - 0x3fab);
+ load8bitBinary(stream, 0xaccb, 4);
+ loadGlobalObjects(stream, 0xacb2 - 0x3fab);
+ } else if (_variant & _variant & GF_CPC_VIRTUALWORLDS) {
+ load8bitBinary(stream, 0x11acb, 4);
+ } else if (_variant & GF_CPC_BUDGET) {
+ loadMessagesFixedSize(stream, 0x9ef7, 14, 20);
+ loadFonts(stream, 0xd914);
+ load8bitBinary(stream, 0xda76, 4);
+ loadGlobalObjects(stream, 0x9ab2);
+ } else
+ error("Unknown Amstrad CPC variant");
+}
+
void DrillerEngine::drawCPCUI(Graphics::Surface *surface) {
uint32 color = 1;
uint8 r, g, b;
diff --git a/engines/freescape/games/driller/dos.cpp b/engines/freescape/games/driller/dos.cpp
index ad61fa078d0..bb3f0b52d32 100644
--- a/engines/freescape/games/driller/dos.cpp
+++ b/engines/freescape/games/driller/dos.cpp
@@ -19,6 +19,8 @@
*
*/
+#include "common/file.h"
+
#include "freescape/freescape.h"
#include "freescape/language/8bitDetokeniser.h"
@@ -178,6 +180,76 @@ Graphics::Surface *DrillerEngine::load8bitTitleImage(Common::SeekableReadStream
}
return surface;
}
+void DrillerEngine::loadAssetsDOSFullGame() {
+ Common::File file;
+ if (_renderMode == Common::kRenderEGA) {
+ file.open("SCN1E.DAT");
+ if (file.isOpen()) {
+ _title = load8bitBinImage(&file, 0x0);
+ }
+ file.close();
+ file.open("EGATITLE.RL");
+ if (file.isOpen()) {
+ _title = load8bitTitleImage(&file, 0x1b3);
+ }
+ file.close();
+
+ file.open("DRILLE.EXE");
+
+ if (!file.isOpen())
+ error("Failed to open DRILLE.EXE");
+
+ loadMessagesFixedSize(&file, 0x4135, 14, 20);
+ loadFonts(&file, 0x99dd);
+ loadGlobalObjects(&file, 0x3b42);
+ load8bitBinary(&file, 0x9b40, 16);
+ _border = load8bitBinImage(&file, 0x210);
+ } else if (_renderMode == Common::kRenderCGA) {
+ file.open("SCN1C.DAT");
+ if (file.isOpen()) {
+ _title = load8bitBinImage(&file, 0x0);
+ }
+ file.close();
+ file.open("CGATITLE.RL");
+ if (file.isOpen()) {
+ _title = load8bitTitleImage(&file, 0x1b3);
+ }
+ file.close();
+ file.open("DRILLC.EXE");
+
+ if (!file.isOpen())
+ error("Failed to open DRILLC.EXE");
+
+ loadFonts(&file, 0x07a4a);
+ loadMessagesFixedSize(&file, 0x2585, 14, 20);
+ load8bitBinary(&file, 0x7bb0, 4);
+ loadGlobalObjects(&file, 0x1fa2);
+ _border = load8bitBinImage(&file, 0x210);
+ } else
+ error("Unsupported video mode for DOS");
+}
+
+void DrillerEngine::loadAssetsDOSDemo() {
+ Common::File file;
+ _renderMode = Common::kRenderCGA; // DOS demos is CGA only
+ _viewArea = Common::Rect(36, 16, 284, 117); // correct view area
+ _gfx->_renderMode = _renderMode;
+ loadBundledImages();
+ file.open("d2");
+ if (!file.isOpen())
+ error("Failed to open 'd2' file");
+
+ loadFonts(&file, 0x4eb0);
+ loadMessagesFixedSize(&file, 0x636, 14, 20);
+ load8bitBinary(&file, 0x55b0, 4);
+ loadGlobalObjects(&file, 0x8c);
+
+ // Fixed for a corrupted area names in the demo data
+ _areaMap[2]->_name = "LAPIS LAZULI";
+ _areaMap[3]->_name = "EMERALD";
+ _areaMap[8]->_name = "TOPAZ";
+ file.close();
+}
void DrillerEngine::drawDOSUI(Graphics::Surface *surface) {
uint32 color = _renderMode == Common::kRenderCGA ? 1 : 14;
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 73179d250e4..f1ea313ea11 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -22,7 +22,6 @@
#include "common/config-manager.h"
#include "common/events.h"
#include "common/file.h"
-#include "common/memstream.h"
#include "common/random.h"
#include "freescape/freescape.h"
@@ -279,49 +278,7 @@ void DrillerEngine::loadAssets() {
void DrillerEngine::loadAssetsDemo() {
Common::File file;
if (isAmiga()) {
- file.open("lift.neo");
- if (!file.isOpen())
- error("Failed to open 'lift.neo' file");
-
- _title = loadAndConvertNeoImage(&file, 0);
-
- file.close();
- file.open("console.neo");
- if (!file.isOpen())
- error("Failed to open 'console.neo' file");
-
- _border = loadAndConvertNeoImage(&file, 0);
-
- file.close();
- file.open("demo.cmd");
- if (!file.isOpen())
- error("Failed to open 'demo.cmd' file");
-
- loadDemoData(&file, 0, 0x1000);
-
- file.close();
- file.open("data");
- if (!file.isOpen())
- error("Failed to open 'data' file");
-
- load8bitBinary(&file, 0x442, 16);
- loadPalettes(&file, 0x0);
-
- file.close();
- file.open("driller");
- if (!file.isOpen())
- error("Failed to open 'driller' file");
-
- loadFonts(&file, 0xa30);
- loadMessagesFixedSize(&file, 0x3960, 14, 20);
- loadGlobalObjects(&file, 0x3716);
-
- file.close();
- file.open("soundfx");
- if (!file.isOpen())
- error("Failed to open 'soundfx' executable for Amiga");
-
- loadSoundsFx(&file, 0, 25);
+ loadAssetsAmigaDemo();
} else if (isAtariST()) {
file.open("lift.neo");
if (!file.isOpen())
@@ -368,24 +325,7 @@ void DrillerEngine::loadAssetsDemo() {
loadSoundsFx(&file, 0, 25);
} else if (isDOS()) {
- _renderMode = Common::kRenderCGA; // DOS demos is CGA only
- _viewArea = Common::Rect(36, 16, 284, 117); // correct view area
- _gfx->_renderMode = _renderMode;
- loadBundledImages();
- file.open("d2");
- if (!file.isOpen())
- error("Failed to open 'd2' file");
-
- loadFonts(&file, 0x4eb0);
- loadMessagesFixedSize(&file, 0x636, 14, 20);
- load8bitBinary(&file, 0x55b0, 4);
- loadGlobalObjects(&file, 0x8c);
-
- // Fixed for a corrupted area names in the demo data
- _areaMap[2]->_name = "LAPIS LAZULI";
- _areaMap[3]->_name = "EMERALD";
- _areaMap[8]->_name = "TOPAZ";
- file.close();
+ loadAssetsDOSDemo();
} else
error("Unsupported demo for Driller");
@@ -393,67 +333,10 @@ void DrillerEngine::loadAssetsDemo() {
_angleRotationIndex = 0;
}
-extern byte *parseEDSK(const Common::String filename, int &size);
-extern void deobfuscateDrillerCPCVirtualWorlds(byte *memBuffer);
-
void DrillerEngine::loadAssetsFullGame() {
Common::File file;
if (isAmiga()) {
- if (_variant & GF_AMIGA_RETAIL) {
- file.open("driller");
-
- if (!file.isOpen())
- error("Failed to open 'driller' executable for Amiga");
-
- _border = loadAndConvertNeoImage(&file, 0x137f4);
- byte *palette = (byte *)malloc(16 * 3);
- for (int i = 0; i < 16; i++) { // gray scale palette
- palette[i * 3 + 0] = i * (255 / 16);
- palette[i * 3 + 1] = i * (255 / 16);
- palette[i * 3 + 2] = i * (255 / 16);
- }
- _title = loadAndConvertNeoImage(&file, 0x10, palette);
-
- loadFonts(&file, 0x8940);
- loadMessagesFixedSize(&file, 0xc66e, 14, 20);
- loadGlobalObjects(&file, 0xbd62);
- load8bitBinary(&file, 0x29c16, 16);
- loadPalettes(&file, 0x297d4);
- loadSoundsFx(&file, 0x30e80, 25);
- } else if (_variant & GF_AMIGA_BUDGET) {
- file.open("lift.neo");
- if (!file.isOpen())
- error("Failed to open 'lift.neo' file");
-
- _title = loadAndConvertNeoImage(&file, 0);
-
- file.close();
- file.open("console.neo");
- if (!file.isOpen())
- error("Failed to open 'console.neo' file");
-
- _border = loadAndConvertNeoImage(&file, 0);
-
- file.close();
- file.open("driller");
- if (!file.isOpen())
- error("Failed to open 'driller' executable for Amiga");
-
- loadFonts(&file, 0xa62);
- loadMessagesFixedSize(&file, 0x499a, 14, 20);
- loadGlobalObjects(&file, 0x4098);
- load8bitBinary(&file, 0x21a3e, 16);
- loadPalettes(&file, 0x215fc);
-
- file.close();
- file.open("soundfx");
- if (!file.isOpen())
- error("Failed to open 'soundfx' executable for Amiga");
-
- loadSoundsFx(&file, 0, 25);
- }
- else
- error("Invalid or unknown Amiga release");
+ loadAssetsAmigaFullGame();
} else if (isAtariST()) {
file.open("x.prg");
@@ -476,83 +359,9 @@ void DrillerEngine::loadAssetsFullGame() {
loadPalettes(&file, 0x296fa);
loadSoundsFx(&file, 0x30da6, 25);
} else if (isSpectrum()) {
- file.open("driller.zx.title");
- if (file.isOpen()) {
- _title = loadAndCenterScrImage(&file);
- } else
- error("Unable to find driller.zx.title");
-
- file.close();
-
- file.open("driller.zx.border");
- if (file.isOpen()) {
- _border = loadAndCenterScrImage(&file);
- } else
- error("Unable to find driller.zx.border");
- file.close();
-
- file.open("driller.zx.data");
-
- if (!file.isOpen())
- error("Failed to open driller.zx.data");
-
- if (_variant & GF_ZX_DISC)
- loadMessagesFixedSize(&file, 0x2164, 14, 20);
- else
- loadMessagesFixedSize(&file, 0x20e4, 14, 20);
-
- if (_variant & GF_ZX_RETAIL)
- loadFonts(&file, 0x62ca);
- else if (_variant & GF_ZX_BUDGET)
- loadFonts(&file, 0x5aa8);
- else if (_variant & GF_ZX_DISC)
- loadFonts(&file, 0x63f0);
-
- if (_variant & GF_ZX_DISC)
- loadGlobalObjects(&file, 0x1d13);
- else
- loadGlobalObjects(&file, 0x1c93);
-
- if (_variant & GF_ZX_RETAIL)
- load8bitBinary(&file, 0x642c, 4);
- else if (_variant & GF_ZX_BUDGET)
- load8bitBinary(&file, 0x5c0a, 4);
- else if (_variant & GF_ZX_DISC)
- load8bitBinary(&file, 0x6552, 4);
-
- else
- error("Unknown ZX spectrum variant");
+ loadAssetsZXFullGame();
} else if (isCPC()) {
- loadBundledImages();
- byte *memBuffer;
- int memSize = 0;
- if (_variant & GF_CPC_VIRTUALWORLDS) {
- memBuffer = parseEDSK("virtualworlds.A.cpc.edsk", memSize);
- deobfuscateDrillerCPCVirtualWorlds(memBuffer);
- } else
- memBuffer = parseEDSK("driller.cpc.edsk", memSize);
- assert(memSize > 0);
- Common::SeekableReadStream *stream = new Common::MemoryReadStream((const byte*)memBuffer, memSize);
-
- if (_variant & GF_CPC_RETAIL) {
- loadMessagesFixedSize(stream, 0xb0f7, 14, 20);
- loadFonts(stream, 0xeb14);
- load8bitBinary(stream, 0xec76, 4);
- loadGlobalObjects(stream, 0xacb2);
- } else if (_variant & GF_CPC_RETAIL2) {
- loadMessagesFixedSize(stream, 0xb0f7 - 0x3fab, 14, 20);
- loadFonts(stream, 0xeb14 - 0x3fab);
- load8bitBinary(stream, 0xaccb, 4);
- loadGlobalObjects(stream, 0xacb2 - 0x3fab);
- } else if (_variant & _variant & GF_CPC_VIRTUALWORLDS) {
- load8bitBinary(stream, 0x11acb, 4);
- } else if (_variant & GF_CPC_BUDGET) {
- loadMessagesFixedSize(stream, 0x9ef7, 14, 20);
- loadFonts(stream, 0xd914);
- load8bitBinary(stream, 0xda76, 4);
- loadGlobalObjects(stream, 0x9ab2);
- } else
- error("Unknown Amstrad CPC variant");
+ loadAssetsCPCFullGame();
} else if (isC64()) {
if (_targetName.hasPrefix("spacestationoblivion")) {
loadBundledImages();
@@ -568,49 +377,8 @@ void DrillerEngine::loadAssetsFullGame() {
load8bitBinary(&file, 0x8e02 - 0x400, 4);
loadGlobalObjects(&file, 0x1855 - 0x400);
}
- } else if (_renderMode == Common::kRenderEGA) {
- file.open("SCN1E.DAT");
- if (file.isOpen()) {
- _title = load8bitBinImage(&file, 0x0);
- }
- file.close();
- file.open("EGATITLE.RL");
- if (file.isOpen()) {
- _title = load8bitTitleImage(&file, 0x1b3);
- }
- file.close();
-
- file.open("DRILLE.EXE");
-
- if (!file.isOpen())
- error("Failed to open DRILLE.EXE");
-
- loadMessagesFixedSize(&file, 0x4135, 14, 20);
- loadFonts(&file, 0x99dd);
- loadGlobalObjects(&file, 0x3b42);
- load8bitBinary(&file, 0x9b40, 16);
- _border = load8bitBinImage(&file, 0x210);
- } else if (_renderMode == Common::kRenderCGA) {
- file.open("SCN1C.DAT");
- if (file.isOpen()) {
- _title = load8bitBinImage(&file, 0x0);
- }
- file.close();
- file.open("CGATITLE.RL");
- if (file.isOpen()) {
- _title = load8bitTitleImage(&file, 0x1b3);
- }
- file.close();
- file.open("DRILLC.EXE");
-
- if (!file.isOpen())
- error("Failed to open DRILLC.EXE");
-
- loadFonts(&file, 0x07a4a);
- loadMessagesFixedSize(&file, 0x2585, 14, 20);
- load8bitBinary(&file, 0x7bb0, 4);
- loadGlobalObjects(&file, 0x1fa2);
- _border = load8bitBinImage(&file, 0x210);
+ } else if (isDOS()) {
+ loadAssetsDOSFullGame();
} else
error("Invalid or unsupported render mode %s for Driller", Common::getRenderModeDescription(_renderMode));
diff --git a/engines/freescape/games/driller/zx.cpp b/engines/freescape/games/driller/zx.cpp
index 482bde642bc..a8f1a4658e3 100644
--- a/engines/freescape/games/driller/zx.cpp
+++ b/engines/freescape/games/driller/zx.cpp
@@ -18,12 +18,63 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+#include "common/file.h"
#include "freescape/freescape.h"
#include "freescape/language/8bitDetokeniser.h"
namespace Freescape {
+void DrillerEngine::loadAssetsZXFullGame() {
+ Common::File file;
+ file.open("driller.zx.title");
+ if (file.isOpen()) {
+ _title = loadAndCenterScrImage(&file);
+ } else
+ error("Unable to find driller.zx.title");
+
+ file.close();
+
+ file.open("driller.zx.border");
+ if (file.isOpen()) {
+ _border = loadAndCenterScrImage(&file);
+ } else
+ error("Unable to find driller.zx.border");
+ file.close();
+
+ file.open("driller.zx.data");
+
+ if (!file.isOpen())
+ error("Failed to open driller.zx.data");
+
+ if (_variant & GF_ZX_DISC)
+ loadMessagesFixedSize(&file, 0x2164, 14, 20);
+ else
+ loadMessagesFixedSize(&file, 0x20e4, 14, 20);
+
+ if (_variant & GF_ZX_RETAIL)
+ loadFonts(&file, 0x62ca);
+ else if (_variant & GF_ZX_BUDGET)
+ loadFonts(&file, 0x5aa8);
+ else if (_variant & GF_ZX_DISC)
+ loadFonts(&file, 0x63f0);
+
+ if (_variant & GF_ZX_DISC)
+ loadGlobalObjects(&file, 0x1d13);
+ else
+ loadGlobalObjects(&file, 0x1c93);
+
+ if (_variant & GF_ZX_RETAIL)
+ load8bitBinary(&file, 0x642c, 4);
+ else if (_variant & GF_ZX_BUDGET)
+ load8bitBinary(&file, 0x5c0a, 4);
+ else if (_variant & GF_ZX_DISC)
+ load8bitBinary(&file, 0x6552, 4);
+
+ else
+ error("Unknown ZX spectrum variant");
+}
+
void DrillerEngine::drawZXUI(Graphics::Surface *surface) {
uint32 color = 5;
uint8 r, g, b;
Commit: edc1322b0b15e9160f24c02beaf832ca0d691969
https://github.com/scummvm/scummvm/commit/edc1322b0b15e9160f24c02beaf832ca0d691969
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:17:21+01:00
Commit Message:
FREESCAPE: refactored/moved driller code specific for the atari release
Changed paths:
A engines/freescape/games/driller/atari.cpp
engines/freescape/freescape.h
engines/freescape/games/driller/driller.cpp
engines/freescape/module.mk
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 8b05dd4291b..94521c68e43 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -439,6 +439,9 @@ private:
void loadAssetsDemo();
void loadAssetsFullGame();
+ void loadAssetsAtariFullGame();
+ void loadAssetsAtariDemo();
+
void loadAssetsAmigaFullGame();
void loadAssetsAmigaDemo();
diff --git a/engines/freescape/games/driller/atari.cpp b/engines/freescape/games/driller/atari.cpp
new file mode 100644
index 00000000000..6c2fe74a4ff
--- /dev/null
+++ b/engines/freescape/games/driller/atari.cpp
@@ -0,0 +1,100 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "common/file.h"
+
+#include "freescape/freescape.h"
+#include "freescape/language/8bitDetokeniser.h"
+
+namespace Freescape {
+
+void DrillerEngine::loadAssetsAtariFullGame() {
+ Common::File file;
+ file.open("x.prg");
+
+ if (!file.isOpen())
+ error("Failed to open 'x.prg' executable for AtariST");
+
+ _border = loadAndConvertNeoImage(&file, 0x1371a);
+ byte *palette = (byte *)malloc(16 * 3);
+ for (int i = 0; i < 16; i++) { // gray scale palette
+ palette[i * 3 + 0] = i * (255 / 16);
+ palette[i * 3 + 1] = i * (255 / 16);
+ palette[i * 3 + 2] = i * (255 / 16);
+ }
+ _title = loadAndConvertNeoImage(&file, 0x10, palette);
+
+ loadFonts(&file, 0x8a32);
+ loadMessagesFixedSize(&file, 0xc5d8, 14, 20);
+ loadGlobalObjects(&file, 0xbccc);
+ load8bitBinary(&file, 0x29b3c, 16);
+ loadPalettes(&file, 0x296fa);
+ loadSoundsFx(&file, 0x30da6, 25);
+}
+
+void DrillerEngine::loadAssetsAtariDemo() {
+ Common::File file;
+ file.open("lift.neo");
+ if (!file.isOpen())
+ error("Failed to open 'lift.neo' file");
+
+ _title = loadAndConvertNeoImage(&file, 0);
+
+ file.close();
+ file.open("console.neo");
+ if (!file.isOpen())
+ error("Failed to open 'console.neo' file");
+
+ _border = loadAndConvertNeoImage(&file, 0);
+
+ file.close();
+ file.open("demo.cmd");
+ if (!file.isOpen())
+ error("Failed to open 'demo.cmd' file");
+
+ loadDemoData(&file, 0, 0x1000);
+
+ file.close();
+ file.open("data");
+
+ if (!file.isOpen())
+ error("Failed to open 'data' file");
+
+ load8bitBinary(&file, 0x442, 16);
+ loadPalettes(&file, 0x0);
+
+ file.close();
+ file.open("x.prg");
+ if (!file.isOpen())
+ error("Failed to open 'x.prg' file");
+
+ loadFonts(&file, 0x7bc);
+ loadMessagesFixedSize(&file, 0x3b90, 14, 20);
+ loadGlobalObjects(&file, 0x3946);
+
+ file.close();
+ file.open("soundfx");
+ if (!file.isOpen())
+ error("Failed to open 'soundfx' executable for AtariST demo");
+
+ loadSoundsFx(&file, 0, 25);
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index f1ea313ea11..752eeed6d96 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -280,50 +280,7 @@ void DrillerEngine::loadAssetsDemo() {
if (isAmiga()) {
loadAssetsAmigaDemo();
} else if (isAtariST()) {
- file.open("lift.neo");
- if (!file.isOpen())
- error("Failed to open 'lift.neo' file");
-
- _title = loadAndConvertNeoImage(&file, 0);
-
- file.close();
- file.open("console.neo");
- if (!file.isOpen())
- error("Failed to open 'console.neo' file");
-
- _border = loadAndConvertNeoImage(&file, 0);
-
- file.close();
- file.open("demo.cmd");
- if (!file.isOpen())
- error("Failed to open 'demo.cmd' file");
-
- loadDemoData(&file, 0, 0x1000);
-
- file.close();
- file.open("data");
-
- if (!file.isOpen())
- error("Failed to open 'data' file");
-
- load8bitBinary(&file, 0x442, 16);
- loadPalettes(&file, 0x0);
-
- file.close();
- file.open("x.prg");
- if (!file.isOpen())
- error("Failed to open 'x.prg' file");
-
- loadFonts(&file, 0x7bc);
- loadMessagesFixedSize(&file, 0x3b90, 14, 20);
- loadGlobalObjects(&file, 0x3946);
-
- file.close();
- file.open("soundfx");
- if (!file.isOpen())
- error("Failed to open 'soundfx' executable for AtariST demo");
-
- loadSoundsFx(&file, 0, 25);
+ loadAssetsAtariDemo();
} else if (isDOS()) {
loadAssetsDOSDemo();
} else
@@ -338,26 +295,7 @@ void DrillerEngine::loadAssetsFullGame() {
if (isAmiga()) {
loadAssetsAmigaFullGame();
} else if (isAtariST()) {
- file.open("x.prg");
-
- if (!file.isOpen())
- error("Failed to open 'x.prg' executable for AtariST");
-
- _border = loadAndConvertNeoImage(&file, 0x1371a);
- byte *palette = (byte *)malloc(16 * 3);
- for (int i = 0; i < 16; i++) { // gray scale palette
- palette[i * 3 + 0] = i * (255 / 16);
- palette[i * 3 + 1] = i * (255 / 16);
- palette[i * 3 + 2] = i * (255 / 16);
- }
- _title = loadAndConvertNeoImage(&file, 0x10, palette);
-
- loadFonts(&file, 0x8a32);
- loadMessagesFixedSize(&file, 0xc5d8, 14, 20);
- loadGlobalObjects(&file, 0xbccc);
- load8bitBinary(&file, 0x29b3c, 16);
- loadPalettes(&file, 0x296fa);
- loadSoundsFx(&file, 0x30da6, 25);
+ loadAssetsAtariFullGame();
} else if (isSpectrum()) {
loadAssetsZXFullGame();
} else if (isCPC()) {
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index b3baab38526..0d3c8b7d085 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS := \
games/castle.o \
games/dark.o \
games/driller/amiga.o \
+ games/driller/atari.o \
games/driller/cpc.o \
games/driller/dos.o \
games/driller/driller.o \
Commit: c22636621e5f431afad4c057ef0381054271dde9
https://github.com/scummvm/scummvm/commit/c22636621e5f431afad4c057ef0381054271dde9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:17:31+01:00
Commit Message:
FREESCAPE: fixed artifacts when using stipple effect in opengl
Changed paths:
engines/freescape/gfx_opengl.cpp
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index db8c9ba1a8b..e504625b1c4 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -283,7 +283,7 @@ void OpenGLRenderer::setStippleData(byte *data) {
void OpenGLRenderer::useStipple(bool enabled) {
if (enabled) {
glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(-5.0f, 1.0f);
+ glPolygonOffset(0.0f, -1.0f);
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(_renderMode == Common::kRenderZX ? _variableStippleArray : _defaultStippleArray);
} else {
Commit: 366c5c6bbacf64d6d14fc7376ccf7ec57e547821
https://github.com/scummvm/scummvm/commit/366c5c6bbacf64d6d14fc7376ccf7ec57e547821
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:17:40+01:00
Commit Message:
FREESCAPE: fixed _lastMinute initialization for driller amiga/atari
Changed paths:
engines/freescape/games/driller/driller.cpp
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 752eeed6d96..97ce479a819 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -1002,8 +1002,11 @@ void DrillerEngine::initGameState() {
_playerHeightNumber = 1;
_playerHeight = _playerHeights[_playerHeightNumber];
removeTimers();
- startCountdown(_initialCountdown);
- _lastMinute = 0;
+ startCountdown(_initialCountdown - 1);
+
+ int seconds, minutes, hours;
+ getTimeFromCountdown(seconds, minutes, hours);
+ _lastMinute = minutes;
_demoIndex = 0;
_demoEvents.clear();
}
Commit: e539c321670e26e950a2e50daf9a180037875c7f
https://github.com/scummvm/scummvm/commit/e539c321670e26e950a2e50daf9a180037875c7f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:17:55+01:00
Commit Message:
FREESCAPE: simplified loading of data files in driller cpc
Changed paths:
engines/freescape/detection.cpp
engines/freescape/games/driller/cpc.cpp
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index f3faa281ae6..758267f1f88 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -75,7 +75,7 @@ static const ADGameDescription gameDescriptions[] = {
"driller",
"",
{
- {"DRILLER.CPC.EDSK", 0, "05df84207b5373e145ef90a3e4b98ae0", 215073},
+ {"DRILL.BIN", 0, "719f5157391e88b2c391c30576340637", 35320},
AD_LISTEND
},
Common::EN_ANY,
@@ -83,30 +83,6 @@ static const ADGameDescription gameDescriptions[] = {
GF_CPC_RETAIL,
GUIO2(GUIO_NOMIDI, GAMEOPTION_AUTOMATIC_DRILLING)
},
- {
- "driller",
- "",
- {
- {"DRILLER.CPC.EDSK", 0, "ccca1fb22252f43403f75a546ebb5a57", 194816},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformAmstradCPC,
- GF_CPC_RETAIL2,
- GUIO2(GUIO_NOMIDI, GAMEOPTION_AUTOMATIC_DRILLING)
- },
- {
- "driller",
- "",
- {
- {"DRILLER.CPC.EDSK", 0, "252f90756eaee25f2231e8d3bfaab68f", 125952},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformAmstradCPC,
- GF_CPC_BUDGET,
- GUIO2(GUIO_NOMIDI, GAMEOPTION_AUTOMATIC_DRILLING)
- },
{
"driller",
"VirtualWorlds-A",
diff --git a/engines/freescape/games/driller/cpc.cpp b/engines/freescape/games/driller/cpc.cpp
index 8bf22b5df99..c42df9fbd49 100644
--- a/engines/freescape/games/driller/cpc.cpp
+++ b/engines/freescape/games/driller/cpc.cpp
@@ -125,37 +125,16 @@ void deobfuscateDrillerCPCVirtualWorlds(byte *memBuffer) {
void DrillerEngine::loadAssetsCPCFullGame() {
Common::File file;
-
loadBundledImages();
- byte *memBuffer;
- int memSize = 0;
- if (_variant & GF_CPC_VIRTUALWORLDS) {
- memBuffer = parseEDSK("virtualworlds.A.cpc.edsk", memSize);
- deobfuscateDrillerCPCVirtualWorlds(memBuffer);
- } else
- memBuffer = parseEDSK("driller.cpc.edsk", memSize);
- assert(memSize > 0);
- Common::SeekableReadStream *stream = new Common::MemoryReadStream((const byte*)memBuffer, memSize);
-
- if (_variant & GF_CPC_RETAIL) {
- loadMessagesFixedSize(stream, 0xb0f7, 14, 20);
- loadFonts(stream, 0xeb14);
- load8bitBinary(stream, 0xec76, 4);
- loadGlobalObjects(stream, 0xacb2);
- } else if (_variant & GF_CPC_RETAIL2) {
- loadMessagesFixedSize(stream, 0xb0f7 - 0x3fab, 14, 20);
- loadFonts(stream, 0xeb14 - 0x3fab);
- load8bitBinary(stream, 0xaccb, 4);
- loadGlobalObjects(stream, 0xacb2 - 0x3fab);
- } else if (_variant & _variant & GF_CPC_VIRTUALWORLDS) {
- load8bitBinary(stream, 0x11acb, 4);
- } else if (_variant & GF_CPC_BUDGET) {
- loadMessagesFixedSize(stream, 0x9ef7, 14, 20);
- loadFonts(stream, 0xd914);
- load8bitBinary(stream, 0xda76, 4);
- loadGlobalObjects(stream, 0x9ab2);
- } else
- error("Unknown Amstrad CPC variant");
+ file.open("DRILL.BIN");
+
+ if (!file.isOpen())
+ error("Failed to open DRILL.BIN");
+
+ loadMessagesFixedSize(&file, 0x214c, 14, 20);
+ loadFonts(&file, 0x5b69);
+ loadGlobalObjects(&file, 0x1d07);
+ load8bitBinary(&file, 0x5ccb, 16);
}
void DrillerEngine::drawCPCUI(Graphics::Surface *surface) {
Commit: 8a0acc14409958c6010771d899fa22819fb92b09
https://github.com/scummvm/scummvm/commit/8a0acc14409958c6010771d899fa22819fb92b09
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T09:18:05+01:00
Commit Message:
FREESCAPE: enable some spfx effects for different platforms (zx, cpc)
Changed paths:
engines/freescape/language/instruction.cpp
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 3389ca99493..2f68554d9cb 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -249,7 +249,7 @@ void FreescapeEngine::executeSPFX(FCLInstruction &instruction) {
debugC(1, kFreescapeDebugCode, "Switching complete palette to color %d", dst);
for (int i = 1; i < 16; i++)
_currentArea->remapColor(i, color);
- } else if (isDOS()) {
+ } else {
debugC(1, kFreescapeDebugCode, "Switching palette from position %d to %d", src, dst);
if (src == 0 && dst == 1)
_currentArea->remapColor(_currentArea->_usualBackgroundColor, _renderMode == Common::kRenderCGA ? 1 : _currentArea->_underFireBackgroundColor);
Commit: 8227c50b44e154047109df299d46aa5e07967b16
https://github.com/scummvm/scummvm/commit/8227c50b44e154047109df299d46aa5e07967b16
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T10:05:59+01:00
Commit Message:
FREESCAPE: use managed surfaces for border and title images
Changed paths:
engines/freescape/freescape.cpp
engines/freescape/freescape.h
engines/freescape/games/driller/dos.cpp
engines/freescape/gfx.cpp
engines/freescape/gfx.h
engines/freescape/loaders/8bitBinaryLoader.cpp
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 2c5b96da6aa..975605018ae 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -194,7 +194,7 @@ void FreescapeEngine::drawBorder() {
void FreescapeEngine::drawTitle() {
_gfx->setViewport(_fullscreenViewArea);
if (isSpectrum()) {
- Graphics::Surface *title = new Graphics::Surface();
+ Graphics::ManagedSurface *title = new Graphics::ManagedSurface();
title->create(320, 200, _title->format);
title->copyRectToSurface(*_title, (320 - _title->w) / 2, (200 - _title->h) / 2, Common::Rect(_title->w, _title->h));
_title->free();
@@ -202,7 +202,7 @@ void FreescapeEngine::drawTitle() {
_title = title;
}
if (!_titleTexture)
- _titleTexture = _gfx->createTexture(_title);
+ _titleTexture = _gfx->createTexture(&_title->rawSurface());
_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _titleTexture);
_gfx->setViewport(_viewArea);
}
@@ -617,7 +617,7 @@ void FreescapeEngine::borderScreen() {}
void FreescapeEngine::loadBorder() {
if (_border)
- _borderTexture = _gfx->createTexture(_border);
+ _borderTexture = _gfx->createTexture(&_border->rawSurface());
}
void FreescapeEngine::processBorder() {
@@ -637,7 +637,7 @@ void FreescapeEngine::processBorder() {
_border->setPixel(i, j, transparent);
}
}
- _borderTexture = _gfx->createTexture(_border);
+ _borderTexture = _gfx->createTexture(&_border->rawSurface());
}
}
@@ -869,20 +869,20 @@ byte *FreescapeEngine::getPaletteFromNeoImage(Common::SeekableReadStream *stream
return palette;
}
-Graphics::Surface *FreescapeEngine::loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte *palette) {
+Graphics::ManagedSurface *FreescapeEngine::loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte *palette) {
stream->seek(offset);
NeoDecoder decoder(palette);
decoder.loadStream(*stream);
- Graphics::Surface *surface = new Graphics::Surface();
+ Graphics::ManagedSurface *surface = new Graphics::ManagedSurface();
surface->copyFrom(*decoder.getSurface());
surface->convertToInPlace(_gfx->_currentPixelFormat, decoder.getPalette());
return surface;
}
-Graphics::Surface *FreescapeEngine::loadAndCenterScrImage(Common::SeekableReadStream *stream) {
+Graphics::ManagedSurface *FreescapeEngine::loadAndCenterScrImage(Common::SeekableReadStream *stream) {
ScrDecoder decoder;
decoder.loadStream(*stream);
- Graphics::Surface *surface = new Graphics::Surface();
+ Graphics::ManagedSurface *surface = new Graphics::ManagedSurface();
const Graphics::Surface *decoded = decoder.getSurface();
surface->create(320, 200, decoded->format);
surface->copyRectToSurface(*decoded, (320 - decoded->w) / 2, (200 - decoded->h) / 2, Common::Rect(decoded->w, decoded->h));
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 94521c68e43..1b21c8edcc4 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -25,6 +25,7 @@
#include "common/bitarray.h"
#include "common/events.h"
#include "engines/advancedDetector.h"
+#include "graphics/managed_surface.h"
#include "graphics/surface.h"
#include "audio/decoders/wave.h"
@@ -124,8 +125,8 @@ public:
virtual void drawInfoMenu();
virtual void drawCrossair(Graphics::Surface *surface);
- Graphics::Surface *_border;
- Graphics::Surface *_title;
+ Graphics::ManagedSurface *_border;
+ Graphics::ManagedSurface *_title;
Texture *_borderTexture;
Texture *_titleTexture;
Texture *_uiTexture;
@@ -139,8 +140,8 @@ public:
void loadDataBundle();
void loadBundledImages();
byte *getPaletteFromNeoImage(Common::SeekableReadStream *stream, int offset);
- Graphics::Surface *loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte *palette = nullptr);
- Graphics::Surface *loadAndCenterScrImage(Common::SeekableReadStream *stream);
+ Graphics::ManagedSurface *loadAndConvertNeoImage(Common::SeekableReadStream *stream, int offset, byte *palette = nullptr);
+ Graphics::ManagedSurface *loadAndCenterScrImage(Common::SeekableReadStream *stream);
void loadPalettes(Common::SeekableReadStream *file, int offset);
void swapPalette(uint16 areaID);
Common::HashMap<uint16, byte *> _paletteByArea;
@@ -165,12 +166,12 @@ public:
void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors);
Object *load8bitObject(Common::SeekableReadStream *file);
- void renderPixels8bitBinImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color);
+ void renderPixels8bitBinImage(Graphics::ManagedSurface *surface, int &i, int &j, uint8 pixels, int color);
- void renderPixels8bitBinCGAImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color);
- void renderPixels8bitBinEGAImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color);
+ void renderPixels8bitBinCGAImage(Graphics::ManagedSurface *surface, int &i, int &j, uint8 pixels, int color);
+ void renderPixels8bitBinEGAImage(Graphics::ManagedSurface *surface, int &i, int &j, uint8 pixels, int color);
- Graphics::Surface *load8bitBinImage(Common::SeekableReadStream *file, int offset);
+ Graphics::ManagedSurface *load8bitBinImage(Common::SeekableReadStream *file, int offset);
// Areas
uint16 _startArea;
@@ -460,9 +461,9 @@ private:
void drawC64UI(Graphics::Surface *surface);
void drawAmigaAtariSTUI(Graphics::Surface *surface);
- Graphics::Surface *load8bitTitleImage(Common::SeekableReadStream *file, int offset);
+ Graphics::ManagedSurface *load8bitTitleImage(Common::SeekableReadStream *file, int offset);
uint32 getPixel8bitTitleImage(int index);
- void renderPixels8bitTitleImage(Graphics::Surface *surface, int &i, int &j, int pixels);
+ void renderPixels8bitTitleImage(Graphics::ManagedSurface *surface, int &i, int &j, int pixels);
};
class DarkEngine : public FreescapeEngine {
diff --git a/engines/freescape/games/driller/dos.cpp b/engines/freescape/games/driller/dos.cpp
index bb3f0b52d32..ee38b0a6b13 100644
--- a/engines/freescape/games/driller/dos.cpp
+++ b/engines/freescape/games/driller/dos.cpp
@@ -35,16 +35,13 @@ extern byte kEGADefaultPaletteData[16][3];
*/
uint32 DrillerEngine::getPixel8bitTitleImage(int index) {
- uint8 r, g, b;
if (index < 4 || _renderMode == Common::kRenderEGA) {
- _gfx->readFromPalette(index, r, g, b);
- return _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b);
+ return index;
}
- _gfx->readFromPalette(index / 4, r, g, b);
- return _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b);
+ return index / 4;
}
-void DrillerEngine::renderPixels8bitTitleImage(Graphics::Surface *surface, int &i, int &j, int pixels) {
+void DrillerEngine::renderPixels8bitTitleImage(Graphics::ManagedSurface *surface, int &i, int &j, int pixels) {
int c1 = pixels >> 4;
int c2 = pixels & 0xf;
@@ -80,17 +77,10 @@ void DrillerEngine::renderPixels8bitTitleImage(Graphics::Surface *surface, int &
i++;
}
-Graphics::Surface *DrillerEngine::load8bitTitleImage(Common::SeekableReadStream *file, int offset) {
- Graphics::Surface *surface = new Graphics::Surface();
- if (_renderMode == Common::kRenderCGA)
- _gfx->_palette = (byte *)kCGAPalettePinkBlueWhiteData;
- else if (_renderMode == Common::kRenderEGA)
- _gfx->_palette = (byte *)kEGADefaultPaletteData;
- else
- error("Invalid render mode: %d", _renderMode);
- surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
- uint32 black = _gfx->_currentPixelFormat.ARGBToColor(0xFF, 0, 0, 0);
- surface->fillRect(Common::Rect(0, 0, 320, 200), black);
+Graphics::ManagedSurface *DrillerEngine::load8bitTitleImage(Common::SeekableReadStream *file, int offset) {
+ Graphics::ManagedSurface *surface = new Graphics::ManagedSurface();
+ surface->create(_screenW, _screenH, Graphics::PixelFormat::createFormatCLUT8());
+ surface->fillRect(Common::Rect(0, 0, 320, 200), 0);
int i = 0;
int j = 0;
@@ -180,17 +170,45 @@ Graphics::Surface *DrillerEngine::load8bitTitleImage(Common::SeekableReadStream
}
return surface;
}
+
+byte kCGAPalettePinkBlueWhiteData[4][3] = {
+ {0x00, 0x00, 0x00},
+ {0x55, 0xff, 0xff},
+ {0xff, 0x55, 0xff},
+ {0xff, 0xff, 0xff},
+};
+
+byte kEGADefaultPaletteData[16][3] = {
+ {0x00, 0x00, 0x00},
+ {0x00, 0x00, 0xaa},
+ {0x00, 0xaa, 0x00},
+ {0xaa, 0x00, 0x00},
+ {0xaa, 0x00, 0xaa},
+ {0xaa, 0x55, 0x00},
+ {0x55, 0xff, 0x55},
+ {0xff, 0x55, 0x55},
+ {0x12, 0x34, 0x56},
+ {0xff, 0xff, 0x55},
+ {0xff, 0xff, 0xff},
+ {0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00}
+};
+
void DrillerEngine::loadAssetsDOSFullGame() {
Common::File file;
if (_renderMode == Common::kRenderEGA) {
file.open("SCN1E.DAT");
if (file.isOpen()) {
_title = load8bitBinImage(&file, 0x0);
+ _title->setPalette((byte*)&kEGADefaultPaletteData, 0, 16);
}
file.close();
file.open("EGATITLE.RL");
if (file.isOpen()) {
_title = load8bitTitleImage(&file, 0x1b3);
+ _title->setPalette((byte*)&kEGADefaultPaletteData, 0, 16);
}
file.close();
@@ -204,15 +222,18 @@ void DrillerEngine::loadAssetsDOSFullGame() {
loadGlobalObjects(&file, 0x3b42);
load8bitBinary(&file, 0x9b40, 16);
_border = load8bitBinImage(&file, 0x210);
+ _border->setPalette((byte*)&kEGADefaultPaletteData, 0, 16);
} else if (_renderMode == Common::kRenderCGA) {
file.open("SCN1C.DAT");
if (file.isOpen()) {
_title = load8bitBinImage(&file, 0x0);
+ _title->setPalette((byte*)&kCGAPalettePinkBlueWhiteData, 0, 4);
}
file.close();
file.open("CGATITLE.RL");
if (file.isOpen()) {
_title = load8bitTitleImage(&file, 0x1b3);
+ _title->setPalette((byte*)&kCGAPalettePinkBlueWhiteData, 0, 4);
}
file.close();
file.open("DRILLC.EXE");
@@ -225,6 +246,7 @@ void DrillerEngine::loadAssetsDOSFullGame() {
load8bitBinary(&file, 0x7bb0, 4);
loadGlobalObjects(&file, 0x1fa2);
_border = load8bitBinImage(&file, 0x210);
+ _border->setPalette((byte*)&kCGAPalettePinkBlueWhiteData, 0, 4);
} else
error("Unsupported video mode for DOS");
}
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 3fab0026779..ac35f24ee4f 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -76,7 +76,7 @@ bool Renderer::getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
return false;
assert (_renderMode == Common::kRenderCGA);
- if (index <= 4) { // Solid colors
+ if (index <= 4) { // Solid colors
readFromPalette(index - 1, r1, g1, b1);
r2 = r1;
g2 = g1;
@@ -164,7 +164,7 @@ bool Renderer::getRGBAtZX(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r
return false;
byte *entry = (*_colorMap)[index - 1];
- if (entry[0] == 0 && entry[1] == 0 && entry[2] == 0 && entry[3] == 0) {
+ if (entry[0] == 0 && entry[1] == 0 && entry[2] == 0 && entry[3] == 0) {
readFromPalette(_paperColor, r1, g1, b1);
readFromPalette(_paperColor, r2, g2, b2);
return true;
@@ -342,12 +342,23 @@ void Renderer::flipVertical(Graphics::Surface *s) {
}
}
-void Renderer::convertImageFormatIfNecessary(Graphics::Surface *surface) {
+void Renderer::convertImageFormatIfNecessary(Graphics::ManagedSurface *surface) {
if (!surface)
return;
- if (surface->format != _texturePixelFormat)
- surface->convertToInPlace(_texturePixelFormat);
+ if (surface->format != _texturePixelFormat) {
+ const uint32 *src = surface->getPalette();
+ byte *palette = (byte *)malloc(sizeof(byte) * 16 * 3);
+ for (int num = 16; num > 0; --num, palette += 3) { // Maximum should be 16 colours
+ uint32 p = *src++;
+ palette[0] = p & 0xff;
+ palette[1] = (p >> 8) & 0xff;
+ palette[2] = (p >> 16) & 0xff;
+ }
+ palette = palette - 16 * 3;
+ surface->convertToInPlace(_texturePixelFormat, palette);
+ free(palette);
+ }
}
Common::Rect Renderer::viewport() const {
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index a8b08b5cd66..074ce8be090 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -26,6 +26,7 @@
#include "common/rect.h"
#include "graphics/pixelformat.h"
+#include "graphics/managed_surface.h"
#include "graphics/renderer.h"
#include "math/frustum.h"
#include "math/vector3d.h"
@@ -76,7 +77,7 @@ public:
virtual void polygonOffset(bool enabled) = 0;
virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
- void convertImageFormatIfNecessary(Graphics::Surface *surface);
+ void convertImageFormatIfNecessary(Graphics::ManagedSurface *surface);
virtual void freeTexture(Texture *texture) = 0;
virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) = 0;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index b39cd64c2e3..b62a5e6d28f 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -298,32 +298,7 @@ static const char *eclipseRoomName[] = {
"ILLUSION",
"????????"};
-byte kCGAPalettePinkBlueWhiteData[4][3] = {
- {0x00, 0x00, 0x00},
- {0x55, 0xff, 0xff},
- {0xff, 0x55, 0xff},
- {0xff, 0xff, 0xff},
-};
-
-byte kEGADefaultPaletteData[16][3] = {
- {0x00, 0x00, 0x00},
- {0x00, 0x00, 0xaa},
- {0x00, 0xaa, 0x00},
- {0xaa, 0x00, 0x00},
- {0xaa, 0x00, 0xaa},
- {0xaa, 0x55, 0x00},
- {0x55, 0xff, 0x55},
- {0xff, 0x55, 0x55},
- {0x12, 0x34, 0x56},
- {0xff, 0xff, 0x55},
- {0xff, 0xff, 0xff},
- {0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00}
-};
-
-void FreescapeEngine::renderPixels8bitBinImage(Graphics::Surface *surface, int &i, int &j, uint8 pixels, int color) {
+void FreescapeEngine::renderPixels8bitBinImage(Graphics::ManagedSurface *surface, int &i, int &j, uint8 pixels, int color) {
if (i >= 320) {
//debug("cannot continue, stopping here at row %d!", j);
return;
@@ -333,13 +308,8 @@ void FreescapeEngine::renderPixels8bitBinImage(Graphics::Surface *surface, int &
while (acc > 0) {
assert(i < 320);
if (acc & pixels) {
- uint8 r, g, b;
- uint32 previousPixel = surface->getPixel(i, j);
- _gfx->_currentPixelFormat.colorToRGB(previousPixel, r, g, b);
- int previousColor = _gfx->indexFromColor(r, g, b);
- //debug("index: %d", previousColor + color);
- _gfx->readFromPalette(previousColor + color, r, g, b);
- surface->setPixel(i, j, _gfx->_currentPixelFormat.ARGBToColor(0xFF, r, g, b));
+ int previousColor = surface->getPixel(i, j);
+ surface->setPixel(i, j, previousColor + color);
}
i++;
acc = acc >> 1;
@@ -347,18 +317,10 @@ void FreescapeEngine::renderPixels8bitBinImage(Graphics::Surface *surface, int &
}
-Graphics::Surface *FreescapeEngine::load8bitBinImage(Common::SeekableReadStream *file, int offset) {
- Graphics::Surface *surface = new Graphics::Surface();
- if (_renderMode == Common::kRenderCGA)
- _gfx->_palette = (byte *)kCGAPalettePinkBlueWhiteData;
- else if (_renderMode == Common::kRenderEGA)
- _gfx->_palette = (byte *)kEGADefaultPaletteData;
- else
- error("Invalid render mode: %d", _renderMode);
-
- surface->create(_screenW, _screenH, _gfx->_currentPixelFormat);
- uint32 black = _gfx->_currentPixelFormat.ARGBToColor(0xFF, 0, 0, 0);
- surface->fillRect(Common::Rect(0, 0, 320, 200), black);
+Graphics::ManagedSurface *FreescapeEngine::load8bitBinImage(Common::SeekableReadStream *file, int offset) {
+ Graphics::ManagedSurface *surface = new Graphics::ManagedSurface();
+ surface->create(_screenW, _screenH, Graphics::PixelFormat::createFormatCLUT8());
+ surface->fillRect(Common::Rect(0, 0, 320, 200), 0);
file->seek(offset);
int imageSize = file->readUint16BE();
@@ -735,7 +697,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
}
void FreescapeEngine::loadBundledImages() {
- Image::BitmapDecoder decoder;
+ /*Image::BitmapDecoder decoder;
Common::String targetName = Common::String(_gameDescription->gameId);
if (isDOS() && isDemo())
Common::replace(targetName, "-demo", "");
@@ -757,7 +719,7 @@ void FreescapeEngine::loadBundledImages() {
_title = new Graphics::Surface();
_title->copyFrom(*decoder.getSurface());
decoder.destroy();
- }
+ }*/
}
void FreescapeEngine::loadFonts(Common::SeekableReadStream *file, int offset) {
Commit: 9b0f5b3de324fe5d2b9d1a259c6cb3d9854faf02
https://github.com/scummvm/scummvm/commit/9b0f5b3de324fe5d2b9d1a259c6cb3d9854faf02
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T10:10:56+01:00
Commit Message:
FREESCAPE: allow to change the palette of title and border per level using managed surfaces
Changed paths:
engines/freescape/freescape.cpp
engines/freescape/games/driller/driller.cpp
engines/freescape/games/palettes.cpp
engines/freescape/gfx.cpp
engines/freescape/gfx.h
engines/freescape/loaders/8bitBinaryLoader.cpp
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 975605018ae..52aa76309dd 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -193,16 +193,12 @@ void FreescapeEngine::drawBorder() {
void FreescapeEngine::drawTitle() {
_gfx->setViewport(_fullscreenViewArea);
- if (isSpectrum()) {
- Graphics::ManagedSurface *title = new Graphics::ManagedSurface();
- title->create(320, 200, _title->format);
- title->copyRectToSurface(*_title, (320 - _title->w) / 2, (200 - _title->h) / 2, Common::Rect(_title->w, _title->h));
- _title->free();
- delete _title;
- _title = title;
+ if (!_titleTexture) {
+ Graphics::Surface *title = _gfx->convertImageFormatIfNecessary(_title);
+ _titleTexture = _gfx->createTexture(title);
+ title->free();
+ delete title;
}
- if (!_titleTexture)
- _titleTexture = _gfx->createTexture(&_title->rawSurface());
_gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _titleTexture);
_gfx->setViewport(_viewArea);
}
@@ -559,8 +555,6 @@ Common::Error FreescapeEngine::run() {
initGameState();
loadColorPalette();
- _gfx->convertImageFormatIfNecessary(_title);
- _gfx->convertImageFormatIfNecessary(_border);
g_system->lockMouse(true);
// Simple main event loop
@@ -616,28 +610,37 @@ void FreescapeEngine::titleScreen() {}
void FreescapeEngine::borderScreen() {}
void FreescapeEngine::loadBorder() {
- if (_border)
- _borderTexture = _gfx->createTexture(&_border->rawSurface());
+ if (_border) {
+ Graphics::Surface *border = _gfx->convertImageFormatIfNecessary(_border);
+ _borderTexture = _gfx->createTexture(border);
+ border->free();
+ delete border;
+ }
}
void FreescapeEngine::processBorder() {
if (_border) {
if (_borderTexture)
delete _borderTexture;
+ Graphics::Surface *border = _gfx->convertImageFormatIfNecessary(_border);
+
uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
- _border->fillRect(_viewArea, gray);
+ border->fillRect(_viewArea, gray);
// Replace black pixel for transparent ones
- uint32 black = _border->format.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
- uint32 transparent = _border->format.ARGBToColor(0x00, 0x00, 0x00, 0x00);
+ uint32 black = border->format.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
+ uint32 transparent = border->format.ARGBToColor(0x00, 0x00, 0x00, 0x00);
- for (int i = 0; i < _border->w; i++) {
- for (int j = 0; j < _border->h; j++) {
- if (_border->getPixel(i, j) == black)
- _border->setPixel(i, j, transparent);
+ for (int i = 0; i < border->w; i++) {
+ for (int j = 0; j < border->h; j++) {
+ if (border->getPixel(i, j) == black)
+ border->setPixel(i, j, transparent);
}
}
- _borderTexture = _gfx->createTexture(&_border->rawSurface());
+
+ _borderTexture = _gfx->createTexture(border);
+ border->free();
+ delete border;
}
}
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 97ce479a819..c1e33edd9e2 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -29,59 +29,6 @@
namespace Freescape {
-enum {
- kDrillerCGAPalettePinkBlue = 0,
- kDrillerCGAPaletteRedGreen = 1,
-};
-
-static const struct CGAPalettteEntry {
- int areaId;
- int palette;
-} rawCGAPaletteTable[] {
- {1, kDrillerCGAPaletteRedGreen},
- {2, kDrillerCGAPalettePinkBlue},
- {3, kDrillerCGAPaletteRedGreen},
- {4, kDrillerCGAPalettePinkBlue},
- {5, kDrillerCGAPaletteRedGreen},
- {6, kDrillerCGAPalettePinkBlue},
- {7, kDrillerCGAPaletteRedGreen},
- {8, kDrillerCGAPalettePinkBlue},
- {9, kDrillerCGAPaletteRedGreen},
- {10, kDrillerCGAPalettePinkBlue},
- {11, kDrillerCGAPaletteRedGreen},
- {12, kDrillerCGAPalettePinkBlue},
-
- {14, kDrillerCGAPalettePinkBlue},
-
- {16, kDrillerCGAPalettePinkBlue},
-
- {19, kDrillerCGAPaletteRedGreen},
- {20, kDrillerCGAPalettePinkBlue},
- {21, kDrillerCGAPaletteRedGreen},
- {22, kDrillerCGAPalettePinkBlue},
- {23, kDrillerCGAPaletteRedGreen},
-
- {28, kDrillerCGAPalettePinkBlue},
-
- {32, kDrillerCGAPalettePinkBlue},
- {127, kDrillerCGAPaletteRedGreen},
- {0, 0} // This marks the end
-};
-
-byte kDrillerCGAPalettePinkBlueData[4][3] = {
- {0x00, 0x00, 0x00},
- {0x00, 0xaa, 0xaa},
- {0xaa, 0x00, 0xaa},
- {0xaa, 0xaa, 0xaa},
-};
-
-byte kDrillerCGAPaletteRedGreenData[4][3] = {
- {0x00, 0x00, 0x00},
- {0x00, 0xaa, 0x00},
- {0xaa, 0x00, 0x00},
- {0xaa, 0x55, 0x00},
-};
-
enum {
kDrillerNoRig = 0,
kDrillerRigInPlace = 1,
@@ -147,7 +94,7 @@ void DrillerEngine::titleScreen() {
if (isDOS() && isDemo()) // Demo will not show any title screen
return;
- if (isAmiga() || isAtariST()) // These releases has their own screens
+ if (isAmiga() || isAtariST()) // TODO: implement these with their own animations
return;
if (_title) {
@@ -161,7 +108,7 @@ void DrillerEngine::borderScreen() {
if (isDOS() && isDemo()) // Demo will not show the border
return;
- if (isAmiga() || isAtariST()) // These releases has their own screens
+ if (isAmiga() || isAtariST()) // TODO: implement these with their own animations
return;
if (_border) {
@@ -346,47 +293,6 @@ void DrillerEngine::loadAssetsFullGame() {
void DrillerEngine::processBorder() {
FreescapeEngine::processBorder();
- if (isDOS() && _renderMode == Common::kRenderCGA) { // Replace some colors for the CGA borders
- uint32 color1 = _border->format.ARGBToColor(0xFF, 0xAA, 0x00, 0xAA);
- uint32 color2 = _border->format.ARGBToColor(0xFF, 0xAA, 0x55, 0x00);
-
- uint32 colorA = _border->format.ARGBToColor(0xFF, 0x00, 0xAA, 0xAA);
- uint32 colorB = _border->format.ARGBToColor(0xFF, 0x00, 0xAA, 0x00);
-
- uint32 colorX = _border->format.ARGBToColor(0xFF, 0xAA, 0xAA, 0xAA);
- uint32 colorY = _border->format.ARGBToColor(0xFF, 0xAA, 0x00, 0x00);
-
- Graphics::Surface *borderRedGreen = new Graphics::Surface();
- borderRedGreen->create(1, 1, _border->format);
- borderRedGreen->copyFrom(*_border);
-
- for (int i = 0; i < _border->w; i++) {
- for (int j = 0; j < _border->h; j++) {
- if (borderRedGreen->getPixel(i, j) == color1)
- borderRedGreen->setPixel(i, j, color2);
- else if (borderRedGreen->getPixel(i, j) == colorA)
- borderRedGreen->setPixel(i, j, colorB);
- else if (borderRedGreen->getPixel(i, j) == colorX)
- borderRedGreen->setPixel(i, j, colorY);
-
- }
- }
- Texture *borderTextureRedGreen = _gfx->createTexture(borderRedGreen);
-
- const CGAPalettteEntry *entry = rawCGAPaletteTable;
- while (entry->areaId) {
-
- if (entry->palette == kDrillerCGAPaletteRedGreen) {
- _borderCGAByArea[entry->areaId] = borderTextureRedGreen;
- _paletteCGAByArea[entry->areaId] = (byte *)kDrillerCGAPaletteRedGreenData;
- } else if (entry->palette == kDrillerCGAPalettePinkBlue) {
- _borderCGAByArea[entry->areaId] = _borderTexture;
- _paletteCGAByArea[entry->areaId] = (byte *)kDrillerCGAPalettePinkBlueData;
- } else
- error("Invalid CGA palette to use");
- entry++;
- }
- }
}
void DrillerEngine::drawUI() {
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 1f4c8766fe6..97d4cfbf94c 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -155,6 +155,59 @@ void FreescapeEngine::loadPalettes(Common::SeekableReadStream *file, int offset)
}
}
+enum {
+ kDrillerCGAPalettePinkBlue = 0,
+ kDrillerCGAPaletteRedGreen = 1,
+};
+
+static const struct CGAPalettteEntry {
+ int areaId;
+ int palette;
+} rawCGAPaletteTable[] {
+ {1, kDrillerCGAPaletteRedGreen},
+ {2, kDrillerCGAPalettePinkBlue},
+ {3, kDrillerCGAPaletteRedGreen},
+ {4, kDrillerCGAPalettePinkBlue},
+ {5, kDrillerCGAPaletteRedGreen},
+ {6, kDrillerCGAPalettePinkBlue},
+ {7, kDrillerCGAPaletteRedGreen},
+ {8, kDrillerCGAPalettePinkBlue},
+ {9, kDrillerCGAPaletteRedGreen},
+ {10, kDrillerCGAPalettePinkBlue},
+ {11, kDrillerCGAPaletteRedGreen},
+ {12, kDrillerCGAPalettePinkBlue},
+
+ {14, kDrillerCGAPalettePinkBlue},
+
+ {16, kDrillerCGAPalettePinkBlue},
+
+ {19, kDrillerCGAPaletteRedGreen},
+ {20, kDrillerCGAPalettePinkBlue},
+ {21, kDrillerCGAPaletteRedGreen},
+ {22, kDrillerCGAPalettePinkBlue},
+ {23, kDrillerCGAPaletteRedGreen},
+
+ {28, kDrillerCGAPalettePinkBlue},
+
+ {32, kDrillerCGAPalettePinkBlue},
+ {127, kDrillerCGAPaletteRedGreen},
+ {0, 0} // This marks the end
+};
+
+byte kDrillerCGAPalettePinkBlueData[4][3] = {
+ {0x00, 0x00, 0x00},
+ {0x00, 0xaa, 0xaa},
+ {0xaa, 0x00, 0xaa},
+ {0xaa, 0xaa, 0xaa},
+};
+
+byte kDrillerCGAPaletteRedGreenData[4][3] = {
+ {0x00, 0x00, 0x00},
+ {0x00, 0xaa, 0x00},
+ {0xaa, 0x00, 0x00},
+ {0xaa, 0x55, 0x00},
+};
+
void FreescapeEngine::swapPalette(uint16 levelID) {
if (isAmiga() || isAtariST())
_gfx->_palette = _paletteByArea[levelID];
@@ -163,11 +216,28 @@ void FreescapeEngine::swapPalette(uint16 levelID) {
_gfx->_paperColor = _areaMap[levelID]->_paperColor;
_gfx->_underFireBackgroundColor = _areaMap[levelID]->_underFireBackgroundColor;
} else if (isDOS() && _renderMode == Common::kRenderCGA) {
- assert(_borderCGAByArea.contains(levelID));
- assert(_paletteCGAByArea.contains(levelID));
- _borderTexture = _borderCGAByArea.getVal(levelID);
- _gfx->_palette = _paletteCGAByArea.getVal(levelID);
+ const CGAPalettteEntry *entry = rawCGAPaletteTable;
+ while (entry->areaId) {
+ if (entry->areaId == levelID) {
+ if (entry->palette == kDrillerCGAPaletteRedGreen) {
+ _gfx->_palette = (byte *)kDrillerCGAPaletteRedGreenData;
+ } else if (entry->palette == kDrillerCGAPalettePinkBlue) {
+ _gfx->_palette = (byte *)kDrillerCGAPalettePinkBlueData;
+ } else
+ error("Invalid CGA palette to use");
+ break;
+ }
+ entry++;
+ }
+
+ assert(entry->areaId == levelID);
+ _border->setPalette(_gfx->_palette, 0, 4);
+ processBorder();
+ } else if (isDOS() && _renderMode == Common::kRenderEGA) {
+ _border->setPalette(_gfx->_palette, 0, 4);
+ processBorder();
}
+
}
} // End of namespace Freescape
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index ac35f24ee4f..d93e937dab8 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -342,23 +342,25 @@ void Renderer::flipVertical(Graphics::Surface *s) {
}
}
-void Renderer::convertImageFormatIfNecessary(Graphics::ManagedSurface *surface) {
- if (!surface)
- return;
-
- if (surface->format != _texturePixelFormat) {
- const uint32 *src = surface->getPalette();
- byte *palette = (byte *)malloc(sizeof(byte) * 16 * 3);
- for (int num = 16; num > 0; --num, palette += 3) { // Maximum should be 16 colours
- uint32 p = *src++;
- palette[0] = p & 0xff;
- palette[1] = (p >> 8) & 0xff;
- palette[2] = (p >> 16) & 0xff;
- }
- palette = palette - 16 * 3;
- surface->convertToInPlace(_texturePixelFormat, palette);
- free(palette);
- }
+Graphics::Surface *Renderer::convertImageFormatIfNecessary(Graphics::ManagedSurface *msurface) {
+ if (!msurface)
+ return nullptr;
+
+ assert(msurface->format != _texturePixelFormat);
+ Graphics::Surface *surface = new Graphics::Surface();
+ surface->copyFrom(msurface->rawSurface());
+ const uint32 *src = msurface->getPalette();
+ byte *palette = (byte *)malloc(sizeof(byte) * 16 * 3);
+ for (int num = 16; num > 0; --num, palette += 3) { // Maximum should be 16 colours
+ uint32 p = *src++;
+ palette[0] = p & 0xff;
+ palette[1] = (p >> 8) & 0xff;
+ palette[2] = (p >> 16) & 0xff;
+ }
+ palette = palette - 16 * 3;
+ surface->convertToInPlace(_texturePixelFormat, palette);
+ free(palette);
+ return surface;
}
Common::Rect Renderer::viewport() const {
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 074ce8be090..867da87b0f0 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -77,7 +77,7 @@ public:
virtual void polygonOffset(bool enabled) = 0;
virtual Texture *createTexture(const Graphics::Surface *surface) = 0;
- void convertImageFormatIfNecessary(Graphics::ManagedSurface *surface);
+ Graphics::Surface *convertImageFormatIfNecessary(Graphics::ManagedSurface *surface);
virtual void freeTexture(Texture *texture) = 0;
virtual void drawTexturedRect2D(const Common::Rect &screenRect, const Common::Rect &textureRect, Texture *texture) = 0;
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index b62a5e6d28f..d9e1157be65 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -310,6 +310,7 @@ void FreescapeEngine::renderPixels8bitBinImage(Graphics::ManagedSurface *surface
if (acc & pixels) {
int previousColor = surface->getPixel(i, j);
surface->setPixel(i, j, previousColor + color);
+ assert(previousColor + color < 16);
}
i++;
acc = acc >> 1;
Commit: d909a548e4f4ba32ece7bdf92209485ed0c26ce9
https://github.com/scummvm/scummvm/commit/d909a548e4f4ba32ece7bdf92209485ed0c26ce9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T10:11:54+01:00
Commit Message:
FREESCAPE: load original images and adjust ui for driller cpc
Changed paths:
engines/freescape/games/driller/cpc.cpp
diff --git a/engines/freescape/games/driller/cpc.cpp b/engines/freescape/games/driller/cpc.cpp
index c42df9fbd49..25750cfb6b1 100644
--- a/engines/freescape/games/driller/cpc.cpp
+++ b/engines/freescape/games/driller/cpc.cpp
@@ -123,9 +123,75 @@ void deobfuscateDrillerCPCVirtualWorlds(byte *memBuffer) {
}
}
+byte kCPCPalettePinkBlueWhiteData[4][3] = {
+ {0x00, 0x00, 0x00},
+ {0x55, 0xff, 0xff},
+ {0xff, 0x55, 0xff},
+ {0xff, 0xff, 0xff},
+};
+
+Graphics::ManagedSurface *readCPCImage(Common::SeekableReadStream *file) {
+ Graphics::ManagedSurface *surface = new Graphics::ManagedSurface();
+ surface->create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
+ surface->fillRect(Common::Rect(0, 0, 320, 200), 0);
+
+ int x, y;
+ file->seek(0x80);
+ for (int block = 0; block < 8; block++) {
+ for (int line = 0; line < 25; line++) {
+ for (int offset = 0; offset < 320 / 4; offset++) {
+ byte cpc_byte = file->readByte(); // Get CPC byte
+
+ // Process first pixel
+ int pixel_0 = ((cpc_byte & 0x08) >> 2) | ((cpc_byte & 0x80) >> 7); // %Aa
+ y = line * 8 + block ; // Coord Y for the pixel
+ x = 4 * offset + 0; // Coord X for the pixel
+ surface->setPixel(x, y, pixel_0);
+
+ // Process second pixel
+ int pixel_1 = ((cpc_byte & 0x04) >> 1) | ((cpc_byte & 0x40) >> 6); // %Bb
+ y = line * 8 + block ; // Coord Y for the pixel
+ x = 4 * offset + 1; // Coord X for the pixel
+ surface->setPixel(x, y, pixel_1);
+
+ // Process third pixel
+ int pixel_2 = (cpc_byte & 0x02) | ((cpc_byte & 0x20) >> 5); // %Cc
+ y = line * 8 + block ; // Coord Y for the pixel
+ x = 4 * offset + 2; // Coord X for the pixel
+ surface->setPixel(x, y, pixel_2);
+
+ // Process fourth pixel
+ int pixel_3 = ((cpc_byte & 0x01) << 1) | ((cpc_byte & 0x10) >> 4); // %Dd
+ y = line * 8 + block ; // Coord Y for the pixel
+ x = 4 * offset + 3; // Coord X for the pixel
+ surface->setPixel(x, y, pixel_3);
+ }
+ }
+ // We should skip the next 48 bytes, because they are padding the block to be 2048 bytes
+ file->seek(48, SEEK_CUR);
+ }
+ return surface;
+}
+
void DrillerEngine::loadAssetsCPCFullGame() {
Common::File file;
- loadBundledImages();
+
+ file.open("DSCN1.BIN");
+ if (!file.isOpen())
+ error("Failed to open DSCN1.BIN");
+
+ _title = readCPCImage(&file);
+ _title->setPalette((byte*)&kCPCPalettePinkBlueWhiteData, 0, 4);
+
+ file.close();
+ file.open("DSCN2.BIN");
+ if (!file.isOpen())
+ error("Failed to open DSCN2.BIN");
+
+ _border = readCPCImage(&file);
+ _border->setPalette((byte*)&kCPCPalettePinkBlueWhiteData, 0, 4);
+
+ file.close();
file.open("DRILL.BIN");
if (!file.isOpen())
@@ -153,30 +219,30 @@ void DrillerEngine::drawCPCUI(Graphics::Surface *surface) {
uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
int score = _gameStateVars[k8bitVariableScore];
- drawStringInSurface(_currentArea->_name, 200, 188, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 149, 148, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 149, 156, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 149, 164, front, back, surface);
+ drawStringInSurface(_currentArea->_name, 200, 185, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 149, 145, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 149, 153, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 149, 161, front, back, surface);
if (_playerHeightNumber >= 0)
- drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 54, 164, front, back, surface);
+ drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 54, 161, front, back, surface);
else
- drawStringInSurface(Common::String::format("%s", "J"), 54, 164, front, back, surface);
+ drawStringInSurface(Common::String::format("%s", "J"), 54, 161, front, back, surface);
- drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 46, 148, front, back, surface);
- drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 44, 156, front, back, surface);
- drawStringInSurface(Common::String::format("%07d", score), 239, 132, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 46, 145, front, back, surface);
+ drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 44, 153, front, back, surface);
+ drawStringInSurface(Common::String::format("%07d", score), 239, 129, front, back, surface);
int seconds, minutes, hours;
getTimeFromCountdown(seconds, minutes, hours);
- drawStringInSurface(Common::String::format("%02d", hours), 209, 11, front, back, surface);
- drawStringInSurface(Common::String::format("%02d", minutes), 232, 11, front, back, surface);
- drawStringInSurface(Common::String::format("%02d", seconds), 254, 11, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", hours), 209, 8, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", minutes), 232, 8, front, back, surface);
+ drawStringInSurface(Common::String::format("%02d", seconds), 254, 8, front, back, surface);
Common::String message;
int deadline;
getLatestMessages(message, deadline);
if (deadline <= _countdown) {
- drawStringInSurface(message, 191, 180, back, front, surface);
+ drawStringInSurface(message, 191, 177, back, front, surface);
_temporaryMessages.push_back(message);
_temporaryMessageDeadlines.push_back(deadline);
} else if (_messagesList.size() > 0) {
@@ -187,24 +253,24 @@ void DrillerEngine::drawCPCUI(Graphics::Surface *surface) {
else
message = _messagesList[1];
- drawStringInSurface(message, 191, 180, front, back, surface);
+ drawStringInSurface(message, 191, 177, front, back, surface);
}
int energy = _gameStateVars[k8bitVariableEnergy];
int shield = _gameStateVars[k8bitVariableShield];
if (energy >= 0) {
- Common::Rect backBar(25, 187, 89 - energy, 194);
+ Common::Rect backBar(25, 184, 89 - energy, 191);
surface->fillRect(backBar, back);
- Common::Rect energyBar(88 - energy, 187, 88, 194);
+ Common::Rect energyBar(88 - energy, 184, 88, 191);
surface->fillRect(energyBar, front);
}
if (shield >= 0) {
- Common::Rect backBar(25, 180, 89 - shield, 186);
+ Common::Rect backBar(25, 177, 89 - shield, 183);
surface->fillRect(backBar, back);
- Common::Rect shieldBar(88 - shield, 180, 88, 186);
+ Common::Rect shieldBar(88 - shield, 177, 88, 183);
surface->fillRect(shieldBar, front);
}
}
Commit: 4633fd48749ac9ec2b93ca5db3fa6fb0306f146a
https://github.com/scummvm/scummvm/commit/4633fd48749ac9ec2b93ca5db3fa6fb0306f146a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T10:12:04+01:00
Commit Message:
FREESCAPE: load correct border palette for certain driller releases
Changed paths:
engines/freescape/games/driller/driller.cpp
engines/freescape/games/palettes.cpp
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index c1e33edd9e2..76bef52466b 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -54,7 +54,7 @@ DrillerEngine::DrillerEngine(OSystem *syst, const ADGameDescription *gd) : Frees
else if (isSpectrum())
_viewArea = Common::Rect(56, 20, 264, 124);
else if (isCPC())
- _viewArea = Common::Rect(36, 19, 284, 120);
+ _viewArea = Common::Rect(36, 16, 284, 117);
else if (isC64())
_viewArea = Common::Rect(32, 16, 288, 119);
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 97d4cfbf94c..6baef6c443f 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -215,6 +215,18 @@ void FreescapeEngine::swapPalette(uint16 levelID) {
_gfx->_inkColor = _areaMap[levelID]->_inkColor;
_gfx->_paperColor = _areaMap[levelID]->_paperColor;
_gfx->_underFireBackgroundColor = _areaMap[levelID]->_underFireBackgroundColor;
+
+ byte *palette = (byte *)malloc(sizeof(byte) * 4 * 3);
+ for (int c = 0; c < 4; c++) {
+ byte r, g, b;
+ _gfx->selectColorFromFourColorPalette(c, r, g, b);
+ palette[3 * c + 0] = r;
+ palette[3 * c + 1] = g;
+ palette[3 * c + 2] = b;
+ }
+ _border->setPalette(palette, 0, 4);
+ free(palette);
+ processBorder();
} else if (isDOS() && _renderMode == Common::kRenderCGA) {
const CGAPalettteEntry *entry = rawCGAPaletteTable;
while (entry->areaId) {
Commit: 6dc129dc3488fcd665356b323c037e9a862a04ca
https://github.com/scummvm/scummvm/commit/6dc129dc3488fcd665356b323c037e9a862a04ca
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T10:12:14+01:00
Commit Message:
FREESCAPE: color and ui fixes for driller cpc
Changed paths:
engines/freescape/games/driller/cpc.cpp
engines/freescape/games/driller/driller.cpp
diff --git a/engines/freescape/games/driller/cpc.cpp b/engines/freescape/games/driller/cpc.cpp
index 25750cfb6b1..68c33eba2e4 100644
--- a/engines/freescape/games/driller/cpc.cpp
+++ b/engines/freescape/games/driller/cpc.cpp
@@ -123,11 +123,18 @@ void deobfuscateDrillerCPCVirtualWorlds(byte *memBuffer) {
}
}
-byte kCPCPalettePinkBlueWhiteData[4][3] = {
+byte kCPCPaletteTitleData[4][3] = {
{0x00, 0x00, 0x00},
- {0x55, 0xff, 0xff},
- {0xff, 0x55, 0xff},
- {0xff, 0xff, 0xff},
+ {0x00, 0x80, 0xff},
+ {0xff, 0x00, 0x00},
+ {0xff, 0xff, 0x00},
+};
+
+byte kCPCPaletteBorderData[4][3] = {
+ {0x00, 0x00, 0x00},
+ {0xff, 0x80, 0x00},
+ {0x80, 0xff, 0xff},
+ {0x00, 0x80, 0x00},
};
Graphics::ManagedSurface *readCPCImage(Common::SeekableReadStream *file) {
@@ -181,7 +188,7 @@ void DrillerEngine::loadAssetsCPCFullGame() {
error("Failed to open DSCN1.BIN");
_title = readCPCImage(&file);
- _title->setPalette((byte*)&kCPCPalettePinkBlueWhiteData, 0, 4);
+ _title->setPalette((byte*)&kCPCPaletteTitleData, 0, 4);
file.close();
file.open("DSCN2.BIN");
@@ -189,7 +196,7 @@ void DrillerEngine::loadAssetsCPCFullGame() {
error("Failed to open DSCN2.BIN");
_border = readCPCImage(&file);
- _border->setPalette((byte*)&kCPCPalettePinkBlueWhiteData, 0, 4);
+ _border->setPalette((byte*)&kCPCPaletteBorderData, 0, 4);
file.close();
file.open("DRILL.BIN");
@@ -220,9 +227,9 @@ void DrillerEngine::drawCPCUI(Graphics::Surface *surface) {
int score = _gameStateVars[k8bitVariableScore];
drawStringInSurface(_currentArea->_name, 200, 185, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 149, 145, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 149, 153, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 149, 161, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 150, 145, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 150, 153, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 150, 161, front, back, surface);
if (_playerHeightNumber >= 0)
drawStringInSurface(Common::String::format("%d", _playerHeightNumber), 54, 161, front, back, surface);
else
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 76bef52466b..62ff6f7d970 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -420,6 +420,9 @@ void DrillerEngine::drawInfoMenu() {
case Common::kRenderZX:
color = 6;
break;
+ case Common::kRenderCPC:
+ color = _gfx->_underFireBackgroundColor;
+ break;
default:
color = 14;
}
Commit: c77e28050002a023caeaf6577af6eed38551b11f
https://github.com/scummvm/scummvm/commit/c77e28050002a023caeaf6577af6eed38551b11f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T10:12:23+01:00
Commit Message:
FREESCAPE: correctly parse images in dos driller demo and removed extra files from freescape.dat
Changed paths:
R devtools/create_freescape/driller_cga.bmp
R devtools/create_freescape/driller_cpc.bmp
dists/engine-data/freescape.dat
engines/freescape/freescape.h
engines/freescape/games/driller/dos.cpp
engines/freescape/games/driller/driller.cpp
diff --git a/devtools/create_freescape/driller_cga.bmp b/devtools/create_freescape/driller_cga.bmp
deleted file mode 100644
index 4234daf00ac..00000000000
Binary files a/devtools/create_freescape/driller_cga.bmp and /dev/null differ
diff --git a/devtools/create_freescape/driller_cpc.bmp b/devtools/create_freescape/driller_cpc.bmp
deleted file mode 100644
index 2b834a76adc..00000000000
Binary files a/devtools/create_freescape/driller_cpc.bmp and /dev/null differ
diff --git a/dists/engine-data/freescape.dat b/dists/engine-data/freescape.dat
index 322725f9b14..4bae5edd3a7 100644
Binary files a/dists/engine-data/freescape.dat and b/dists/engine-data/freescape.dat differ
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 1b21c8edcc4..d2f8405437a 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -462,6 +462,8 @@ private:
void drawAmigaAtariSTUI(Graphics::Surface *surface);
Graphics::ManagedSurface *load8bitTitleImage(Common::SeekableReadStream *file, int offset);
+ Graphics::ManagedSurface *load8bitDemoImage(Common::SeekableReadStream *file, int offset);
+
uint32 getPixel8bitTitleImage(int index);
void renderPixels8bitTitleImage(Graphics::ManagedSurface *surface, int &i, int &j, int pixels);
};
diff --git a/engines/freescape/games/driller/dos.cpp b/engines/freescape/games/driller/dos.cpp
index ee38b0a6b13..4998673f6a7 100644
--- a/engines/freescape/games/driller/dos.cpp
+++ b/engines/freescape/games/driller/dos.cpp
@@ -196,6 +196,50 @@ byte kEGADefaultPaletteData[16][3] = {
{0x00, 0x00, 0x00}
};
+Graphics::ManagedSurface *DrillerEngine::load8bitDemoImage(Common::SeekableReadStream *file, int offset) {
+ Graphics::ManagedSurface *surface = new Graphics::ManagedSurface();
+ surface->create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
+ surface->fillRect(Common::Rect(0, 0, 320, 200), 0);
+ file->seek(offset);
+ int i = 0;
+ int j = 0;
+ while (true) {
+ byte pixels = file->readByte();
+ for (int b = 0; b < 4; b++) {
+ int color = pixels & 3;
+ pixels = pixels >> 2;
+ surface->setPixel(i + (3 - b), 2 * j, color);
+ }
+ i = i + 4;
+ if (i == 320) {
+ i = 0;
+ j++;
+ }
+ if (j == 100)
+ break;
+ }
+ file->seek(0xc0, SEEK_CUR);
+
+ i = 0;
+ j = 0;
+ while (true) {
+ byte pixels = file->readByte();
+ for (int b = 0; b < 4; b++) {
+ int color = pixels & 3;
+ pixels = pixels >> 2;
+ surface->setPixel(i + (3 - b), 2 * j + 1, color);
+ }
+ i = i + 4;
+ if (i == 320) {
+ i = 0;
+ j++;
+ }
+ if (j == 100)
+ break;
+ }
+ return surface;
+}
+
void DrillerEngine::loadAssetsDOSFullGame() {
Common::File file;
if (_renderMode == Common::kRenderEGA) {
@@ -256,7 +300,6 @@ void DrillerEngine::loadAssetsDOSDemo() {
_renderMode = Common::kRenderCGA; // DOS demos is CGA only
_viewArea = Common::Rect(36, 16, 284, 117); // correct view area
_gfx->_renderMode = _renderMode;
- loadBundledImages();
file.open("d2");
if (!file.isOpen())
error("Failed to open 'd2' file");
@@ -265,6 +308,8 @@ void DrillerEngine::loadAssetsDOSDemo() {
loadMessagesFixedSize(&file, 0x636, 14, 20);
load8bitBinary(&file, 0x55b0, 4);
loadGlobalObjects(&file, 0x8c);
+ _border = load8bitDemoImage(&file, 0x6220);
+ _border->setPalette((byte*)&kCGAPalettePinkBlueWhiteData, 0, 4);
// Fixed for a corrupted area names in the demo data
_areaMap[2]->_name = "LAPIS LAZULI";
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 62ff6f7d970..782506c5ea8 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -105,9 +105,6 @@ void DrillerEngine::titleScreen() {
}
}
void DrillerEngine::borderScreen() {
- if (isDOS() && isDemo()) // Demo will not show the border
- return;
-
if (isAmiga() || isAtariST()) // TODO: implement these with their own animations
return;
Commit: ef1a07d8f5ce731bfa08a0140339738cdf340452
https://github.com/scummvm/scummvm/commit/ef1a07d8f5ce731bfa08a0140339738cdf340452
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T10:12:44+01:00
Commit Message:
FREESCAPE: removed edsk related code to parse cpc releases of driller
Changed paths:
engines/freescape/detection.cpp
engines/freescape/games/driller/cpc.cpp
diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 758267f1f88..cdfcccba49d 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -83,18 +83,6 @@ static const ADGameDescription gameDescriptions[] = {
GF_CPC_RETAIL,
GUIO2(GUIO_NOMIDI, GAMEOPTION_AUTOMATIC_DRILLING)
},
- {
- "driller",
- "VirtualWorlds-A",
- {
- {"VIRTUALWORLDS.A.CPC.EDSK", 0, "421d369636984fc209a0969007daa35b", 195635},
- AD_LISTEND
- },
- Common::EN_ANY,
- Common::kPlatformAmstradCPC,
- GF_CPC_VIRTUALWORLDS,
- GUIO2(GUIO_NOMIDI, GAMEOPTION_AUTOMATIC_DRILLING)
- },
{
"spacestationoblivion",
"",
diff --git a/engines/freescape/games/driller/cpc.cpp b/engines/freescape/games/driller/cpc.cpp
index 68c33eba2e4..bd43a0a1d01 100644
--- a/engines/freescape/games/driller/cpc.cpp
+++ b/engines/freescape/games/driller/cpc.cpp
@@ -27,102 +27,6 @@
namespace Freescape {
-byte *parseEDSK(const Common::String filename, int &size) {
- debugC(1, kFreescapeDebugParser, "Trying to parse edsk file: %s", filename.c_str());
- Common::File file;
- file.open(filename);
- if (!file.isOpen())
- error("Failed to open %s", filename.c_str());
-
- int totalSize = file.size();
- byte *edskBuffer = (byte *)malloc(totalSize);
- file.read(edskBuffer, totalSize);
- file.close();
-
- // We don't know the final size, but we allocate enough
- byte *memBuffer = (byte *)malloc(totalSize);
-
- byte nsides = edskBuffer[49];
- assert(nsides == 1);
- int ntracks = 0;
- int i = 256;
- int j = 0;
- while (i + 1 < totalSize) {
- byte ssize = edskBuffer[i + 0x14];
- debugC(1, kFreescapeDebugParser, "i: %x ssize: %d, number: %d", i, ssize, edskBuffer[i + 0x10]);
- assert(ssize == 3 || edskBuffer[i + 0x0] == 'T');
- assert(ssize == 3 || edskBuffer[i + 0x1] == 'r');
- assert(ssize == 3 || edskBuffer[i + 0x2] == 'a');
- //assert(ssize == 3 || ntracks == edskBuffer[i + 0x10]);
- int start = i + 0x100;
- debugC(1, kFreescapeDebugParser, "sector size: %d", ssize);
- if (ssize == 2) {
- i = i + 9 * 512 + 256;
- } else if (ssize == 5) {
- i = i + 8 * 512 + 256;
- } else if (ssize == 0) {
- i = totalSize - 1;
- } else if (ssize == 3) {
- break; // Not sure
- } else {
- error("ssize: %d", ssize);
- }
- int osize = i - start;
- debugC(1, kFreescapeDebugParser, "copying track %d start: %x size: %x, dest: %x", ntracks, start, osize, j);
- memcpy(memBuffer + j, edskBuffer + start, osize);
- j = j + osize;
- ntracks++;
- }
- size = j;
-
- if (0) { // Useful to debug where exactly each object is located in memory once it is parsed
- i = 0;
- while(i < j) {
- debugN("%05x: ", i);
- for (int k = 0; k <= 16; k++) {
- debugN("%02x ", memBuffer[i]);
- i++;
- }
- debugN("\n");
- }
- }
- free(edskBuffer);
- return memBuffer;
-}
-
-void deobfuscateDrillerCPCVirtualWorlds(byte *memBuffer) {
- // Deofuscation / loader code
- for (int j = 0; j < 0x200; j++) {
- memBuffer[0x14000 + j] = memBuffer[0x14200 + j];
- memBuffer[0x14200 + j] = memBuffer[0x13400 + j];
- memBuffer[0x14400 + j] = memBuffer[0x13800 + j];
- memBuffer[0x14600 + j] = memBuffer[0x13c00 + j];
- }
-
- for (int j = 0; j < 0x200; j++) {
- memBuffer[0x13c00 + j] = memBuffer[0x13a00 + j];
- memBuffer[0x13a00 + j] = memBuffer[0x13600 + j];
- memBuffer[0x13800 + j] = memBuffer[0x13200 + j];
- memBuffer[0x13600 + j] = memBuffer[0x12e00 + j];
- memBuffer[0x12e00 + j] = memBuffer[0x13000 + j];
- memBuffer[0x13000 + j] = memBuffer[0x12200 + j];
- memBuffer[0x13200 + j] = memBuffer[0x12600 + j];
- memBuffer[0x13400 + j] = memBuffer[0x12a00 + j];
- }
-
- for (int i = 6; i >= 0; i--) {
- //debug("copying 0x200 bytes to %x from %x", 0x12000 + 0x200*i, 0x11400 + 0x400*i);
- for (int j = 0; j < 0x200; j++) {
- memBuffer[0x12000 + 0x200*i + j] = memBuffer[0x11400 + 0x400*i + j];
- }
- }
-
- for (int j = 0; j < 0x200; j++) {
- memBuffer[0x11c00 + j] = memBuffer[0x11e00 + j];
- memBuffer[0x11e00 + j] = memBuffer[0x11000 + j];
- }
-}
-
byte kCPCPaletteTitleData[4][3] = {
{0x00, 0x00, 0x00},
{0x00, 0x80, 0xff},
Commit: cc7bb7d6601540f78a6e9bc832c06c7f6f65294b
https://github.com/scummvm/scummvm/commit/cc7bb7d6601540f78a6e9bc832c06c7f6f65294b
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T11:00:52+01:00
Commit Message:
FREESCAPE: load and show driller dos demo title image
Changed paths:
engines/freescape/games/driller/dos.cpp
engines/freescape/games/driller/driller.cpp
diff --git a/engines/freescape/games/driller/dos.cpp b/engines/freescape/games/driller/dos.cpp
index 4998673f6a7..fa948e5c330 100644
--- a/engines/freescape/games/driller/dos.cpp
+++ b/engines/freescape/games/driller/dos.cpp
@@ -196,6 +196,11 @@ byte kEGADefaultPaletteData[16][3] = {
{0x00, 0x00, 0x00}
};
+/*
+ The following function is only used for decoding images for
+ the Driller DOS demo
+*/
+
Graphics::ManagedSurface *DrillerEngine::load8bitDemoImage(Common::SeekableReadStream *file, int offset) {
Graphics::ManagedSurface *surface = new Graphics::ManagedSurface();
surface->create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
@@ -300,6 +305,14 @@ void DrillerEngine::loadAssetsDOSDemo() {
_renderMode = Common::kRenderCGA; // DOS demos is CGA only
_viewArea = Common::Rect(36, 16, 284, 117); // correct view area
_gfx->_renderMode = _renderMode;
+ file.open("d1");
+ if (!file.isOpen())
+ error("Failed to open 'd1' file");
+
+ _title = load8bitDemoImage(&file, 0x0);
+ _title->setPalette((byte*)&kCGAPalettePinkBlueWhiteData, 0, 4);
+
+ file.close();
file.open("d2");
if (!file.isOpen())
error("Failed to open 'd2' file");
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 782506c5ea8..a9fb1974581 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -91,9 +91,6 @@ DrillerEngine::~DrillerEngine() {
}
void DrillerEngine::titleScreen() {
- if (isDOS() && isDemo()) // Demo will not show any title screen
- return;
-
if (isAmiga() || isAtariST()) // TODO: implement these with their own animations
return;
Commit: b4f7bc818d2f7507102f85e4f733952e79ead4da
https://github.com/scummvm/scummvm/commit/b4f7bc818d2f7507102f85e4f733952e79ead4da
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T11:01:01+01:00
Commit Message:
FREESCAPE: moved dark side related code to its own directory
Changed paths:
A engines/freescape/games/dark/dark.cpp
A engines/freescape/games/dark/dos.cpp
R engines/freescape/games/dark.cpp
engines/freescape/module.mk
diff --git a/engines/freescape/games/dark.cpp b/engines/freescape/games/dark/dark.cpp
similarity index 82%
rename from engines/freescape/games/dark.cpp
rename to engines/freescape/games/dark/dark.cpp
index 1a10368adb1..29414dbbbc9 100644
--- a/engines/freescape/games/dark.cpp
+++ b/engines/freescape/games/dark/dark.cpp
@@ -298,69 +298,6 @@ void DarkEngine::updateTimeVariables() {
}
}
-void DarkEngine::drawDOSUI(Graphics::Surface *surface) {
- uint32 color = _renderMode == Common::kRenderCGA ? 1 : 14;
- uint8 r, g, b;
-
- _gfx->readFromPalette(color, r, g, b);
- uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
-
- color = _currentArea->_usualBackgroundColor;
- if (_gfx->_colorRemaps && _gfx->_colorRemaps->contains(color)) {
- color = (*_gfx->_colorRemaps)[color];
- }
-
- _gfx->readFromPalette(color, r, g, b);
- uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
-
- int score = _gameStateVars[k8bitVariableScore];
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 199, 137, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 199, 145, front, back, surface);
- drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 199, 153, front, back, surface);
-
- drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 71, 168, front, back, surface);
- drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 71, 177, front, back, surface);
- drawStringInSurface(Common::String::format("%07d", score), 95, 8, front, back, surface);
-
- int seconds, minutes, hours;
- getTimeFromCountdown(seconds, minutes, hours);
- // TODO: implement binary clock
-
- Common::String message;
- int deadline;
- getLatestMessages(message, deadline);
- if (deadline <= _countdown) {
- drawStringInSurface(message, 112, 177, back, front, surface);
- _temporaryMessages.push_back(message);
- _temporaryMessageDeadlines.push_back(deadline);
- } else
- drawStringInSurface(_currentArea->_name, 112, 177, front, back, surface);
-
- int energy = _gameStateVars[k8bitVariableEnergy]; // called fuel in this game
- int shield = _gameStateVars[k8bitVariableShield];
-
- _gfx->readFromPalette(9, r, g, b);
- uint32 blue = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
-
- if (shield >= 0) {
- Common::Rect shieldBar;
- shieldBar = Common::Rect(72, 139, 151 - (k8bitMaxShield - shield), 146);
- surface->fillRect(shieldBar, front);
-
- shieldBar = Common::Rect(72, 140, 151 - (k8bitMaxShield - shield), 145);
- surface->fillRect(shieldBar, blue);
- }
-
- if (energy >= 0) {
- Common::Rect energyBar;
- energyBar = Common::Rect(72, 147, 151 - (k8bitMaxEnergy - energy), 154);
- surface->fillRect(energyBar, front);
-
- energyBar = Common::Rect(72, 148, 151 - (k8bitMaxEnergy - energy), 153);
- surface->fillRect(energyBar, blue);
- }
-}
-
void DarkEngine::drawUI() {
Graphics::Surface *surface = nullptr;
if (_border) { // This can be removed when all the borders are loaded
diff --git a/engines/freescape/games/dark/dos.cpp b/engines/freescape/games/dark/dos.cpp
new file mode 100644
index 00000000000..6a3c5aff2ae
--- /dev/null
+++ b/engines/freescape/games/dark/dos.cpp
@@ -0,0 +1,92 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/file.h"
+
+#include "freescape/freescape.h"
+#include "freescape/language/8bitDetokeniser.h"
+
+namespace Freescape {
+
+void DarkEngine::drawDOSUI(Graphics::Surface *surface) {
+ uint32 color = _renderMode == Common::kRenderCGA ? 1 : 14;
+ uint8 r, g, b;
+
+ _gfx->readFromPalette(color, r, g, b);
+ uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+ color = _currentArea->_usualBackgroundColor;
+ if (_gfx->_colorRemaps && _gfx->_colorRemaps->contains(color)) {
+ color = (*_gfx->_colorRemaps)[color];
+ }
+
+ _gfx->readFromPalette(color, r, g, b);
+ uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+ int score = _gameStateVars[k8bitVariableScore];
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.x())), 199, 137, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.z())), 199, 145, front, back, surface);
+ drawStringInSurface(Common::String::format("%04d", int(2 * _position.y())), 199, 153, front, back, surface);
+
+ drawStringInSurface(Common::String::format("%02d", int(_angleRotations[_angleRotationIndex])), 71, 168, front, back, surface);
+ drawStringInSurface(Common::String::format("%3d", _playerSteps[_playerStepIndex]), 71, 177, front, back, surface);
+ drawStringInSurface(Common::String::format("%07d", score), 95, 8, front, back, surface);
+
+ int seconds, minutes, hours;
+ getTimeFromCountdown(seconds, minutes, hours);
+ // TODO: implement binary clock
+
+ Common::String message;
+ int deadline;
+ getLatestMessages(message, deadline);
+ if (deadline <= _countdown) {
+ drawStringInSurface(message, 112, 177, back, front, surface);
+ _temporaryMessages.push_back(message);
+ _temporaryMessageDeadlines.push_back(deadline);
+ } else
+ drawStringInSurface(_currentArea->_name, 112, 177, front, back, surface);
+
+ int energy = _gameStateVars[k8bitVariableEnergy]; // called fuel in this game
+ int shield = _gameStateVars[k8bitVariableShield];
+
+ _gfx->readFromPalette(9, r, g, b);
+ uint32 blue = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
+
+ if (shield >= 0) {
+ Common::Rect shieldBar;
+ shieldBar = Common::Rect(72, 139, 151 - (k8bitMaxShield - shield), 146);
+ surface->fillRect(shieldBar, front);
+
+ shieldBar = Common::Rect(72, 140, 151 - (k8bitMaxShield - shield), 145);
+ surface->fillRect(shieldBar, blue);
+ }
+
+ if (energy >= 0) {
+ Common::Rect energyBar;
+ energyBar = Common::Rect(72, 147, 151 - (k8bitMaxEnergy - energy), 154);
+ surface->fillRect(energyBar, front);
+
+ energyBar = Common::Rect(72, 148, 151 - (k8bitMaxEnergy - energy), 153);
+ surface->fillRect(energyBar, blue);
+ }
+}
+
+} // End of namespace Freescape
\ No newline at end of file
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 0d3c8b7d085..771c5b78e7f 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -5,7 +5,8 @@ MODULE_OBJS := \
demo.o \
freescape.o \
games/castle.o \
- games/dark.o \
+ games/dark/dark.o \
+ games/dark/dos.o \
games/driller/amiga.o \
games/driller/atari.o \
games/driller/cpc.o \
Commit: 82813e11d638072799ca9d8c7b85e7e3da437535
https://github.com/scummvm/scummvm/commit/82813e11d638072799ca9d8c7b85e7e3da437535
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T11:01:09+01:00
Commit Message:
FREESCAPE: moved some functions to the main freescape class and reorganized game code
Changed paths:
A engines/freescape/assets.cpp
A engines/freescape/ui.cpp
engines/freescape/freescape.cpp
engines/freescape/freescape.h
engines/freescape/games/castle.cpp
engines/freescape/games/dark/dark.cpp
engines/freescape/games/driller/driller.cpp
engines/freescape/games/eclipse.cpp
engines/freescape/module.mk
diff --git a/engines/freescape/assets.cpp b/engines/freescape/assets.cpp
new file mode 100644
index 00000000000..a43b59d02c1
--- /dev/null
+++ b/engines/freescape/assets.cpp
@@ -0,0 +1,72 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Based on Phantasma code by Thomas Harte (2013),
+// available at https://github.com/TomHarte/Phantasma/ (MIT)
+
+#include "freescape/freescape.h"
+
+namespace Freescape {
+
+void FreescapeEngine::loadAssets() {
+ if (isDemo())
+ loadAssetsDemo();
+ else
+ loadAssetsFullGame();
+}
+
+void FreescapeEngine::loadAssetsDemo() {
+}
+
+void FreescapeEngine::loadAssetsAtariDemo() {
+}
+
+void FreescapeEngine::loadAssetsAmigaDemo() {
+}
+
+void FreescapeEngine::loadAssetsDOSDemo() {
+}
+
+void FreescapeEngine::loadAssetsZXDemo() {
+}
+
+void FreescapeEngine::loadAssetsCPCDemo() {
+}
+
+void FreescapeEngine::loadAssetsFullGame() {
+}
+
+void FreescapeEngine::loadAssetsAtariFullGame() {
+}
+
+void FreescapeEngine::loadAssetsAmigaFullGame() {
+}
+
+void FreescapeEngine::loadAssetsDOSFullGame() {
+}
+
+void FreescapeEngine::loadAssetsZXFullGame() {
+}
+
+void FreescapeEngine::loadAssetsCPCFullGame() {
+}
+
+} // End of namespace Freescape
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 52aa76309dd..c39ed86ade4 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -203,10 +203,6 @@ void FreescapeEngine::drawTitle() {
_gfx->setViewport(_viewArea);
}
-void FreescapeEngine::loadAssets() {
- error("Function \"%s\" not implemented", __FUNCTION__);
-}
-
// Taken from the Myst 3 codebase, it should be abstracted
Math::Vector3d FreescapeEngine::directionToVector(float pitch, float heading) {
Math::Vector3d v;
@@ -222,25 +218,6 @@ Math::Vector3d FreescapeEngine::directionToVector(float pitch, float heading) {
return v;
}
-void FreescapeEngine::drawUI() {
- // TODO: crossair
- _gfx->setViewport(_viewArea);
-}
-
-void FreescapeEngine::drawInfoMenu() {
- warning("Function \"%s\" not implemented", __FUNCTION__);
-}
-
-void FreescapeEngine::drawCrossair(Graphics::Surface *surface) {
- uint32 white = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
-
- surface->drawLine(_crossairPosition.x - 3, _crossairPosition.y, _crossairPosition.x - 2, _crossairPosition.y, white);
- surface->drawLine(_crossairPosition.x + 2, _crossairPosition.y, _crossairPosition.x + 3, _crossairPosition.y, white);
-
- surface->drawLine(_crossairPosition.x, _crossairPosition.y - 3, _crossairPosition.x, _crossairPosition.y - 2, white);
- surface->drawLine(_crossairPosition.x, _crossairPosition.y + 2, _crossairPosition.x, _crossairPosition.y + 3, white);
-}
-
void FreescapeEngine::centerCrossair() {
_crossairPosition.x = _viewArea.left + _viewArea.width() / 2;
_crossairPosition.y = _viewArea.top + _viewArea.height() / 2;
@@ -295,7 +272,6 @@ void FreescapeEngine::drawBackground() {
_gfx->clear(_currentArea->_skyColor);
}
-
void FreescapeEngine::drawFrame() {
_gfx->updateProjectionMatrix(70.0, _nearClipPlane, _farClipPlane);
_gfx->positionCamera(_position, _position + _cameraFront);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index d2f8405437a..f0418c893f8 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -135,7 +135,31 @@ public:
// Parsing assets
uint8 _binaryBits;
- virtual void loadAssets();
+ void loadAssets();
+ virtual void loadAssetsDemo();
+ virtual void loadAssetsFullGame();
+
+ virtual void loadAssetsAtariFullGame();
+ virtual void loadAssetsAtariDemo();
+
+ virtual void loadAssetsAmigaFullGame();
+ virtual void loadAssetsAmigaDemo();
+
+ virtual void loadAssetsDOSFullGame();
+ virtual void loadAssetsDOSDemo();
+
+ virtual void loadAssetsZXFullGame();
+ virtual void loadAssetsZXDemo();
+
+ virtual void loadAssetsCPCFullGame();
+ virtual void loadAssetsCPCDemo();
+
+ virtual void drawDOSUI(Graphics::Surface *surface);
+ virtual void drawZXUI(Graphics::Surface *surface);
+ virtual void drawCPCUI(Graphics::Surface *surface);
+ virtual void drawC64UI(Graphics::Surface *surface);
+ virtual void drawAmigaAtariSTUI(Graphics::Surface *surface);
+
Common::Archive *_dataBundle;
void loadDataBundle();
void loadBundledImages();
@@ -419,8 +443,6 @@ public:
void titleScreen() override;
void processBorder() override;
- void loadAssets() override;
- void drawUI() override;
void drawInfoMenu() override;
void pressedKey(const int keycode) override;
@@ -437,29 +459,27 @@ private:
void removeDrill(Area *area);
void addSkanner(Area *area);
- void loadAssetsDemo();
- void loadAssetsFullGame();
+ void loadAssetsDemo() override;
+ void loadAssetsFullGame() override;
- void loadAssetsAtariFullGame();
- void loadAssetsAtariDemo();
+ void loadAssetsAtariFullGame() override;
+ void loadAssetsAtariDemo() override;
- void loadAssetsAmigaFullGame();
- void loadAssetsAmigaDemo();
+ void loadAssetsAmigaFullGame() override;
+ void loadAssetsAmigaDemo() override;
- void loadAssetsDOSFullGame();
- void loadAssetsDOSDemo();
+ void loadAssetsDOSFullGame() override;
+ void loadAssetsDOSDemo() override;
- void loadAssetsZXFullGame();
- void loadAssetsZXDemo();
+ void loadAssetsZXFullGame() override;
- void loadAssetsCPCFullGame();
- void loadAssetsCPCDemo();
+ void loadAssetsCPCFullGame() override;
- void drawDOSUI(Graphics::Surface *surface);
- void drawZXUI(Graphics::Surface *surface);
- void drawCPCUI(Graphics::Surface *surface);
- void drawC64UI(Graphics::Surface *surface);
- void drawAmigaAtariSTUI(Graphics::Surface *surface);
+ void drawDOSUI(Graphics::Surface *surface) override;
+ void drawZXUI(Graphics::Surface *surface) override;
+ void drawCPCUI(Graphics::Surface *surface) override;
+ void drawC64UI(Graphics::Surface *surface) override;
+ void drawAmigaAtariSTUI(Graphics::Surface *surface) override;
Graphics::ManagedSurface *load8bitTitleImage(Common::SeekableReadStream *file, int offset);
Graphics::ManagedSurface *load8bitDemoImage(Common::SeekableReadStream *file, int offset);
@@ -475,7 +495,6 @@ public:
uint32 _initialFuel;
uint32 _initialShield;
- void loadAssets() override;
void initGameState() override;
void borderScreen() override;
void titleScreen() override;
@@ -505,7 +524,7 @@ class EclipseEngine : public FreescapeEngine {
public:
EclipseEngine(OSystem *syst, const ADGameDescription *gd);
- void loadAssets() override;
+ void loadAssetsFullGame() override;
void titleScreen() override;
void gotoArea(uint16 areaID, int entranceID) override;
@@ -519,7 +538,7 @@ class CastleEngine : public FreescapeEngine {
public:
CastleEngine(OSystem *syst, const ADGameDescription *gd);
- void loadAssets() override;
+ void loadAssetsFullGame() override;
void gotoArea(uint16 areaID, int entranceID) override;
Common::Error saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave = false) override;
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 249c3b32064..1830891b8ed 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -56,7 +56,7 @@ Common::SeekableReadStream *CastleEngine::decryptFile(const Common::String filen
return (new Common::MemoryReadStream(encryptedBuffer, size));
}
-void CastleEngine::loadAssets() {
+void CastleEngine::loadAssetsFullGame() {
Common::SeekableReadStream *stream = nullptr;
stream = decryptFile("CMLE");
diff --git a/engines/freescape/games/dark/dark.cpp b/engines/freescape/games/dark/dark.cpp
index 29414dbbbc9..eadc74d1c12 100644
--- a/engines/freescape/games/dark/dark.cpp
+++ b/engines/freescape/games/dark/dark.cpp
@@ -61,13 +61,6 @@ void DarkEngine::titleScreen() {
}
}
-void DarkEngine::loadAssets() {
- if (isDemo())
- loadAssetsDemo();
- else
- loadAssetsFullGame();
-}
-
void DarkEngine::loadAssetsDemo() {
Common::File file;
if (isDOS() && _renderMode == Common::kRenderEGA) {
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index a9fb1974581..d132721d0ae 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -206,16 +206,6 @@ void DrillerEngine::loadGlobalObjects(Common::SeekableReadStream *file, int offs
_areaMap[255] = new Area(255, 0, globalObjectsByID, nullptr);
}
-void DrillerEngine::loadAssets() {
- if (isDemo())
- loadAssetsDemo();
- else
- loadAssetsFullGame();
-
- // Start playing music, if any, in any supported format
- playMusic("Matt Gray - The Best Of Reformation - 07 Driller Theme");
-}
-
void DrillerEngine::loadAssetsDemo() {
Common::File file;
if (isAmiga()) {
@@ -242,20 +232,7 @@ void DrillerEngine::loadAssetsFullGame() {
} else if (isCPC()) {
loadAssetsCPCFullGame();
} else if (isC64()) {
- if (_targetName.hasPrefix("spacestationoblivion")) {
- loadBundledImages();
- file.open("spacestationoblivion.c64.data");
- loadMessagesFixedSize(&file, 0x167a, 14, 20);
- //loadFonts(&file, 0xae54);
- load8bitBinary(&file, 0x8e02, 4);
- loadGlobalObjects(&file, 0x1855);
- } else if (_targetName.hasPrefix("driller")) {
- file.open("driller.c64.data");
- loadMessagesFixedSize(&file, 0x167a - 0x400, 14, 20);
- //loadFonts(&file, 0xae54);
- load8bitBinary(&file, 0x8e02 - 0x400, 4);
- loadGlobalObjects(&file, 0x1855 - 0x400);
- }
+ //loadAssetsC64FullGame();
} else if (isDOS()) {
loadAssetsDOSFullGame();
} else
@@ -289,41 +266,6 @@ void DrillerEngine::processBorder() {
FreescapeEngine::processBorder();
}
-void DrillerEngine::drawUI() {
- Graphics::Surface *surface = nullptr;
- if (_border) { // This can be removed when all the borders are loaded
- uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
- surface = new Graphics::Surface();
- surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
- surface->fillRect(_fullscreenViewArea, gray);
- drawCrossair(surface);
- } else
- return;
-
- if (isDOS())
- drawDOSUI(surface);
- else if (isC64())
- drawC64UI(surface);
- else if (isSpectrum())
- drawZXUI(surface);
- else if (isCPC())
- drawCPCUI(surface);
- else if (isAmiga() || isAtariST())
- drawAmigaAtariSTUI(surface);
-
- if (!_uiTexture)
- _uiTexture = _gfx->createTexture(surface);
- else
- _uiTexture->update(surface);
-
- _gfx->setViewport(_fullscreenViewArea);
- _gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _uiTexture);
- _gfx->setViewport(_viewArea);
-
- surface->free();
- delete surface;
-}
-
void DrillerEngine::drawC64UI(Graphics::Surface *surface) {
uint32 color = 1;
uint8 r, g, b;
@@ -912,6 +854,9 @@ void DrillerEngine::initGameState() {
_lastMinute = minutes;
_demoIndex = 0;
_demoEvents.clear();
+
+ // Start playing music, if any, in any supported format
+ playMusic("Matt Gray - The Best Of Reformation - 07 Driller Theme");
}
bool DrillerEngine::checkIfGameEnded() {
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index 56baa42f46b..e8d67acbfb4 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -111,7 +111,7 @@ void EclipseEngine::titleScreen() {
}
}
-void EclipseEngine::loadAssets() {
+void EclipseEngine::loadAssetsFullGame() {
Common::File file;
if (_renderMode == Common::kRenderEGA) {
file.open("SCN1E.DAT");
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index 771c5b78e7f..f157394ca05 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/freescape
MODULE_OBJS := \
area.o \
+ assets.o \
demo.o \
freescape.o \
games/castle.o \
@@ -25,7 +26,8 @@ MODULE_OBJS := \
objects/geometricobject.o \
objects/sensor.o \
scr.o \
- sound.o
+ sound.o \
+ ui.o
ifdef USE_TINYGL
MODULE_OBJS += \
diff --git a/engines/freescape/ui.cpp b/engines/freescape/ui.cpp
new file mode 100644
index 00000000000..9bc829e4b93
--- /dev/null
+++ b/engines/freescape/ui.cpp
@@ -0,0 +1,90 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "freescape/freescape.h"
+
+namespace Freescape {
+
+void FreescapeEngine::drawUI() {
+ Graphics::Surface *surface = nullptr;
+ if (_border) { // This can be removed when all the borders are loaded
+ uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
+ surface = new Graphics::Surface();
+ surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
+ surface->fillRect(_fullscreenViewArea, gray);
+ drawCrossair(surface);
+ } else
+ return;
+
+ if (isDOS())
+ drawDOSUI(surface);
+ else if (isC64())
+ drawC64UI(surface);
+ else if (isSpectrum())
+ drawZXUI(surface);
+ else if (isCPC())
+ drawCPCUI(surface);
+ else if (isAmiga() || isAtariST())
+ drawAmigaAtariSTUI(surface);
+
+ if (!_uiTexture)
+ _uiTexture = _gfx->createTexture(surface);
+ else
+ _uiTexture->update(surface);
+
+ _gfx->setViewport(_fullscreenViewArea);
+ _gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _uiTexture);
+ _gfx->setViewport(_viewArea);
+
+ surface->free();
+ delete surface;
+}
+
+void FreescapeEngine::drawInfoMenu() {
+ warning("Function \"%s\" not implemented", __FUNCTION__);
+}
+
+void FreescapeEngine::drawCrossair(Graphics::Surface *surface) {
+ uint32 white = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00);
+
+ surface->drawLine(_crossairPosition.x - 3, _crossairPosition.y, _crossairPosition.x - 2, _crossairPosition.y, white);
+ surface->drawLine(_crossairPosition.x + 2, _crossairPosition.y, _crossairPosition.x + 3, _crossairPosition.y, white);
+
+ surface->drawLine(_crossairPosition.x, _crossairPosition.y - 3, _crossairPosition.x, _crossairPosition.y - 2, white);
+ surface->drawLine(_crossairPosition.x, _crossairPosition.y + 2, _crossairPosition.x, _crossairPosition.y + 3, white);
+}
+
+void FreescapeEngine::drawAmigaAtariSTUI(Graphics::Surface *surface) {
+}
+
+void FreescapeEngine::drawDOSUI(Graphics::Surface *surface) {
+}
+
+void FreescapeEngine::drawZXUI(Graphics::Surface *surface) {
+}
+
+void FreescapeEngine::drawCPCUI(Graphics::Surface *surface) {
+}
+
+void FreescapeEngine::drawC64UI(Graphics::Surface *surface) {
+}
+
+} // End of namespace Freescape
Commit: 98a2bbb4f012f840bf481c4e40aaf7b6995197ef
https://github.com/scummvm/scummvm/commit/98a2bbb4f012f840bf481c4e40aaf7b6995197ef
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T11:01:17+01:00
Commit Message:
FREESCAPE: moved more functions to the main freescape class and reorganized game code
Changed paths:
engines/freescape/assets.cpp
engines/freescape/freescape.h
engines/freescape/games/castle.cpp
engines/freescape/games/dark/dark.cpp
engines/freescape/games/driller/driller.cpp
engines/freescape/games/eclipse.cpp
diff --git a/engines/freescape/assets.cpp b/engines/freescape/assets.cpp
index a43b59d02c1..813dfb45683 100644
--- a/engines/freescape/assets.cpp
+++ b/engines/freescape/assets.cpp
@@ -22,6 +22,8 @@
// Based on Phantasma code by Thomas Harte (2013),
// available at https://github.com/TomHarte/Phantasma/ (MIT)
+#include "common/file.h"
+
#include "freescape/freescape.h"
namespace Freescape {
@@ -33,7 +35,37 @@ void FreescapeEngine::loadAssets() {
loadAssetsFullGame();
}
+void FreescapeEngine::loadAssetsFullGame() {
+ Common::File file;
+ if (isAmiga()) {
+ loadAssetsAmigaFullGame();
+ } else if (isAtariST()) {
+ loadAssetsAtariFullGame();
+ } else if (isSpectrum()) {
+ loadAssetsZXFullGame();
+ } else if (isCPC()) {
+ loadAssetsCPCFullGame();
+ } else if (isC64()) {
+ //loadAssetsC64FullGame();
+ } else if (isDOS()) {
+ loadAssetsDOSFullGame();
+ } else
+ error("Invalid or unsupported render mode %s for Driller", Common::getRenderModeDescription(_renderMode));
+}
+
void FreescapeEngine::loadAssetsDemo() {
+ Common::File file;
+ if (isAmiga()) {
+ loadAssetsAmigaDemo();
+ } else if (isAtariST()) {
+ loadAssetsAtariDemo();
+ } else if (isDOS()) {
+ loadAssetsDOSDemo();
+ } else
+ error("Unsupported demo for Driller");
+
+ _demoMode = !_disableDemoMode;
+ _angleRotationIndex = 0;
}
void FreescapeEngine::loadAssetsAtariDemo() {
@@ -51,9 +83,6 @@ void FreescapeEngine::loadAssetsZXDemo() {
void FreescapeEngine::loadAssetsCPCDemo() {
}
-void FreescapeEngine::loadAssetsFullGame() {
-}
-
void FreescapeEngine::loadAssetsAtariFullGame() {
}
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index f0418c893f8..46d817799cb 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -459,7 +459,6 @@ private:
void removeDrill(Area *area);
void addSkanner(Area *area);
- void loadAssetsDemo() override;
void loadAssetsFullGame() override;
void loadAssetsAtariFullGame() override;
@@ -504,14 +503,14 @@ public:
void pressedKey(const int keycode) override;
void executePrint(FCLInstruction &instruction) override;
- void loadAssetsDemo();
- void loadAssetsFullGame();
+ void loadAssetsDOSFullGame() override;
+ void loadAssetsDOSDemo() override;
+
int _lastTenSeconds;
void updateTimeVariables() override;
void executeMovementConditions() override;
- void drawUI() override;
- void drawDOSUI(Graphics::Surface *surface);
+ void drawDOSUI(Graphics::Surface *surface) override;
void drawFullscreenMessage(Common::String message);
Common::Error saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave = false) override;
Common::Error loadGameStreamExtended(Common::SeekableReadStream *stream) override;
@@ -524,12 +523,12 @@ class EclipseEngine : public FreescapeEngine {
public:
EclipseEngine(OSystem *syst, const ADGameDescription *gd);
- void loadAssetsFullGame() override;
void titleScreen() override;
-
void gotoArea(uint16 areaID, int entranceID) override;
+ void loadAssetsDOSFullGame() override;
void drawUI() override;
+
Common::Error saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave = false) override;
Common::Error loadGameStreamExtended(Common::SeekableReadStream *stream) override;
};
@@ -538,7 +537,7 @@ class CastleEngine : public FreescapeEngine {
public:
CastleEngine(OSystem *syst, const ADGameDescription *gd);
- void loadAssetsFullGame() override;
+ void loadAssetsDOSFullGame() override;
void gotoArea(uint16 areaID, int entranceID) override;
Common::Error saveGameStreamExtended(Common::WriteStream *stream, bool isAutosave = false) override;
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 1830891b8ed..e81afcff921 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -56,7 +56,7 @@ Common::SeekableReadStream *CastleEngine::decryptFile(const Common::String filen
return (new Common::MemoryReadStream(encryptedBuffer, size));
}
-void CastleEngine::loadAssetsFullGame() {
+void CastleEngine::loadAssetsDOSFullGame() {
Common::SeekableReadStream *stream = nullptr;
stream = decryptFile("CMLE");
diff --git a/engines/freescape/games/dark/dark.cpp b/engines/freescape/games/dark/dark.cpp
index eadc74d1c12..0cb8e2d2a9a 100644
--- a/engines/freescape/games/dark/dark.cpp
+++ b/engines/freescape/games/dark/dark.cpp
@@ -61,36 +61,6 @@ void DarkEngine::titleScreen() {
}
}
-void DarkEngine::loadAssetsDemo() {
- Common::File file;
- if (isDOS() && _renderMode == Common::kRenderEGA) {
- file.open("SCN1E.DAT");
- if (file.isOpen())
- _title = load8bitBinImage(&file, 0x0);
- file.close();
- file.open("DSIDEE.EXE");
-
- if (!file.isOpen())
- error("Failed to open DSIDEE.EXE");
- loadMessagesFixedSize(&file, 0x4525, 16, 27);
- loadMessagesFixedSize(&file, 0x9959, 307, 5);
- loadFonts(&file, 0xa598);
- loadGlobalObjects(&file, 0x3d04);
- load8bitBinary(&file, 0xa700, 16);
- _border = load8bitBinImage(&file, 0x210);
- } else if (isDOS() && _renderMode == Common::kRenderCGA) {
- //loadBundledImages();
- file.open("DSIDEC.EXE");
-
- if (!file.isOpen())
- error("Failed to open DSIDEC.EXE");
- loadFonts(&file, 0xa598);
- load8bitBinary(&file, 0x8a70, 4); // TODO
- } else
- error("Invalid or unsupported render mode %s for Dark Side", Common::getRenderModeDescription(_renderMode));
-}
-
-
void DarkEngine::loadGlobalObjects(Common::SeekableReadStream *file, int offset) {
assert(!_areaMap.contains(255));
ObjectMap *globalObjectsByID = new ObjectMap;
@@ -106,7 +76,6 @@ void DarkEngine::loadGlobalObjects(Common::SeekableReadStream *file, int offset)
_areaMap[255] = new Area(255, 0, globalObjectsByID, nullptr);
}
-
void DarkEngine::initGameState() {
_flyMode = false;
_noClipMode = false;
@@ -135,12 +104,48 @@ void DarkEngine::initGameState() {
_demoEvents.clear();
}
-void DarkEngine::loadAssetsFullGame() {
+extern byte kEGADefaultPaletteData[16][3];
+
+void DarkEngine::loadAssetsDOSDemo() {
Common::File file;
if (_renderMode == Common::kRenderEGA) {
file.open("SCN1E.DAT");
- if (file.isOpen())
+ if (file.isOpen()) {
_title = load8bitBinImage(&file, 0x0);
+ _title->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
+ }
+ file.close();
+ file.open("DSIDEE.EXE");
+
+ if (!file.isOpen())
+ error("Failed to open DSIDEE.EXE");
+ loadMessagesFixedSize(&file, 0x4525, 16, 27);
+ loadMessagesFixedSize(&file, 0x9959, 307, 5);
+ loadFonts(&file, 0xa598);
+ loadGlobalObjects(&file, 0x3d04);
+ load8bitBinary(&file, 0xa700, 16);
+ _border = load8bitBinImage(&file, 0x210);
+ _border->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
+ } else if (_renderMode == Common::kRenderCGA) {
+ //loadBundledImages();
+ file.open("DSIDEC.EXE");
+
+ if (!file.isOpen())
+ error("Failed to open DSIDEC.EXE");
+ loadFonts(&file, 0xa598);
+ load8bitBinary(&file, 0x8a70, 4); // TODO
+ } else
+ error("Invalid or unsupported render mode %s for Dark Side", Common::getRenderModeDescription(_renderMode));
+}
+
+void DarkEngine::loadAssetsDOSFullGame() {
+ Common::File file;
+ if (_renderMode == Common::kRenderEGA) {
+ file.open("SCN1E.DAT");
+ if (file.isOpen()) {
+ _title = load8bitBinImage(&file, 0x0);
+ _title->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
+ }
file.close();
file.open("DSIDEE.EXE");
@@ -152,6 +157,7 @@ void DarkEngine::loadAssetsFullGame() {
loadGlobalObjects(&file, 0x3d04);
load8bitBinary(&file, 0xa280, 16);
_border = load8bitBinImage(&file, 0x210);
+ _border->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
// TODO: load objects
/*for (auto &it : _areaMap) {
@@ -291,35 +297,6 @@ void DarkEngine::updateTimeVariables() {
}
}
-void DarkEngine::drawUI() {
- Graphics::Surface *surface = nullptr;
- if (_border) { // This can be removed when all the borders are loaded
- uint32 gray = _gfx->_texturePixelFormat.ARGBToColor(0x00, 0xA0, 0xA0, 0xA0);
- surface = new Graphics::Surface();
- surface->create(_screenW, _screenH, _gfx->_texturePixelFormat);
- surface->fillRect(_fullscreenViewArea, gray);
- drawCrossair(surface);
- } else
- return;
-
- if (isDOS())
- drawDOSUI(surface);
- else
- error("UI not implemented yet");
-
- if (!_uiTexture)
- _uiTexture = _gfx->createTexture(surface);
- else
- _uiTexture->update(surface);
-
- _gfx->setViewport(_fullscreenViewArea);
- _gfx->drawTexturedRect2D(_fullscreenViewArea, _fullscreenViewArea, _uiTexture);
- _gfx->setViewport(_viewArea);
-
- surface->free();
- delete surface;
-}
-
void DarkEngine::borderScreen() {
if (_border) {
drawBorder();
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index d132721d0ae..72e7f9e05a6 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -206,38 +206,8 @@ void DrillerEngine::loadGlobalObjects(Common::SeekableReadStream *file, int offs
_areaMap[255] = new Area(255, 0, globalObjectsByID, nullptr);
}
-void DrillerEngine::loadAssetsDemo() {
- Common::File file;
- if (isAmiga()) {
- loadAssetsAmigaDemo();
- } else if (isAtariST()) {
- loadAssetsAtariDemo();
- } else if (isDOS()) {
- loadAssetsDOSDemo();
- } else
- error("Unsupported demo for Driller");
-
- _demoMode = !_disableDemoMode;
- _angleRotationIndex = 0;
-}
-
void DrillerEngine::loadAssetsFullGame() {
- Common::File file;
- if (isAmiga()) {
- loadAssetsAmigaFullGame();
- } else if (isAtariST()) {
- loadAssetsAtariFullGame();
- } else if (isSpectrum()) {
- loadAssetsZXFullGame();
- } else if (isCPC()) {
- loadAssetsCPCFullGame();
- } else if (isC64()) {
- //loadAssetsC64FullGame();
- } else if (isDOS()) {
- loadAssetsDOSFullGame();
- } else
- error("Invalid or unsupported render mode %s for Driller", Common::getRenderModeDescription(_renderMode));
-
+ FreescapeEngine::loadAssetsFullGame();
/*
We are going to inject a small script in the
last area to force the game to end:
diff --git a/engines/freescape/games/eclipse.cpp b/engines/freescape/games/eclipse.cpp
index e8d67acbfb4..7f970e86209 100644
--- a/engines/freescape/games/eclipse.cpp
+++ b/engines/freescape/games/eclipse.cpp
@@ -111,12 +111,15 @@ void EclipseEngine::titleScreen() {
}
}
-void EclipseEngine::loadAssetsFullGame() {
+extern byte kEGADefaultPaletteData[16][3];
+
+void EclipseEngine::loadAssetsDOSFullGame() {
Common::File file;
if (_renderMode == Common::kRenderEGA) {
file.open("SCN1E.DAT");
if (file.isOpen()) {
_title = load8bitBinImage(&file, 0x0);
+ _title->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
}
file.close();
file.open("TOTEE.EXE");
@@ -129,6 +132,7 @@ void EclipseEngine::loadAssetsFullGame() {
for (auto &it : _areaMap)
it._value->addStructure(_areaMap[255]);
_border = load8bitBinImage(&file, 0x210);
+ _border->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
} else if (_renderMode == Common::kRenderCGA) {
loadBundledImages();
file.open("TOTEC.EXE");
Commit: 3b135c9ed82efdfe9a0514bba124f1b6c53c271a
https://github.com/scummvm/scummvm/commit/3b135c9ed82efdfe9a0514bba124f1b6c53c271a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T11:01:34+01:00
Commit Message:
FREESCAPE: moved code from dark dos release into its dedicated file
Changed paths:
engines/freescape/games/dark/dark.cpp
engines/freescape/games/dark/dos.cpp
diff --git a/engines/freescape/games/dark/dark.cpp b/engines/freescape/games/dark/dark.cpp
index 0cb8e2d2a9a..d628c4d4ef5 100644
--- a/engines/freescape/games/dark/dark.cpp
+++ b/engines/freescape/games/dark/dark.cpp
@@ -104,78 +104,6 @@ void DarkEngine::initGameState() {
_demoEvents.clear();
}
-extern byte kEGADefaultPaletteData[16][3];
-
-void DarkEngine::loadAssetsDOSDemo() {
- Common::File file;
- if (_renderMode == Common::kRenderEGA) {
- file.open("SCN1E.DAT");
- if (file.isOpen()) {
- _title = load8bitBinImage(&file, 0x0);
- _title->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
- }
- file.close();
- file.open("DSIDEE.EXE");
-
- if (!file.isOpen())
- error("Failed to open DSIDEE.EXE");
- loadMessagesFixedSize(&file, 0x4525, 16, 27);
- loadMessagesFixedSize(&file, 0x9959, 307, 5);
- loadFonts(&file, 0xa598);
- loadGlobalObjects(&file, 0x3d04);
- load8bitBinary(&file, 0xa700, 16);
- _border = load8bitBinImage(&file, 0x210);
- _border->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
- } else if (_renderMode == Common::kRenderCGA) {
- //loadBundledImages();
- file.open("DSIDEC.EXE");
-
- if (!file.isOpen())
- error("Failed to open DSIDEC.EXE");
- loadFonts(&file, 0xa598);
- load8bitBinary(&file, 0x8a70, 4); // TODO
- } else
- error("Invalid or unsupported render mode %s for Dark Side", Common::getRenderModeDescription(_renderMode));
-}
-
-void DarkEngine::loadAssetsDOSFullGame() {
- Common::File file;
- if (_renderMode == Common::kRenderEGA) {
- file.open("SCN1E.DAT");
- if (file.isOpen()) {
- _title = load8bitBinImage(&file, 0x0);
- _title->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
- }
- file.close();
- file.open("DSIDEE.EXE");
-
- if (!file.isOpen())
- error("Failed to open DSIDEE.EXE");
-
- loadFonts(&file, 0xa113);
- loadMessagesFixedSize(&file, 0x4525, 16, 27);
- loadGlobalObjects(&file, 0x3d04);
- load8bitBinary(&file, 0xa280, 16);
- _border = load8bitBinImage(&file, 0x210);
- _border->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
-
- // TODO: load objects
- /*for (auto &it : _areaMap) {
- if (!it._value->entranceWithID(255))
- continue;
- it._value->addStructure(_areaMap[255]);
- }*/
- } else if (_renderMode == Common::kRenderCGA) {
- loadBundledImages();
- file.open("DSIDEC.EXE");
-
- if (!file.isOpen())
- error("Failed to open DSIDEC.EXE");
- load8bitBinary(&file, 0x7bb0, 4); // TODO
- } else
- error("Invalid or unsupported render mode %s for Dark Side", Common::getRenderModeDescription(_renderMode));
-}
-
void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
debugC(1, kFreescapeDebugMove, "Jumping to area: %d, entrance: %d", areaID, entranceID);
if (!_gameStateBits.contains(areaID))
diff --git a/engines/freescape/games/dark/dos.cpp b/engines/freescape/games/dark/dos.cpp
index 6a3c5aff2ae..24c4396d079 100644
--- a/engines/freescape/games/dark/dos.cpp
+++ b/engines/freescape/games/dark/dos.cpp
@@ -26,6 +26,78 @@
namespace Freescape {
+extern byte kEGADefaultPaletteData[16][3];
+
+void DarkEngine::loadAssetsDOSDemo() {
+ Common::File file;
+ if (_renderMode == Common::kRenderEGA) {
+ file.open("SCN1E.DAT");
+ if (file.isOpen()) {
+ _title = load8bitBinImage(&file, 0x0);
+ _title->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
+ }
+ file.close();
+ file.open("DSIDEE.EXE");
+
+ if (!file.isOpen())
+ error("Failed to open DSIDEE.EXE");
+ loadMessagesFixedSize(&file, 0x4525, 16, 27);
+ loadMessagesFixedSize(&file, 0x9959, 307, 5);
+ loadFonts(&file, 0xa598);
+ loadGlobalObjects(&file, 0x3d04);
+ load8bitBinary(&file, 0xa700, 16);
+ _border = load8bitBinImage(&file, 0x210);
+ _border->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
+ } else if (_renderMode == Common::kRenderCGA) {
+ //loadBundledImages();
+ file.open("DSIDEC.EXE");
+
+ if (!file.isOpen())
+ error("Failed to open DSIDEC.EXE");
+ loadFonts(&file, 0xa598);
+ load8bitBinary(&file, 0x8a70, 4); // TODO
+ } else
+ error("Invalid or unsupported render mode %s for Dark Side", Common::getRenderModeDescription(_renderMode));
+}
+
+void DarkEngine::loadAssetsDOSFullGame() {
+ Common::File file;
+ if (_renderMode == Common::kRenderEGA) {
+ file.open("SCN1E.DAT");
+ if (file.isOpen()) {
+ _title = load8bitBinImage(&file, 0x0);
+ _title->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
+ }
+ file.close();
+ file.open("DSIDEE.EXE");
+
+ if (!file.isOpen())
+ error("Failed to open DSIDEE.EXE");
+
+ loadFonts(&file, 0xa113);
+ loadMessagesFixedSize(&file, 0x4525, 16, 27);
+ loadGlobalObjects(&file, 0x3d04);
+ load8bitBinary(&file, 0xa280, 16);
+ _border = load8bitBinImage(&file, 0x210);
+ _border->setPalette((byte *)&kEGADefaultPaletteData, 0, 16);
+
+ // TODO: load objects
+ /*for (auto &it : _areaMap) {
+ if (!it._value->entranceWithID(255))
+ continue;
+ it._value->addStructure(_areaMap[255]);
+ }*/
+ } else if (_renderMode == Common::kRenderCGA) {
+ loadBundledImages();
+ file.open("DSIDEC.EXE");
+
+ if (!file.isOpen())
+ error("Failed to open DSIDEC.EXE");
+ load8bitBinary(&file, 0x7bb0, 4); // TODO
+ } else
+ error("Invalid or unsupported render mode %s for Dark Side", Common::getRenderModeDescription(_renderMode));
+}
+
void DarkEngine::drawDOSUI(Graphics::Surface *surface) {
uint32 color = _renderMode == Common::kRenderCGA ? 1 : 14;
uint8 r, g, b;
Commit: 0154df5c8bd619f8c5b86573fd615cf67085f880
https://github.com/scummvm/scummvm/commit/0154df5c8bd619f8c5b86573fd615cf67085f880
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T11:01:42+01:00
Commit Message:
FREESCAPE: simplified driller cpc color handling code
Changed paths:
engines/freescape/games/driller/cpc.cpp
engines/freescape/gfx.cpp
diff --git a/engines/freescape/games/driller/cpc.cpp b/engines/freescape/games/driller/cpc.cpp
index bd43a0a1d01..ced3e80c64e 100644
--- a/engines/freescape/games/driller/cpc.cpp
+++ b/engines/freescape/games/driller/cpc.cpp
@@ -41,6 +41,19 @@ byte kCPCPaletteBorderData[4][3] = {
{0x00, 0x80, 0x00},
};
+byte getCPCPixel(byte cpc_byte, int index) {
+ if (index == 0)
+ return ((cpc_byte & 0x08) >> 2) | ((cpc_byte & 0x80) >> 7);
+ else if (index == 1)
+ return ((cpc_byte & 0x04) >> 1) | ((cpc_byte & 0x40) >> 6);
+ else if (index == 2)
+ return (cpc_byte & 0x02) | ((cpc_byte & 0x20) >> 5);
+ else if (index == 3)
+ return ((cpc_byte & 0x01) << 1) | ((cpc_byte & 0x10) >> 4);
+ else
+ error("Invalid index %d requested", index);
+}
+
Graphics::ManagedSurface *readCPCImage(Common::SeekableReadStream *file) {
Graphics::ManagedSurface *surface = new Graphics::ManagedSurface();
surface->create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
@@ -54,25 +67,25 @@ Graphics::ManagedSurface *readCPCImage(Common::SeekableReadStream *file) {
byte cpc_byte = file->readByte(); // Get CPC byte
// Process first pixel
- int pixel_0 = ((cpc_byte & 0x08) >> 2) | ((cpc_byte & 0x80) >> 7); // %Aa
+ int pixel_0 = getCPCPixel(cpc_byte, 0); // %Aa
y = line * 8 + block ; // Coord Y for the pixel
x = 4 * offset + 0; // Coord X for the pixel
surface->setPixel(x, y, pixel_0);
// Process second pixel
- int pixel_1 = ((cpc_byte & 0x04) >> 1) | ((cpc_byte & 0x40) >> 6); // %Bb
+ int pixel_1 = getCPCPixel(cpc_byte, 1); // %Bb
y = line * 8 + block ; // Coord Y for the pixel
x = 4 * offset + 1; // Coord X for the pixel
surface->setPixel(x, y, pixel_1);
// Process third pixel
- int pixel_2 = (cpc_byte & 0x02) | ((cpc_byte & 0x20) >> 5); // %Cc
+ int pixel_2 = getCPCPixel(cpc_byte, 2); // %Cc
y = line * 8 + block ; // Coord Y for the pixel
x = 4 * offset + 2; // Coord X for the pixel
surface->setPixel(x, y, pixel_2);
// Process fourth pixel
- int pixel_3 = ((cpc_byte & 0x01) << 1) | ((cpc_byte & 0x10) >> 4); // %Dd
+ int pixel_3 = getCPCPixel(cpc_byte, 3); // %Dd
y = line * 8 + block ; // Coord Y for the pixel
x = 4 * offset + 3; // Coord X for the pixel
surface->setPixel(x, y, pixel_3);
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index d93e937dab8..55fbc4d7624 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -188,44 +188,6 @@ bool Renderer::getRGBAtZX(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r
return true;
}
-void Renderer::extractCPCIndexes(uint8 cm1, uint8 cm2, uint8 &i1, uint8 &i2) {
- if (cm1 == 0xb4 && cm2 == 0xe1) {
- i1 = 1;
- i2 = 2;
- } else if (cm1 == 0xb0 && cm2 == 0xe0) {
- i1 = 1;
- i2 = 0;
- } else if (cm1 == 0x05 && cm2 == 0x0a) {
- i1 = 2;
- i2 = 0;
- } else if (cm1 == 0x50 && cm2 == 0xa0) {
- i1 = 1;
- i2 = 0;
- } else if (cm1 == 0x55 && cm2 == 0xaa) {
- i1 = 3;
- i2 = 0;
- } else if (cm1 == 0xf5 && cm2 == 0xfa) {
- i1 = 3;
- i2 = 1;
- } else if (cm1 == 0x5a && cm2 == 0xa5) {
- i1 = 1;
- i2 = 2;
- } else if (cm1 == 0xbb && cm2 == 0xee) {
- i1 = 3;
- i2 = 0;
- } else if (cm1 == 0x5f && cm2 == 0xaf) {
- i1 = 3;
- i2 = 2;
- } else if (cm1 == 0xfb && cm2 == 0xfe) { // TODO
- i1 = 0;
- i2 = 0;
- } else if (cm1 == 0x40 && cm2 == 0x20) { // This one has a special stapple pattern
- i1 = 1;
- i2 = 0;
- } else
- error("%x %x", cm1, cm2);
-}
-
void Renderer::selectColorFromFourColorPalette(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1) {
if (index == 0) {
r1 = 0;
@@ -241,6 +203,8 @@ void Renderer::selectColorFromFourColorPalette(uint8 index, uint8 &r1, uint8 &g1
error("Invalid color");
}
+extern byte getCPCPixel(byte cpc_byte, int index);
+
bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2) {
if (index == _keyColor)
return false;
@@ -260,7 +224,8 @@ bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
entry++;
uint8 cm2 = *(entry);
- extractCPCIndexes(cm1, cm2, i1, i2);
+ i1 = getCPCPixel(cm1, 0);
+ i2 = getCPCPixel(cm1, 1);
selectColorFromFourColorPalette(i1, r1, g1, b1);
selectColorFromFourColorPalette(i2, r2, g2, b2);
return true;
Commit: 35492b4673ec67cdc2eeff09837011aff026378d
https://github.com/scummvm/scummvm/commit/35492b4673ec67cdc2eeff09837011aff026378d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T11:02:03+01:00
Commit Message:
FREESCAPE: commented unused variable
Changed paths:
engines/freescape/gfx.cpp
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 55fbc4d7624..c0e1ef5716c 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -222,7 +222,7 @@ bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
byte *entry = (*_colorMap)[index - 1];
uint8 cm1 = *(entry);
entry++;
- uint8 cm2 = *(entry);
+ //uint8 cm2 = *(entry);
i1 = getCPCPixel(cm1, 0);
i2 = getCPCPixel(cm1, 1);
Commit: 55ae8e40967d0f43180abd61a2b6331a12fc4df4
https://github.com/scummvm/scummvm/commit/55ae8e40967d0f43180abd61a2b6331a12fc4df4
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T11:02:14+01:00
Commit Message:
FREESCAPE: pregenerate and show stipple patterns for driller in zx, cpc and cga
Changed paths:
engines/freescape/games/palettes.cpp
engines/freescape/gfx.cpp
engines/freescape/gfx.h
engines/freescape/gfx_opengl.cpp
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 6baef6c443f..00e626fb653 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -124,7 +124,7 @@ void FreescapeEngine::loadColorPalette() {
} else
error("Invalid render mode, no palette selected");
- _gfx->_colorMap = &_colorMap;
+ _gfx->setColorMap(&_colorMap);
}
void FreescapeEngine::loadPalettes(Common::SeekableReadStream *file, int offset) {
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index c0e1ef5716c..ccf83daa9b2 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -48,10 +48,117 @@ Renderer::Renderer(int screenW, int screenH, Common::RenderMode renderMode) {
_colorRemaps = nullptr;
_renderMode = renderMode;
_isAccelerated = false;
+
+ for (int i = 0; i < 16; i++) {
+ _stipples[0][i] = 0;
+ _stipples[1][i] = 0;
+ _stipples[2][i] = 0;
+ _stipples[3][i] = 0;
+ }
}
Renderer::~Renderer() {}
+extern byte getCPCPixel(byte cpc_byte, int index);
+
+byte getCPCStipple(byte cpc_byte, int back, int fore) {
+ int c0 = getCPCPixel(cpc_byte, 0);
+ assert(c0 == back || c0 == fore);
+ int c1 = getCPCPixel(cpc_byte, 1);
+ assert(c1 == back || c1 == fore);
+ int c2 = getCPCPixel(cpc_byte, 2);
+ assert(c2 == back || c2 == fore);
+ int c3 = getCPCPixel(cpc_byte, 3);
+ assert(c3 == back || c3 == fore);
+
+ byte st = 0;
+ if (c0 == fore)
+ st = st | 0x3;
+
+ if (c1 == fore)
+ st = st | (2 << 0x3);
+
+ if (c2 == fore)
+ st = st | (4 << 0x3);
+
+ if (c3 == fore)
+ st = st | (6 << 0x3);
+
+ return st;
+}
+
+byte getCGAPixel(byte x, int index) {
+ if (index == 0)
+ return (x >> 0) & 0x3;
+ else if (index == 1)
+ return (x >> 2) & 0x3;
+ else if (index == 2)
+ return (x >> 4) & 0x3;
+ else if (index == 3)
+ return (x >> 6) & 0x3;
+ else
+ error("Invalid index %d requested", index);
+}
+
+byte getCGAStipple(byte x, int back, int fore) {
+ int c0 = getCGAPixel(x, 0);
+ assert(c0 == back || c0 == fore || back == fore);
+ int c1 = getCGAPixel(x, 1);
+ assert(c1 == back || c1 == fore || back == fore);
+ int c2 = getCGAPixel(x, 2);
+ assert(c2 == back || c2 == fore || back == fore);
+ int c3 = getCGAPixel(x, 3);
+ assert(c3 == back || c3 == fore || back == fore);
+
+ byte st = 0;
+ if (c0 == fore)
+ st = st | 0x3;
+
+ if (c1 == fore)
+ st = st | (2 << 0x3);
+
+ if (c2 == fore)
+ st = st | (4 << 0x3);
+
+ if (c3 == fore)
+ st = st | (6 << 0x3);
+
+ return st;
+}
+
+void Renderer::setColorMap(ColorMap *colorMap_) {
+ _colorMap = colorMap_;
+ if (_renderMode == Common::kRenderZX) {
+ for (int i = 0; i < 15; i++) {
+ byte *entry = (*_colorMap)[i];
+ _stipples[0][i] = entry[0];
+ _stipples[1][i] = entry[1];
+ _stipples[2][i] = entry[2];
+ _stipples[3][i] = entry[3];
+ }
+ } else if (_renderMode == Common::kRenderCPC) {
+ for (int i = 0; i < 15; i++) {
+ byte *entry = (*_colorMap)[i];
+ int i1 = getCPCPixel(entry[0], 0);
+ int i2 = getCPCPixel(entry[0], 1);
+ _stipples[0][i] = getCPCStipple(entry[0], i1, i2);
+ _stipples[1][i] = getCPCStipple(entry[1], i1, i2);
+ _stipples[2][i] = getCPCStipple(entry[2], i1, i2);
+ _stipples[3][i] = getCPCStipple(entry[3], i1, i2);
+ }
+ } else if (_renderMode == Common::kRenderCGA) {
+ for (int i = 0; i < 15; i++) {
+ byte *entry = (*_colorMap)[i];
+ int i1 = getCGAPixel(entry[0], 0);
+ int i2 = getCGAPixel(entry[0], 1);
+ _stipples[0][i] = getCGAStipple(entry[0], i1, i2);
+ _stipples[1][i] = getCGAStipple(entry[1], i1, i2);
+ _stipples[2][i] = getCGAStipple(entry[2], i1, i2);
+ _stipples[3][i] = getCGAStipple(entry[3], i1, i2);
+ }
+ }
+}
+
void Renderer::readFromPalette(uint8 index, uint8 &r, uint8 &g, uint8 &b) {
r = _palette[3 * index + 0];
g = _palette[3 * index + 1];
@@ -71,7 +178,7 @@ void Renderer::setColorRemaps(ColorReMap *colorRemaps) {
_colorRemaps = colorRemaps;
}
-bool Renderer::getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2) {
+bool Renderer::getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple) {
if (index == _keyColor)
return false;
@@ -84,12 +191,18 @@ bool Renderer::getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
return true;
}
+ if (stipple) {
+ stipple[0] = _stipples[0][index - 1];
+ stipple[1] = _stipples[1][index - 1];
+ stipple[2] = _stipples[2][index - 1];
+ stipple[3] = _stipples[3][index - 1];
+ }
+
byte *entry = (*_colorMap)[index - 1];
- byte be = *(entry);
- readFromPalette((be >> 4) % 4, r1, g1, b1);
- entry++;
- be = *(entry);
- readFromPalette((be >> 4) % 4, r2, g2, b2);
+ uint8 c1 = getCGAPixel(entry[0], 0);
+ uint8 c2 = getCGAPixel(entry[0], 1);
+ readFromPalette(c1, r1, g1, b1);
+ readFromPalette(c2, r2, g2, b2);
return true;
}
@@ -177,10 +290,10 @@ bool Renderer::getRGBAtZX(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r
}
if (stipple) {
- stipple[0] = entry[0];
- stipple[1] = entry[1];
- stipple[2] = entry[2];
- stipple[3] = entry[3];
+ stipple[0] = _stipples[0][index - 1];
+ stipple[1] = _stipples[1][index - 1];
+ stipple[2] = _stipples[2][index - 1];
+ stipple[3] = _stipples[3][index - 1];
}
readFromPalette(_paperColor, r1, g1, b1);
@@ -203,9 +316,7 @@ void Renderer::selectColorFromFourColorPalette(uint8 index, uint8 &r1, uint8 &g1
error("Invalid color");
}
-extern byte getCPCPixel(byte cpc_byte, int index);
-
-bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2) {
+bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple) {
if (index == _keyColor)
return false;
@@ -218,14 +329,16 @@ bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
return true;
}
- uint8 i1, i2;
- byte *entry = (*_colorMap)[index - 1];
- uint8 cm1 = *(entry);
- entry++;
- //uint8 cm2 = *(entry);
+ if (stipple) {
+ stipple[0] = _stipples[0][index - 1];
+ stipple[1] = _stipples[1][index - 1];
+ stipple[2] = _stipples[2][index - 1];
+ stipple[3] = _stipples[3][index - 1];
+ }
- i1 = getCPCPixel(cm1, 0);
- i2 = getCPCPixel(cm1, 1);
+ byte *entry = (*_colorMap)[index - 1];
+ uint8 i1 = getCPCPixel(entry[0], 0);
+ uint8 i2 = getCPCPixel(entry[0], 1);
selectColorFromFourColorPalette(i1, r1, g1, b1);
selectColorFromFourColorPalette(i2, r2, g2, b2);
return true;
@@ -286,9 +399,9 @@ bool Renderer::getRGBAt(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2,
else if (_renderMode == Common::kRenderC64)
return getRGBAtC64(index, r1, g1, b1, r2, g2, b2);
else if (_renderMode == Common::kRenderCGA)
- return getRGBAtCGA(index, r1, g1, b1, r2, g2, b2);
+ return getRGBAtCGA(index, r1, g1, b1, r2, g2, b2, stipple);
else if (_renderMode == Common::kRenderCPC)
- return getRGBAtCPC(index, r1, g1, b1, r2, g2, b2);
+ return getRGBAtCPC(index, r1, g1, b1, r2, g2, b2, stipple);
else if (_renderMode == Common::kRenderZX)
return getRGBAtZX(index, r1, g1, b1, r2, g2, b2, stipple);
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 867da87b0f0..ff6612ee011 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -101,8 +101,8 @@ public:
uint8 indexFromColor(uint8 r, uint8 g, uint8 b);
bool getRGBAt(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple);
bool getRGBAtC64(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2);
- bool getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2);
- bool getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2);
+ bool getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple);
+ bool getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple);
bool getRGBAtEGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2);
bool getRGBAtZX(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple);
void extractCPCIndexes(uint8 cm1, uint8 cm2, uint8 &i1, uint8 &i2);
@@ -113,12 +113,14 @@ public:
virtual void setStippleData(byte *data) {};
virtual void useStipple(bool enabled) {};
byte *_palette;
+ void setColorMap(ColorMap *colorMap_);
ColorMap *_colorMap;
ColorReMap *_colorRemaps;
int _keyColor;
int _inkColor;
int _paperColor;
int _underFireBackgroundColor;
+ byte _stipples[4][16];
/**
* Select the window where to render
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index e504625b1c4..13f08e5db49 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -285,7 +285,12 @@ void OpenGLRenderer::useStipple(bool enabled) {
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(0.0f, -1.0f);
glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(_renderMode == Common::kRenderZX ? _variableStippleArray : _defaultStippleArray);
+ if (_renderMode == Common::kRenderZX ||
+ _renderMode == Common::kRenderCPC ||
+ _renderMode == Common::kRenderCGA)
+ glPolygonStipple(_variableStippleArray);
+ else
+ glPolygonStipple(_defaultStippleArray);
} else {
glPolygonOffset(0, 0);
glDisable(GL_POLYGON_OFFSET_FILL);
Commit: 3dfd360667ee16a81fe2dcfb9db4431c4d00dda7
https://github.com/scummvm/scummvm/commit/3dfd360667ee16a81fe2dcfb9db4431c4d00dda7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T11:03:06+01:00
Commit Message:
FREESCAPE: improved stipple generation
Changed paths:
engines/freescape/gfx.cpp
engines/freescape/gfx.h
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index ccf83daa9b2..9b9df6ecb5e 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -54,6 +54,7 @@ Renderer::Renderer(int screenW, int screenH, Common::RenderMode renderMode) {
_stipples[1][i] = 0;
_stipples[2][i] = 0;
_stipples[3][i] = 0;
+ _colorPair[i] = 0;
}
}
@@ -126,6 +127,45 @@ byte getCGAStipple(byte x, int back, int fore) {
return st;
}
+void Renderer::fillColorPairArray() {
+ for (int i = 4; i < 15; i++) {
+ byte *entry = (*_colorMap)[i];
+ int c1;
+ if (_renderMode == Common::kRenderCGA)
+ c1 = getCGAPixel(entry[0], 0);
+ else if (_renderMode == Common::kRenderCPC)
+ c1 = getCPCPixel(entry[0], 0);
+ else
+ error("Not implemented");
+
+ //debug("c1 = %d", c1);
+ int c2 = -1;
+
+ for (int j = 0; j < 4; j++) {
+ int k, c;
+ for (k = 0; k < 4; k++) {
+ if (_renderMode == Common::kRenderCGA)
+ c = getCGAPixel(entry[j], k);
+ else if (_renderMode == Common::kRenderCPC)
+ c = getCPCPixel(entry[j], k);
+ else
+ error("Not implemented");
+ //debug("c = %d", c);
+ if (c1 != c) {
+ c2 = c;
+ break;
+ }
+ }
+ if (k != 4)
+ break;
+ }
+ assert(c2 >= 0);
+ assert((c1 < 16) & (c2 < 16));
+ _colorPair[i] = byte(c1) | (byte(c2) << 4);
+ //debug("pair: %x", _colorPair[i]);
+ }
+}
+
void Renderer::setColorMap(ColorMap *colorMap_) {
_colorMap = colorMap_;
if (_renderMode == Common::kRenderZX) {
@@ -137,6 +177,7 @@ void Renderer::setColorMap(ColorMap *colorMap_) {
_stipples[3][i] = entry[3];
}
} else if (_renderMode == Common::kRenderCPC) {
+ fillColorPairArray();
for (int i = 0; i < 15; i++) {
byte *entry = (*_colorMap)[i];
int i1 = getCPCPixel(entry[0], 0);
@@ -147,14 +188,16 @@ void Renderer::setColorMap(ColorMap *colorMap_) {
_stipples[3][i] = getCPCStipple(entry[3], i1, i2);
}
} else if (_renderMode == Common::kRenderCGA) {
- for (int i = 0; i < 15; i++) {
+ fillColorPairArray();
+ for (int i = 4; i < 15; i++) {
byte *entry = (*_colorMap)[i];
- int i1 = getCGAPixel(entry[0], 0);
- int i2 = getCGAPixel(entry[0], 1);
- _stipples[0][i] = getCGAStipple(entry[0], i1, i2);
- _stipples[1][i] = getCGAStipple(entry[1], i1, i2);
- _stipples[2][i] = getCGAStipple(entry[2], i1, i2);
- _stipples[3][i] = getCGAStipple(entry[3], i1, i2);
+ byte pair = _colorPair[i];
+ byte c1 = pair & 0xf;
+ byte c2 = (pair >> 4) & 0xf;
+ _stipples[0][i] = getCGAStipple(entry[0], c1, c2);
+ _stipples[1][i] = getCGAStipple(entry[1], c1, c2);
+ _stipples[2][i] = getCGAStipple(entry[2], c1, c2);
+ _stipples[3][i] = getCGAStipple(entry[3], c1, c2);
}
}
}
@@ -198,9 +241,9 @@ bool Renderer::getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
stipple[3] = _stipples[3][index - 1];
}
- byte *entry = (*_colorMap)[index - 1];
- uint8 c1 = getCGAPixel(entry[0], 0);
- uint8 c2 = getCGAPixel(entry[0], 1);
+ byte pair = _colorPair[index - 1];
+ byte c1 = pair & 0xf;
+ byte c2 = (pair >> 4) & 0xf;
readFromPalette(c1, r1, g1, b1);
readFromPalette(c2, r2, g2, b2);
return true;
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index ff6612ee011..8c948e05068 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -116,6 +116,8 @@ public:
void setColorMap(ColorMap *colorMap_);
ColorMap *_colorMap;
ColorReMap *_colorRemaps;
+ void fillColorPairArray();
+ byte _colorPair[16];
int _keyColor;
int _inkColor;
int _paperColor;
Commit: e6b033b40963182b9dd0b37364c38be98c5d228f
https://github.com/scummvm/scummvm/commit/e6b033b40963182b9dd0b37364c38be98c5d228f
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T11:03:12+01:00
Commit Message:
FREESCAPE: improved and optimized stipple pattern usage
Changed paths:
engines/freescape/gfx.cpp
engines/freescape/gfx.h
engines/freescape/gfx_opengl.cpp
engines/freescape/gfx_opengl.h
engines/freescape/gfx_tinygl.cpp
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 9b9df6ecb5e..8d5e2721cfd 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -50,10 +50,9 @@ Renderer::Renderer(int screenW, int screenH, Common::RenderMode renderMode) {
_isAccelerated = false;
for (int i = 0; i < 16; i++) {
- _stipples[0][i] = 0;
- _stipples[1][i] = 0;
- _stipples[2][i] = 0;
- _stipples[3][i] = 0;
+ for (int j = 0; j < 128; j++) {
+ _stipples[i][j] = 0;
+ }
_colorPair[i] = 0;
}
}
@@ -77,13 +76,13 @@ byte getCPCStipple(byte cpc_byte, int back, int fore) {
st = st | 0x3;
if (c1 == fore)
- st = st | (2 << 0x3);
+ st = st | (0x3 << 2);
if (c2 == fore)
- st = st | (4 << 0x3);
+ st = st | (0x3 << 4);
if (c3 == fore)
- st = st | (6 << 0x3);
+ st = st | (0x3 << 6);
return st;
}
@@ -116,13 +115,13 @@ byte getCGAStipple(byte x, int back, int fore) {
st = st | 0x3;
if (c1 == fore)
- st = st | (2 << 0x3);
+ st = st | (0x3 << 2);
if (c2 == fore)
- st = st | (4 << 0x3);
+ st = st | (0x3 << 4);
if (c3 == fore)
- st = st | (6 << 0x3);
+ st = st | (0x3 << 6);
return st;
}
@@ -138,7 +137,6 @@ void Renderer::fillColorPairArray() {
else
error("Not implemented");
- //debug("c1 = %d", c1);
int c2 = -1;
for (int j = 0; j < 4; j++) {
@@ -150,7 +148,6 @@ void Renderer::fillColorPairArray() {
c = getCPCPixel(entry[j], k);
else
error("Not implemented");
- //debug("c = %d", c);
if (c1 != c) {
c2 = c;
break;
@@ -162,7 +159,6 @@ void Renderer::fillColorPairArray() {
assert(c2 >= 0);
assert((c1 < 16) & (c2 < 16));
_colorPair[i] = byte(c1) | (byte(c2) << 4);
- //debug("pair: %x", _colorPair[i]);
}
}
@@ -171,33 +167,28 @@ void Renderer::setColorMap(ColorMap *colorMap_) {
if (_renderMode == Common::kRenderZX) {
for (int i = 0; i < 15; i++) {
byte *entry = (*_colorMap)[i];
- _stipples[0][i] = entry[0];
- _stipples[1][i] = entry[1];
- _stipples[2][i] = entry[2];
- _stipples[3][i] = entry[3];
+ for (int j = 0; j < 128; j++)
+ _stipples[i][j] = entry[(j / 16) % 4];
}
} else if (_renderMode == Common::kRenderCPC) {
fillColorPairArray();
- for (int i = 0; i < 15; i++) {
+ for (int i = 4; i < 15; i++) {
+ byte pair = _colorPair[i];
+ byte c1 = pair & 0xf;
+ byte c2 = (pair >> 4) & 0xf;
byte *entry = (*_colorMap)[i];
- int i1 = getCPCPixel(entry[0], 0);
- int i2 = getCPCPixel(entry[0], 1);
- _stipples[0][i] = getCPCStipple(entry[0], i1, i2);
- _stipples[1][i] = getCPCStipple(entry[1], i1, i2);
- _stipples[2][i] = getCPCStipple(entry[2], i1, i2);
- _stipples[3][i] = getCPCStipple(entry[3], i1, i2);
+ for (int j = 0; j < 128; j++)
+ _stipples[i][j] = getCPCStipple(entry[(j / 8) % 4], c1, c2) ;
}
} else if (_renderMode == Common::kRenderCGA) {
fillColorPairArray();
for (int i = 4; i < 15; i++) {
- byte *entry = (*_colorMap)[i];
byte pair = _colorPair[i];
byte c1 = pair & 0xf;
byte c2 = (pair >> 4) & 0xf;
- _stipples[0][i] = getCGAStipple(entry[0], c1, c2);
- _stipples[1][i] = getCGAStipple(entry[1], c1, c2);
- _stipples[2][i] = getCGAStipple(entry[2], c1, c2);
- _stipples[3][i] = getCGAStipple(entry[3], c1, c2);
+ byte *entry = (*_colorMap)[i];
+ for (int j = 0; j < 128; j++)
+ _stipples[i][j] = getCGAStipple(entry[(j / 8) % 4], c1, c2) ;
}
}
}
@@ -221,7 +212,7 @@ void Renderer::setColorRemaps(ColorReMap *colorRemaps) {
_colorRemaps = colorRemaps;
}
-bool Renderer::getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple) {
+bool Renderer::getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *&stipple) {
if (index == _keyColor)
return false;
@@ -234,13 +225,7 @@ bool Renderer::getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
return true;
}
- if (stipple) {
- stipple[0] = _stipples[0][index - 1];
- stipple[1] = _stipples[1][index - 1];
- stipple[2] = _stipples[2][index - 1];
- stipple[3] = _stipples[3][index - 1];
- }
-
+ stipple = (byte *)_stipples[index - 1];
byte pair = _colorPair[index - 1];
byte c1 = pair & 0xf;
byte c2 = (pair >> 4) & 0xf;
@@ -315,7 +300,7 @@ bool Renderer::getRGBAtC64(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
return true;
}
-bool Renderer::getRGBAtZX(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple) {
+bool Renderer::getRGBAtZX(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *&stipple) {
if (index == _keyColor)
return false;
@@ -332,12 +317,7 @@ bool Renderer::getRGBAtZX(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r
return true;
}
- if (stipple) {
- stipple[0] = _stipples[0][index - 1];
- stipple[1] = _stipples[1][index - 1];
- stipple[2] = _stipples[2][index - 1];
- stipple[3] = _stipples[3][index - 1];
- }
+ stipple = (byte *)_stipples[index - 1];
readFromPalette(_paperColor, r1, g1, b1);
readFromPalette(_inkColor, r2, g2, b2);
@@ -359,7 +339,7 @@ void Renderer::selectColorFromFourColorPalette(uint8 index, uint8 &r1, uint8 &g1
error("Invalid color");
}
-bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple) {
+bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *&stipple) {
if (index == _keyColor)
return false;
@@ -372,13 +352,7 @@ bool Renderer::getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
return true;
}
- if (stipple) {
- stipple[0] = _stipples[0][index - 1];
- stipple[1] = _stipples[1][index - 1];
- stipple[2] = _stipples[2][index - 1];
- stipple[3] = _stipples[3][index - 1];
- }
-
+ stipple = (byte *)_stipples[index - 1];
byte *entry = (*_colorMap)[index - 1];
uint8 i1 = getCPCPixel(entry[0], 0);
uint8 i2 = getCPCPixel(entry[0], 1);
@@ -409,7 +383,7 @@ bool Renderer::getRGBAtEGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &
return true;
}
-bool Renderer::getRGBAt(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple) {
+bool Renderer::getRGBAt(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *&stipple) {
if (_colorRemaps && _colorRemaps->contains(index)) {
index = (*_colorRemaps)[index];
@@ -591,10 +565,10 @@ void Renderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d
}
Common::Array<Math::Vector3d> face;
- uint32 stipple = 0;
+ byte *stipple = nullptr;
uint8 r1, g1, b1, r2, g2, b2;
- if (getRGBAt((*colours)[0], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[0], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
face.push_back(vertices[4]);
@@ -614,8 +588,8 @@ void Renderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d
face.clear();
}
- if (getRGBAt((*colours)[1], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[1], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
face.push_back(vertices[5]);
@@ -634,8 +608,8 @@ void Renderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d
face.clear();
}
- if (getRGBAt((*colours)[2], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[2], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
face.push_back(vertices[6]);
@@ -653,8 +627,8 @@ void Renderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d
face.clear();
}
- if (getRGBAt((*colours)[3], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[3], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
face.push_back(vertices[7]);
@@ -673,8 +647,8 @@ void Renderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d
face.clear();
}
- if (getRGBAt((*colours)[4], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[4], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
face.push_back(vertices[0]);
@@ -692,8 +666,8 @@ void Renderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d
face.clear();
}
- if (getRGBAt((*colours)[5], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[5], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
face.push_back(vertices[7]);
@@ -711,12 +685,12 @@ void Renderer::renderPyramid(const Math::Vector3d &origin, const Math::Vector3d
}
void Renderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &size, Common::Array<uint8> *colours) {
- uint32 stipple = 0;
+ byte *stipple = nullptr;
uint8 r1, g1, b1, r2, g2, b2;
Common::Array<Math::Vector3d> face;
- if (getRGBAt((*colours)[0], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[0], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
face.push_back(origin);
face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z() + size.z()));
@@ -731,8 +705,8 @@ void Renderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &si
}
}
- if (getRGBAt((*colours)[1], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[1], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
face.clear();
face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y() + size.y(), origin.z()));
@@ -748,8 +722,8 @@ void Renderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &si
}
}
- if (getRGBAt((*colours)[2], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[2], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
face.clear();
face.push_back(Math::Vector3d(origin.x() + size.x(), origin.y(), origin.z()));
@@ -765,8 +739,8 @@ void Renderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &si
}
}
- if (getRGBAt((*colours)[3], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[3], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
face.clear();
face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z()));
@@ -782,8 +756,8 @@ void Renderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &si
}
}
- if (getRGBAt((*colours)[4], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[4], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
face.clear();
face.push_back(Math::Vector3d(origin.x(), origin.y() + size.y(), origin.z()));
@@ -799,8 +773,8 @@ void Renderer::renderCube(const Math::Vector3d &origin, const Math::Vector3d &si
}
}
- if (getRGBAt((*colours)[5], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[5], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
face.clear();
face.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z() + size.z()));
@@ -824,13 +798,13 @@ void Renderer::renderRectangle(const Math::Vector3d &origin, const Math::Vector3
float dx, dy, dz;
uint8 r1, g1, b1, r2, g2, b2;
- uint32 stipple = 0;
+ byte *stipple = nullptr;
Common::Array<Math::Vector3d> vertices;
for (int i = 0; i < 2; i++) {
// debug("rec color: %d", (*colours)[i]);
- if (getRGBAt((*colours)[i], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[i], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
vertices.clear();
vertices.push_back(Math::Vector3d(origin.x(), origin.y(), origin.z()));
@@ -882,7 +856,7 @@ void Renderer::renderRectangle(const Math::Vector3d &origin, const Math::Vector3
void Renderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d &size, const Common::Array<uint16> *ordinates, Common::Array<uint8> *colours) {
uint8 r1, g1, b1, r2, g2, b2;
- uint32 stipple = 0;
+ byte *stipple = nullptr;
if (ordinates->size() % 3 > 0 && ordinates->size() > 0)
error("Invalid polygon with size %f %f %f and ordinates %d", size.x(), size.y(), size.z(), ordinates->size());
@@ -890,8 +864,8 @@ void Renderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d
polygonOffset(true);
if (ordinates->size() == 6) { // Line
- assert(getRGBAt((*colours)[0], r1, g1, b1, r2, g2, b2, (byte *)&stipple)); // It will never return false?
- setStippleData((byte *)&stipple);
+ assert(getRGBAt((*colours)[0], r1, g1, b1, r2, g2, b2, stipple)); // It will never return false?
+ setStippleData(stipple);
useColor(r1, g1, b1);
for (uint i = 0; i < ordinates->size(); i = i + 3)
vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
@@ -904,8 +878,8 @@ void Renderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d
}
vertices.clear();
- assert(getRGBAt((*colours)[1], r1, g1, b1, r2, g2, b2, (byte *)&stipple)); // It will never return false?
- setStippleData((byte *)&stipple);
+ assert(getRGBAt((*colours)[1], r1, g1, b1, r2, g2, b2, stipple)); // It will never return false?
+ setStippleData(stipple);
useColor(r1, g1, b1);
for (int i = ordinates->size(); i > 0; i = i - 3)
vertices.push_back(Math::Vector3d((*ordinates)[i - 3], (*ordinates)[i - 2], (*ordinates)[i - 1]));
@@ -918,8 +892,8 @@ void Renderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d
}
} else {
- if (getRGBAt((*colours)[0], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[0], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
for (uint i = 0; i < ordinates->size(); i = i + 3) {
vertices.push_back(Math::Vector3d((*ordinates)[i], (*ordinates)[i + 1], (*ordinates)[i + 2]));
@@ -933,8 +907,8 @@ void Renderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d
}
}
vertices.clear();
- if (getRGBAt((*colours)[1], r1, g1, b1, r2, g2, b2, (byte *)&stipple)) {
- setStippleData((byte *)&stipple);
+ if (getRGBAt((*colours)[1], r1, g1, b1, r2, g2, b2, stipple)) {
+ setStippleData(stipple);
useColor(r1, g1, b1);
for (int i = ordinates->size(); i > 0; i = i - 3) {
vertices.push_back(Math::Vector3d((*ordinates)[i - 3], (*ordinates)[i - 2], (*ordinates)[i - 1]));
diff --git a/engines/freescape/gfx.h b/engines/freescape/gfx.h
index 8c948e05068..6bae31840c9 100644
--- a/engines/freescape/gfx.h
+++ b/engines/freescape/gfx.h
@@ -99,12 +99,12 @@ public:
// palette
void readFromPalette(uint8 index, uint8 &r, uint8 &g, uint8 &b);
uint8 indexFromColor(uint8 r, uint8 g, uint8 b);
- bool getRGBAt(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple);
+ bool getRGBAt(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *&stipple);
bool getRGBAtC64(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2);
- bool getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple);
- bool getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple);
+ bool getRGBAtCGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *&stipple);
+ bool getRGBAtCPC(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *&stipple);
bool getRGBAtEGA(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2);
- bool getRGBAtZX(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *stipple);
+ bool getRGBAtZX(uint8 index, uint8 &r1, uint8 &g1, uint8 &b1, uint8 &r2, uint8 &g2, uint8 &b2, byte *&stipple);
void extractCPCIndexes(uint8 cm1, uint8 cm2, uint8 &i1, uint8 &i2);
void extractC64Indexes(uint8 cm1, uint8 cm2, uint8 &i1, uint8 &i2);
@@ -122,7 +122,7 @@ public:
int _inkColor;
int _paperColor;
int _underFireBackgroundColor;
- byte _stipples[4][16];
+ byte _stipples[16][128];
/**
* Select the window where to render
diff --git a/engines/freescape/gfx_opengl.cpp b/engines/freescape/gfx_opengl.cpp
index 13f08e5db49..2848f48e9fb 100644
--- a/engines/freescape/gfx_opengl.cpp
+++ b/engines/freescape/gfx_opengl.cpp
@@ -42,6 +42,7 @@ OpenGLRenderer::OpenGLRenderer(int screenW, int screenH, Common::RenderMode rend
_coords = (Coord *)malloc(sizeof(Coord) * kCoordsArraySize);
_texturePixelFormat = OpenGLTexture::getRGBAPixelFormat();
_isAccelerated = true;
+ _variableStippleArray = nullptr;
}
OpenGLRenderer::~OpenGLRenderer() {
@@ -276,8 +277,9 @@ void OpenGLRenderer::setStippleData(byte *data) {
if (!data)
return;
- for (int i = 0; i < 128; i++)
- _variableStippleArray[i] = data[(i / 16) % 4];
+ _variableStippleArray = data;
+ //for (int i = 0; i < 128; i++)
+ // _variableStippleArray[i] = data[(i / 16) % 4];
}
void OpenGLRenderer::useStipple(bool enabled) {
@@ -316,8 +318,8 @@ void OpenGLRenderer::clear(uint8 color) {
void OpenGLRenderer::drawFloor(uint8 color) {
uint8 r1, g1, b1, r2, g2, b2;
- uint32 stipple = 0;
- assert(getRGBAt(color, r1, g1, b1, r2, g2, b2, (byte *)&stipple)); // TODO: move check inside this function
+ byte *stipple;
+ assert(getRGBAt(color, r1, g1, b1, r2, g2, b2, stipple)); // TODO: move check inside this function
glColor3ub(r1, g1, b1);
glEnableClientState(GL_VERTEX_ARRAY);
diff --git a/engines/freescape/gfx_opengl.h b/engines/freescape/gfx_opengl.h
index cc9536eac79..a3925a8d4ba 100644
--- a/engines/freescape/gfx_opengl.h
+++ b/engines/freescape/gfx_opengl.h
@@ -79,24 +79,7 @@ public:
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
};
- GLubyte _variableStippleArray[128] = {
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- };
+ GLubyte *_variableStippleArray;
virtual void init() override;
virtual void clear(uint8 color) override;
diff --git a/engines/freescape/gfx_tinygl.cpp b/engines/freescape/gfx_tinygl.cpp
index 15456f24118..ad1c0f62195 100644
--- a/engines/freescape/gfx_tinygl.cpp
+++ b/engines/freescape/gfx_tinygl.cpp
@@ -227,7 +227,8 @@ void TinyGLRenderer::clear(uint8 color) {
void TinyGLRenderer::drawFloor(uint8 color) {
uint8 r1, g1, b1, r2, g2, b2;
- assert(getRGBAt(color, r1, g1, b1, r2, g2, b2, nullptr)); // TODO: move check inside this function
+ byte *stipple = nullptr;
+ assert(getRGBAt(color, r1, g1, b1, r2, g2, b2, stipple)); // TODO: move check inside this function
tglColor3ub(r1, g1, b1);
tglEnableClientState(TGL_VERTEX_ARRAY);
Commit: 59cae6551a7174d06905fcfc68e0412d53effcfa
https://github.com/scummvm/scummvm/commit/59cae6551a7174d06905fcfc68e0412d53effcfa
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T11:04:57+01:00
Commit Message:
FREESCAPE: avoid crash selecting a missing palette in driller demo for amiga/atari
Changed paths:
engines/freescape/games/palettes.cpp
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 00e626fb653..2947a6c6268 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -209,9 +209,13 @@ byte kDrillerCGAPaletteRedGreenData[4][3] = {
};
void FreescapeEngine::swapPalette(uint16 levelID) {
- if (isAmiga() || isAtariST())
+ if (isAmiga() || isAtariST()) {
+ // The following palette was not available in the demo, so we select another one
+ if (isDemo() && levelID == 32)
+ levelID = 31;
+
_gfx->_palette = _paletteByArea[levelID];
- else if (isSpectrum() || isCPC() || isC64()) {
+ } else if (isSpectrum() || isCPC() || isC64()) {
_gfx->_inkColor = _areaMap[levelID]->_inkColor;
_gfx->_paperColor = _areaMap[levelID]->_paperColor;
_gfx->_underFireBackgroundColor = _areaMap[levelID]->_underFireBackgroundColor;
Commit: 8b1448d70dc765eb2d2370f17ff16752b2fc5f3e
https://github.com/scummvm/scummvm/commit/8b1448d70dc765eb2d2370f17ff16752b2fc5f3e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-03-20T11:05:07+01:00
Commit Message:
FREESCAPE: disallow crossair to be outside the view area
Changed paths:
engines/freescape/freescape.cpp
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index c39ed86ade4..50df8756748 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -433,6 +433,8 @@ void FreescapeEngine::processInput() {
} else {
g_system->lockMouse(false);
g_system->warpMouse(_crossairPosition.x, _crossairPosition.y);
+ g_system->getEventManager()->purgeMouseEvents();
+ g_system->getEventManager()->purgeKeyboardEvents();
}
break;
case Common::KEYCODE_i:
@@ -462,15 +464,34 @@ void FreescapeEngine::processInput() {
g_system->warpMouse(mousePos.x, mousePos.y);
if (_shootMode) {
- _crossairPosition = mousePos;
- if (mousePos.x < _viewArea.left)
- g_system->warpMouse(_viewArea.left + 1, _crossairPosition.y);
- else if (mousePos.x > _viewArea.right)
- g_system->warpMouse(_viewArea.right - 1, _crossairPosition.y);
- else if (mousePos.y < _viewArea.top)
- g_system->warpMouse(_crossairPosition.x, _viewArea.top + 1);
- else if (mousePos.y > _viewArea.bottom)
- g_system->warpMouse(_crossairPosition.x, _viewArea.bottom - 1);
+ {
+ bool shouldWarp = false;
+ _crossairPosition = mousePos;
+ if (mousePos.x < _viewArea.left) {
+ _crossairPosition.x = _viewArea.left + 1;
+ shouldWarp = true;
+ }
+
+ if (mousePos.x > _viewArea.right) {
+ _crossairPosition.x = _viewArea.right - 1;
+ shouldWarp = true;
+ }
+ if (mousePos.y < _viewArea.top) {
+ _crossairPosition.y = _viewArea.top + 1;
+ shouldWarp = true;
+ }
+
+ if (mousePos.y > _viewArea.bottom) {
+ _crossairPosition.y = _viewArea.bottom - 1;
+ shouldWarp = true;
+ }
+
+ if (shouldWarp) {
+ g_system->warpMouse(_crossairPosition.x, _crossairPosition.y);
+ g_system->getEventManager()->purgeMouseEvents();
+ g_system->getEventManager()->purgeKeyboardEvents();
+ }
+ }
break;
}
More information about the Scummvm-git-logs
mailing list