[Scummvm-cvs-logs] SF.net SVN: scummvm: [31416] scummvm/trunk/engines/parallaction
Kirben at users.sourceforge.net
Kirben at users.sourceforge.net
Sun Apr 6 09:05:57 CEST 2008
Revision: 31416
http://scummvm.svn.sourceforge.net/scummvm/?rev=31416&view=rev
Author: Kirben
Date: 2008-04-06 00:05:56 -0700 (Sun, 06 Apr 2008)
Log Message:
-----------
Add very basic support for Amiga version of BRA.
Modified Paths:
--------------
scummvm/trunk/engines/parallaction/detection.cpp
scummvm/trunk/engines/parallaction/disk.h
scummvm/trunk/engines/parallaction/disk_br.cpp
scummvm/trunk/engines/parallaction/font.cpp
scummvm/trunk/engines/parallaction/gui_br.cpp
scummvm/trunk/engines/parallaction/parallaction_br.cpp
Modified: scummvm/trunk/engines/parallaction/detection.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/detection.cpp 2008-04-06 05:40:02 UTC (rev 31415)
+++ scummvm/trunk/engines/parallaction/detection.cpp 2008-04-06 07:05:56 UTC (rev 31416)
@@ -157,7 +157,24 @@
GF_LANG_EN | GF_LANG_FR | GF_LANG_DE | GF_LANG_IT | GF_LANG_MULT
},
+ // TODO: Base the detection of Amiga BRA on actual data file, not executable file.
+ {
+ {
+ "bra",
+ "Multi-lingual",
+ {
+ { "bigred", 0, "4f1e6bfd974b8ebabaad96d536904477", 95232 },
+ { NULL, 0, NULL, 0}
+ },
+ Common::UNK_LANG,
+ Common::kPlatformAmiga,
+ Common::ADGF_NO_FLAGS
+ },
+ GType_BRA,
+ GF_LANG_EN | GF_LANG_FR | GF_LANG_DE | GF_LANG_IT | GF_LANG_MULT
+ },
+
{ AD_TABLE_END_MARKER, 0, 0 }
};
Modified: scummvm/trunk/engines/parallaction/disk.h
===================================================================
--- scummvm/trunk/engines/parallaction/disk.h 2008-04-06 05:40:02 UTC (rev 31415)
+++ scummvm/trunk/engines/parallaction/disk.h 2008-04-06 07:05:56 UTC (rev 31416)
@@ -228,13 +228,36 @@
Frames* loadStatic(const char* name);
Frames* loadFrames(const char* name);
void loadSlide(BackgroundInfo& info, const char *filename);
- void loadScenery(BackgroundInfo& info, const char* background, const char* mask, const char* path);
+ void loadScenery(BackgroundInfo& info, const char* name, const char* mask, const char* path);
Table* loadTable(const char* name);
Common::SeekableReadStream* loadMusic(const char* name);
Common::ReadStream* loadSound(const char* name);
};
+class AmigaDisk_br : public DosDisk_br {
+protected:
+ BackgroundInfo _backgroundTemp;
+
+ Sprites* createSprites(const char *name);
+ void unpackFrame(byte *dst, byte *src, uint16 planeSize);
+ void unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 bytesPerPlane, uint16 height);
+ Font *createFont(const char *name, Common::SeekableReadStream &stream);
+ void loadMask(BackgroundInfo& info, const char *name);
+ void loadBackground(BackgroundInfo& info, const char *name);
+
+public:
+ AmigaDisk_br(Parallaction *vm);
+ virtual ~AmigaDisk_br();
+
+ Frames* loadTalk(const char *name);
+ Font* loadFont(const char* name);
+ Frames* loadStatic(const char* name);
+ Frames* loadFrames(const char* name);
+ void loadSlide(BackgroundInfo& info, const char *filename);
+ void loadScenery(BackgroundInfo& info, const char* name, const char* mask, const char* path);
+};
+
} // namespace Parallaction
Modified: scummvm/trunk/engines/parallaction/disk_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/disk_br.cpp 2008-04-06 05:40:02 UTC (rev 31415)
+++ scummvm/trunk/engines/parallaction/disk_br.cpp 2008-04-06 07:05:56 UTC (rev 31416)
@@ -23,6 +23,8 @@
*
*/
+#include "graphics/iff.h"
+
#include "parallaction/parallaction.h"
@@ -394,4 +396,324 @@
}
+
+
+
+
+AmigaDisk_br::AmigaDisk_br(Parallaction *vm) : DosDisk_br(vm) {
+
+}
+
+
+AmigaDisk_br::~AmigaDisk_br() {
+
+}
+
+#define NUM_PLANES 5
+
+/*
+ unpackFrame transforms images from 5-bitplanes format to
+ 8-bit color-index mode
+*/
+void AmigaDisk_br::unpackFrame(byte *dst, byte *src, uint16 planeSize) {
+
+ byte s0, s1, s2, s3, s4, mask, t0, t1, t2, t3, t4;
+
+ for (uint32 j = 0; j < planeSize; j++) {
+ s0 = src[j];
+ s1 = src[j+planeSize];
+ s2 = src[j+planeSize*2];
+ s3 = src[j+planeSize*3];
+ s4 = src[j+planeSize*4];
+
+ for (uint32 k = 0; k < 8; k++) {
+ mask = 1 << (7 - k);
+ t0 = (s0 & mask ? 1 << 0 : 0);
+ t1 = (s1 & mask ? 1 << 1 : 0);
+ t2 = (s2 & mask ? 1 << 2 : 0);
+ t3 = (s3 & mask ? 1 << 3 : 0);
+ t4 = (s4 & mask ? 1 << 4 : 0);
+ *dst++ = t0 | t1 | t2 | t3 | t4;
+ }
+
+ }
+
+}
+
+// FIXME: no mask is loaded
+void AmigaDisk_br::unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 bytesPerPlane, uint16 height) {
+ uint16 planeSize = bytesPerPlane * height;
+
+ for (uint32 i = 0; i < numFrames; i++) {
+ unpackFrame(dst, src, planeSize);
+ src += planeSize * NUM_PLANES;
+ dst += planeSize * 8;
+ }
+}
+
+#undef NUM_PLANES
+
+/*
+ FIXME: mask values are not computed correctly for level 1 and 2
+
+ NOTE: this routine is only able to build masks for Nippon Safes, since mask widths are hardcoded
+ into the main loop.
+*/
+void buildMask2(byte* buf) {
+
+ byte mask1[16] = { 0, 0x80, 0x20, 0xA0, 8, 0x88, 0x28, 0xA8, 2, 0x82, 0x22, 0xA2, 0xA, 0x8A, 0x2A, 0xAA };
+ byte mask0[16] = { 0, 0x40, 0x10, 0x50, 4, 0x44, 0x14, 0x54, 1, 0x41, 0x11, 0x51, 0x5, 0x45, 0x15, 0x55 };
+
+ byte plane0[40];
+ byte plane1[40];
+
+ for (int32 i = 0; i < _vm->_screenHeight; i++) {
+
+ memcpy(plane0, buf, 40);
+ memcpy(plane1, buf+40, 40);
+
+ for (uint32 j = 0; j < 40; j++) {
+ *buf++ = mask0[(plane0[j] & 0xF0) >> 4] | mask1[(plane1[j] & 0xF0) >> 4];
+ *buf++ = mask0[plane0[j] & 0xF] | mask1[plane1[j] & 0xF];
+ }
+
+ }
+}
+
+class BackgroundDecoder : public Graphics::ILBMDecoder {
+
+ PaletteFxRange *_range;
+ uint32 _i;
+
+protected:
+ void readCRNG(Common::IFFChunk &chunk) {
+ _range[_i]._timer = chunk.readUint16BE();
+ _range[_i]._step = chunk.readUint16BE();
+ _range[_i]._flags = chunk.readUint16BE();
+ _range[_i]._first = chunk.readByte();
+ _range[_i]._last = chunk.readByte();
+
+ _i++;
+ }
+
+public:
+ BackgroundDecoder(Common::ReadStream &input, Graphics::Surface &surface, byte *&colors, PaletteFxRange *range) :
+ Graphics::ILBMDecoder(input, surface, colors), _range(range), _i(0) {
+ }
+
+ void decode() {
+ Common::IFFChunk *chunk;
+ while ((chunk = nextChunk()) != 0) {
+ switch (chunk->id) {
+ case ID_BMHD:
+ readBMHD(*chunk);
+ break;
+
+ case ID_CMAP:
+ readCMAP(*chunk);
+ break;
+
+ case ID_BODY:
+ readBODY(*chunk);
+ break;
+
+ case ID_CRNG:
+ readCRNG(*chunk);
+ break;
+ }
+ }
+ }
+
+ uint32 getNumRanges() {
+ return _i;
+ }
+};
+
+
+void AmigaDisk_br::loadBackground(BackgroundInfo& info, const char *name) {
+
+ char path[PATH_LEN];
+ sprintf(path, "%s", name);
+
+ Common::File s;
+
+ if (!s.open(path))
+ errorFileNotFound(path);
+
+ byte *pal;
+ PaletteFxRange ranges[6];
+
+ BackgroundDecoder decoder(s, info.bg, pal, ranges);
+ decoder.decode();
+
+ uint i;
+
+ info.width = info.bg.w;
+ info.height = info.bg.h;
+
+ byte *p = pal;
+ for (i = 0; i < 32; i++) {
+ byte r = *p >> 2;
+ p++;
+ byte g = *p >> 2;
+ p++;
+ byte b = *p >> 2;
+ p++;
+ info.palette.setEntry(i, r, g, b);
+ }
+
+ free(pal);
+
+ for (i = 0; i < 6; i++) {
+ info.setPaletteRange(i, ranges[i]);
+ }
+
+ return;
+
+}
+
+void AmigaDisk_br::loadMask(BackgroundInfo& info, const char *name) {
+ debugC(5, kDebugDisk, "AmigaDisk_br::loadMask(%s)", name);
+
+ Common::File s;
+
+ if (!s.open(name))
+ return;
+
+ s.seek(0x30, SEEK_SET);
+
+ byte r, g, b;
+ for (uint i = 0; i < 4; i++) {
+ r = s.readByte();
+ g = s.readByte();
+ b = s.readByte();
+
+ info.layers[i] = (((r << 4) & 0xF00) | (g & 0xF0) | (b >> 4)) & 0xFF;
+ }
+
+ s.seek(0x126, SEEK_SET); // HACK: skipping IFF/ILBM header should be done by analysis, not magic
+ Graphics::PackBitsReadStream stream(s);
+
+ info.mask.create(info.width, info.height);
+ stream.read(info.mask.data, info.mask.size);
+ buildMask2(info.mask.data);
+
+ return;
+}
+
+void AmigaDisk_br::loadScenery(BackgroundInfo& info, const char* name, const char* mask, const char* path) {
+ debugC(1, kDebugDisk, "AmigaDisk_br::loadScenery '%s', '%s' '%s'", name, mask, path);
+
+ char filename[PATH_LEN];
+ Common::File stream;
+
+ if (name) {
+ sprintf(filename, "%s/backs/%s.bkg", _partPath, name);
+
+ loadBackground(info, filename);
+ }
+
+ if (mask) {
+ sprintf(filename, "%s/msk/%s.msk", _partPath, name);
+
+ loadMask(info, filename);
+ }
+
+ if (path) {
+ sprintf(filename, "%s/pth/%s.pth", _partPath, path);
+ if (!stream.open(filename))
+ errorFileNotFound(filename);
+
+ // NOTE: info.width and info.height are only valid if the background graphics
+ // have already been loaded
+ info.path.create(info.width, info.height);
+ stream.read(info.path.data, info.path.size);
+ stream.close();
+ }
+
+ return;
+}
+
+void AmigaDisk_br::loadSlide(BackgroundInfo& info, const char *name) {
+ debugC(1, kDebugDisk, "AmigaDisk_br::loadSlide '%s'", name);
+
+ char path[PATH_LEN];
+ sprintf(path, "backs/%s.bkg", name);
+
+ loadBackground(info, path);
+ return;
+}
+
+Frames* AmigaDisk_br::loadStatic(const char* name) {
+ debugC(1, kDebugDisk, "AmigaDisk_br::loadStatic '%s'", name);
+
+ char path[PATH_LEN];
+ sprintf(path, "%s/ras/%s", _partPath, name);
+ Common::File stream;
+ if (!stream.open(path)) {
+ errorFileNotFound(path);
+ }
+
+ loadBackground(_backgroundTemp, path);
+ return new SurfaceToFrames(&_backgroundTemp.bg);
+}
+
+Sprites* AmigaDisk_br::createSprites(const char *path) {
+
+ Common::File stream;
+ if (!stream.open(path)) {
+ errorFileNotFound(path);
+ }
+
+ uint16 num = stream.readUint16BE();
+
+ Sprites *sprites = new Sprites(num);
+
+ for (uint i = 0; i < num; i++) {
+ Sprite *spr = &sprites->_sprites[i];
+ spr->size = stream.readUint16BE();
+ spr->x = stream.readUint16BE();
+ spr->y = stream.readUint16BE();
+ spr->w = stream.readUint16BE();
+ spr->h = stream.readUint16BE();
+
+ // TODO: Convert image format
+ spr->packedData = (byte*)malloc(spr->size);
+ stream.read(spr->packedData, spr->size);
+ }
+
+ return sprites;
+}
+
+Frames* AmigaDisk_br::loadFrames(const char* name) {
+ debugC(1, kDebugDisk, "AmigaDisk_br::loadFrames '%s'", name);
+
+ char path[PATH_LEN];
+ sprintf(path, "%s/anims/%s", _partPath, name);
+
+ return createSprites(path);
+}
+
+Frames* AmigaDisk_br::loadTalk(const char *name) {
+ debugC(1, kDebugDisk, "AmigaDisk_br::loadTalk '%s'", name);
+
+ char path[PATH_LEN];
+ sprintf(path, "%s/talks/%s.tal", _partPath, name);
+
+ return createSprites(path);
+}
+
+Font* AmigaDisk_br::loadFont(const char* name) {
+ debugC(1, kDebugDisk, "AmigaFullDisk::loadFont '%s'", name);
+
+ char path[PATH_LEN];
+ sprintf(path, "%s", name);
+
+ Common::File stream;
+ if (!stream.open(path))
+ errorFileNotFound(path);
+
+ return createFont(name, stream);
+}
+
} // namespace Parallaction
Modified: scummvm/trunk/engines/parallaction/font.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/font.cpp 2008-04-06 05:40:02 UTC (rev 31415)
+++ scummvm/trunk/engines/parallaction/font.cpp 2008-04-06 07:05:56 UTC (rev 31416)
@@ -540,6 +540,11 @@
return new BraFont(stream);
}
+Font *AmigaDisk_br::createFont(const char *name, Common::SeekableReadStream &stream) {
+ // TODO: implement AmigaLabelFont for labels
+ return new AmigaFont(stream);
+}
+
void Parallaction_ns::initFonts() {
if (getPlatform() == Common::kPlatformPC) {
@@ -557,4 +562,22 @@
}
+void Parallaction_br::initFonts() {
+ if (getPlatform() == Common::kPlatformPC) {
+ _menuFont = _disk->loadFont("russia");
+ _dialogueFont = _disk->loadFont("comic");
+ _labelFont = _menuFont;
+ } else {
+ // TODO: Confirm fonts matches
+ // fonts/natasha/16
+ // fonts/sonya/18
+ // fonts/vanya/16
+
+ _menuFont = _disk->loadFont("fonts/natasha/16");
+ _dialogueFont = _disk->loadFont("fonts/sonya/18");
+ Common::MemoryReadStream stream(_amigaTopazFont, 2600, false);
+ _labelFont = new AmigaFont(stream);
+ }
}
+
+}
Modified: scummvm/trunk/engines/parallaction/gui_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/gui_br.cpp 2008-04-06 05:40:02 UTC (rev 31415)
+++ scummvm/trunk/engines/parallaction/gui_br.cpp 2008-04-06 07:05:56 UTC (rev 31416)
@@ -60,7 +60,6 @@
_disk->selectArchive(_partNames[_part]);
startPart();
}
-
}
void Parallaction_br::guiSplash(const char *name) {
@@ -98,7 +97,11 @@
surf->create(MENUITEM_WIDTH, MENUITEM_HEIGHT*2, 1);
// build first frame to be displayed when item is not selected
- _menuFont->setColor(0);
+ if (getPlatform() == Common::kPlatformPC) {
+ _menuFont->setColor(0);
+ } else {
+ _menuFont->setColor(7);
+ }
_menuFont->drawString((byte*)surf->getBasePtr(5, 2), MENUITEM_WIDTH, text);
// build second frame to be displayed when item is selected
@@ -141,8 +144,10 @@
_gfx->clearScreen();
_gfx->setBackground(kBackgroundSlide, "tbra", 0, 0);
- _gfx->_backgroundInfo.x = 20;
- _gfx->_backgroundInfo.y = 50;
+ if (getPlatform() == Common::kPlatformPC) {
+ _gfx->_backgroundInfo.x = 20;
+ _gfx->_backgroundInfo.y = 50;
+ }
int availItems = 4 + _progress;
Modified: scummvm/trunk/engines/parallaction/parallaction_br.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction_br.cpp 2008-04-06 05:40:02 UTC (rev 31415)
+++ scummvm/trunk/engines/parallaction/parallaction_br.cpp 2008-04-06 07:05:56 UTC (rev 31416)
@@ -57,12 +57,16 @@
if (getPlatform() == Common::kPlatformPC) {
_disk = new DosDisk_br(this);
_disk->setLanguage(2); // NOTE: language is now hardcoded to English. Original used command-line parameters.
- } else
- error("unsupported platform for Big Red Adventure");
- } else
+ _soundMan = new DummySoundMan(this);
+ } else {
+ _disk = new AmigaDisk_br(this);
+ _disk->setLanguage(2); // NOTE: language is now hardcoded to English. Original used command-line parameters.
+ _soundMan = new AmigaSoundMan(this);
+ }
+ } else {
error("unknown game type");
+ }
- _soundMan = new DummySoundMan(this);
initResources();
initFonts();
@@ -119,14 +123,6 @@
-void Parallaction_br::initFonts() {
-
- _menuFont = _disk->loadFont("russia");
- _dialogueFont = _disk->loadFont("comic");
- _labelFont = _menuFont;
-
-}
-
void Parallaction_br::freeFonts() {
delete _menuFont;
@@ -137,15 +133,22 @@
void Parallaction_br::initCursors() {
- _dinoCursor = _disk->loadPointer("pointer1");
- _dougCursor = _disk->loadPointer("pointer2");
- _donnaCursor = _disk->loadPointer("pointer3");
+ if (getPlatform() == Common::kPlatformPC) {
+ _dinoCursor = _disk->loadPointer("pointer1");
+ _dougCursor = _disk->loadPointer("pointer2");
+ _donnaCursor = _disk->loadPointer("pointer3");
- _mouseArrow = _donnaCursor;
+ _mouseArrow = _donnaCursor;
+ } else {
+ // TODO: Where are the Amiga cursors?
+ }
}
void Parallaction_br::setMousePointer(int16 index) {
+ // FIXME: Where are the Amiga cursors?
+ if (getPlatform() == Common::kPlatformAmiga)
+ return;
Common::Rect r;
_mouseArrow->getRect(0, r);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list