mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-24 11:36:22 +00:00
MORTEVIELLE: Implemented loading of the font data, and rewrote drawing routines to use it.
This commit is contained in:
parent
60f287c85d
commit
1727798a8e
@ -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);
|
||||
}
|
||||
|
||||
|
Binary file not shown.
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -275,8 +275,6 @@ void ani50() {
|
||||
gd = tan;
|
||||
break;
|
||||
}*/
|
||||
// Hardcode display mode to EGA
|
||||
gd = ega;
|
||||
|
||||
gotoxy(1, 24);
|
||||
clreol;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 ------------------------------*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user