aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devtools/create_mortdat/create_mortdat.cpp6
-rw-r--r--dists/engine-data/mort.datbin736 -> 738 bytes
-rw-r--r--engines/mortevielle/mortevielle.cpp136
-rw-r--r--engines/mortevielle/mortevielle.h22
-rw-r--r--engines/mortevielle/mouse.cpp3
-rw-r--r--engines/mortevielle/ovd1.cpp2
-rw-r--r--engines/mortevielle/sprint.cpp4
-rw-r--r--engines/mortevielle/var_mor.cpp20
-rw-r--r--engines/mortevielle/var_mor.h3
9 files changed, 182 insertions, 14 deletions
diff --git a/devtools/create_mortdat/create_mortdat.cpp b/devtools/create_mortdat/create_mortdat.cpp
index 62b81806bc..aa7da0169a 100644
--- a/devtools/create_mortdat/create_mortdat.cpp
+++ b/devtools/create_mortdat/create_mortdat.cpp
@@ -107,7 +107,7 @@ void openOutputFile(const char *outFilename) {
outputFile.open(outFilename, kFileWriteMode);
// Write header
- outputFile.write("mort", 4);
+ outputFile.write("MORT", 4);
outputFile.writeByte(VERSION_MAJOR);
outputFile.writeByte(VERSION_MINOR);
}
@@ -132,7 +132,9 @@ void process() {
// Write out a section header to the output file and the font data
char fontHeader[4] = { 'F', 'O', 'N', 'T' };
- outputFile.write(fontHeader, 4);
+ outputFile.write(fontHeader, 4); // Section Id
+ outputFile.writeWord(121 * 6); // Section size
+
outputFile.write(fontBuffer, 121 * 6);
}
diff --git a/dists/engine-data/mort.dat b/dists/engine-data/mort.dat
index ce4e5bb1c8..ebfb8a8e0e 100644
--- a/dists/engine-data/mort.dat
+++ b/dists/engine-data/mort.dat
Binary files differ
diff --git a/engines/mortevielle/mortevielle.cpp b/engines/mortevielle/mortevielle.cpp
index 68b8dbeeb4..43534a6ae0 100644
--- a/engines/mortevielle/mortevielle.cpp
+++ b/engines/mortevielle/mortevielle.cpp
@@ -20,14 +20,22 @@
*
*/
+#include "common/system.h"
#include "engines/util.h"
+#include "engines/engine.h"
+#include "graphics/palette.h"
+#include "graphics/pixelformat.h"
#include "mortevielle/mortevielle.h"
#include "mortevielle/mort.h"
+#include "mortevielle/var_mor.h"
namespace Mortevielle {
+MortevielleEngine *g_vm;
+
MortevielleEngine::MortevielleEngine(OSystem *system, const ADGameDescription *gameDesc):
Engine(system), _gameDescription(gameDesc) {
+ g_vm = this;
}
MortevielleEngine::~MortevielleEngine() {
@@ -37,10 +45,136 @@ bool MortevielleEngine::hasFeature(EngineFeature f) const {
return false;
}
-Common::Error MortevielleEngine::run() {
+Common::ErrorCode MortevielleEngine::initialise() {
// Initialise graphics mode
initGraphics(SCREEN_WIDTH, SCREEN_HEIGHT, true);
+ // Set up an intermediate screen surface
+ _screenSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8());
+
+ // Set the screen mode
+ gd = ega;
+ res = 2;
+
+ // Load the mort.dat resource
+ return loadMortDat();
+}
+
+/**
+ * Loads the contents of the Mort.dat data file
+ */
+Common::ErrorCode MortevielleEngine::loadMortDat() {
+ Common::File f;
+
+ // Open the mort.dat file
+ if (!f.open(MORT_DAT)) {
+ GUIErrorMessage("Could not locate Mort.dat file");
+ return Common::kReadingFailed;
+ }
+
+ // Validate the data file header
+ char fileId[4];
+ f.read(fileId, 4);
+ if (strncmp(fileId, "MORT", 4) != 0) {
+ GUIErrorMessage("The located mort.dat data file is invalid");
+ return Common::kReadingFailed;
+ }
+
+ // Check the version
+ if (f.readByte() < MORT_DAT_REQUIRED_VERSION) {
+ GUIErrorMessage("The located mort.dat data file is too a version");
+ return Common::kReadingFailed;
+ }
+ f.readByte(); // Minor version
+
+ // Loop to load resources from the data file
+ while (f.pos() < f.size()) {
+ // Get the Id and size of the next resource
+ char dataType[4];
+ int dataSize;
+ f.read(dataType, 4);
+ dataSize = f.readUint16LE();
+
+ if (!strncmp(dataType, "FONT", 4)) {
+ // Font resource
+ assert(dataSize == (FONT_NUM_CHARS * FONT_HEIGHT));
+ f.read(_fontData, FONT_NUM_CHARS * FONT_HEIGHT);
+ } else {
+ // Unknown section
+ f.skip(dataSize);
+ }
+ }
+
+ f.close();
+ return Common::kNoError;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * Update the physical screen
+ */
+void MortevielleEngine::updateScreen() {
+ g_system->copyRectToScreen((const byte *)_screenSurface.getBasePtr(0, 0),
+ SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+ g_system->updateScreen();
+}
+/**
+ * Draws a character at the specified co-ordinates
+ * @remarks Because the ScummVM surface is using a double height 640x200 surface to
+ * simulate the original 640x200 surface, all Y values have to be doubled
+ */
+void MortevielleEngine::writeCharacter(const Common::Point &pt, unsigned char ch,
+ int palIndex, Graphics::Surface *surface) {
+ if (surface == NULL)
+ surface = &_screenSurface;
+
+ // Get the start of the character to use
+ assert((ch >= ' ') && (ch <= (unsigned char)(32 + FONT_NUM_CHARS)));
+ const byte *charData = &_fontData[((int)ch - 32) * FONT_HEIGHT];
+
+ // Loop through decoding each character's data
+ for (int yp = 0; yp < FONT_HEIGHT; ++yp) {
+ byte *lineP = (byte *)surface->getBasePtr(pt.x, (pt.y + yp) * 2);
+ byte byteVal = *charData++;
+
+ for (int xp = 0; xp < 8; ++xp, ++lineP, byteVal <<= 1) {
+ if (byteVal & 0x80) {
+ *lineP = palIndex;
+ *(lineP + SCREEN_WIDTH) = palIndex;
+ }
+ }
+ }
+}
+
+/**
+ * Sets a single pixel at the specified co-ordinates
+ * @remarks Because the ScummVM surface is using a double height 640x200 surface to
+ * simulate the original 640x200 surface, all Y values have to be doubled
+ */
+void MortevielleEngine::setPixel(const Common::Point &pt, int palIndex,
+ Graphics::Surface *surface) {
+ if (surface == NULL)
+ surface = &_screenSurface;
+
+ byte *destP = (byte *)surface->getBasePtr(pt.x, pt.y * 2);
+ *destP = palIndex;
+ *(destP + SCREEN_WIDTH) = palIndex;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+Common::Error MortevielleEngine::run() {
+ // Initialise the game
+ Common::ErrorCode err = initialise();
+ if (err != Common::kNoError)
+ return err;
+
+ // TODO: Remove once palette loading is correctly done
+ uint32 white = 0xffffffff;
+ g_system->getPaletteManager()->setPalette((const byte *)&white, 15, 1);
+
// Dispatch to the game's main routine
const char *argv[] = { "" };
mortevielle_main(1, argv);
diff --git a/engines/mortevielle/mortevielle.h b/engines/mortevielle/mortevielle.h
index 14bee28a03..b9d8265385 100644
--- a/engines/mortevielle/mortevielle.h
+++ b/engines/mortevielle/mortevielle.h
@@ -23,9 +23,12 @@
#ifndef MORTEVIELLE_H
#define MORTEVIELLE_H
+#include "common/file.h"
+#include "common/rect.h"
#include "engines/advancedDetector.h"
#include "engines/engine.h"
#include "common/error.h"
+#include "graphics/surface.h"
namespace Mortevielle {
@@ -35,17 +38,34 @@ enum {
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 400
+#define MORT_DAT_REQUIRED_VERSION 1
+#define MORT_DAT "mort.dat"
+
+#define FONT_WIDTH 8
+#define FONT_HEIGHT 6
+#define FONT_NUM_CHARS 121
class MortevielleEngine : public Engine {
private:
const ADGameDescription *_gameDescription;
+
+ Common::ErrorCode initialise();
+ Common::ErrorCode loadMortDat();
+ void loadFont(Common::File &f);
+public:
+ Graphics::Surface _screenSurface;
+ byte _fontData[FONT_NUM_CHARS * FONT_HEIGHT];
public:
MortevielleEngine(OSystem *system, const ADGameDescription *gameDesc);
~MortevielleEngine();
virtual bool hasFeature(EngineFeature f) const;
virtual Common::Error run();
-
uint32 getGameFlags() const;
+
+ void updateScreen();
+ void writeCharacter(const Common::Point &pt,
+ unsigned char ch, int palIndex, Graphics::Surface *surface = NULL);
+ void setPixel(const Common::Point &pt, int palIndex, Graphics::Surface *surface = NULL);
};
extern MortevielleEngine *g_vm;
diff --git a/engines/mortevielle/mouse.cpp b/engines/mortevielle/mouse.cpp
index 1aaea06d68..d78b458816 100644
--- a/engines/mortevielle/mouse.cpp
+++ b/engines/mortevielle/mouse.cpp
@@ -25,6 +25,7 @@
* Copyright (c) 1988-1989 Lankhor
*/
+#include "common/rect.h"
#include "mortevielle/mouse.h"
#include "mortevielle/var_mor.h"
@@ -256,7 +257,7 @@ void show_mouse() {
}
break;
} /* case Gd */
- affput(2, gd, x_s, y_s, 0, 0);
+ affput(Common::Point(x_s, y_s), 0, 0);
}
void pos_mouse(int x, int y) {
diff --git a/engines/mortevielle/ovd1.cpp b/engines/mortevielle/ovd1.cpp
index a1a47a2913..3aa942c7e2 100644
--- a/engines/mortevielle/ovd1.cpp
+++ b/engines/mortevielle/ovd1.cpp
@@ -275,8 +275,6 @@ void ani50() {
gd = tan;
break;
}*/
- // Hardcode display mode to EGA
- gd = ega;
gotoxy(1, 24);
clreol;
diff --git a/engines/mortevielle/sprint.cpp b/engines/mortevielle/sprint.cpp
index e6a172b821..67bd3ab119 100644
--- a/engines/mortevielle/sprint.cpp
+++ b/engines/mortevielle/sprint.cpp
@@ -27,6 +27,7 @@
#include "common/str.h"
#include "common/textconsole.h"
+#include "mortevielle/mortevielle.h"
#include "mortevielle/mouse.h"
#include "mortevielle/sprint.h"
#include "mortevielle/var_mor.h"
@@ -85,6 +86,9 @@ void writeg(Common::String l, int c)
xo = xo + i;
}
show_mouse();
+
+ // TODO: Move screen updates to main loop once constructed
+ g_vm->updateScreen();
}
} // End of namespace Mortevielle
diff --git a/engines/mortevielle/var_mor.cpp b/engines/mortevielle/var_mor.cpp
index a8b10c1201..e07a7359ac 100644
--- a/engines/mortevielle/var_mor.cpp
+++ b/engines/mortevielle/var_mor.cpp
@@ -28,6 +28,7 @@
#include "common/debug.h"
#include "common/str.h"
#include "common/textconsole.h"
+#include "mortevielle/mortevielle.h"
#include "mortevielle/sprint.h"
#include "mortevielle/var_mor.h"
@@ -306,18 +307,25 @@ void hirs() {
*/
}
-/* procedure affput(Chx,Gd,x,y,coul,char:int); external 'c:\mc\divaf.com'; */
-void affput(int Chx, int Gd, int x, int y, int coul, int char_) {
- warning("TODO: Implement affput");
+/**
+ * Draws either a single pixel or a character to the screen
+ */
+void affput(const Common::Point &pt, int palIndex, int ch) {
+ if (ch == 0)
+ g_vm->setPixel(pt, palIndex);
+ else
+ g_vm->writeCharacter(pt, ch, palIndex);
}
void affcar(int gd, int x, int y, int coul, int chr) {
- if (res == 1) affput(1, gd, ((uint)x >> 1), y, coul, chr);
- else affput(1, gd, x, y, coul, chr);
+ if (res == 1)
+ affput(Common::Point(((uint)x >> 1), y), coul, chr);
+ else
+ affput(Common::Point(x, y), coul, chr);
}
void putpix(int gd, int x, int y, int coul) {
- affput(0, gd, x, y, coul, 0);
+ affput(Common::Point(x, y), coul, 0);
}
/**
diff --git a/engines/mortevielle/var_mor.h b/engines/mortevielle/var_mor.h
index 63d3112760..f9c29e20f6 100644
--- a/engines/mortevielle/var_mor.h
+++ b/engines/mortevielle/var_mor.h
@@ -28,6 +28,7 @@
#ifndef MORTEVIELLE_VAR_H
#define MORTEVIELLE_VAR_H
+#include "common/rect.h"
#include "common/str.h"
namespace Mortevielle {
@@ -396,7 +397,7 @@ void affcar(int gd, int x, int y, int coul, int chr);
void putpix(int gd, int x, int y, int coul);
Common::String copy(const Common::String &s, int idx, size_t size);
void Val(const Common::String &s, int &V, int Code);
-void affput(int Chx, int Gd, int x, int y, int coul, int char_);
+void affput(const Common::Point &pt, int palIndex, int ch);
/*---------------------------------------------------------------------------*/
/*------------------------------ STUBS ------------------------------*/