diff options
| author | David Corrales | 2007-05-26 20:23:24 +0000 |
|---|---|---|
| committer | David Corrales | 2007-05-26 20:23:24 +0000 |
| commit | 3646c968c9578c2a94d65ebd5fb06ec835f8c51d (patch) | |
| tree | 8b57b339ebb31a1d7a67f1678aa5dc5c7759070a /engines/parallaction | |
| parent | d1f56d93f934150f4b579c2e90564e2bf035f113 (diff) | |
| parent | ac45c5b33d834acbc9718f89be76e49d403a4d2c (diff) | |
| download | scummvm-rg350-3646c968c9578c2a94d65ebd5fb06ec835f8c51d.tar.gz scummvm-rg350-3646c968c9578c2a94d65ebd5fb06ec835f8c51d.tar.bz2 scummvm-rg350-3646c968c9578c2a94d65ebd5fb06ec835f8c51d.zip | |
Merged the fs branch with trunk. r26472:26948
svn-id: r26949
Diffstat (limited to 'engines/parallaction')
35 files changed, 2280 insertions, 1309 deletions
diff --git a/engines/parallaction/animation.cpp b/engines/parallaction/animation.cpp index 3d7e0a6190..67dc25994e 100644 --- a/engines/parallaction/animation.cpp +++ b/engines/parallaction/animation.cpp @@ -20,13 +20,9 @@ * */ -#include "parallaction/disk.h" +#include "common/stdafx.h" + #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" -#include "parallaction/music.h" -#include "parallaction/parser.h" -#include "parallaction/walk.h" -#include "parallaction/zone.h" namespace Parallaction { @@ -175,7 +171,7 @@ void jobDisplayAnimations(void *parm, Job *j) { else _si = _vm->_gfx->queryMask(v18->_top + v18->height()); -// printf("jobDisplayAnimations %s, x: %i, y: %i, w: %i, h: %i\n", v18->_name, v18->_left, v18->_top, v14._width, v14._height); + debugC(9, kDebugLocation, "jobDisplayAnimations(%s, x:%i, y:%i, z:%i, w:%i, h:%i, %p)", v18->_label._text, v18->_left, v18->_top, _si, v14._width, v14._height, v14._data0); _vm->_gfx->blitCnv(&v14, v18->_left, v18->_top, _si, Gfx::kBitBack); } @@ -465,7 +461,7 @@ void jobRunScripts(void *parm, Job *j) { while (((*inst)->_index != INST_SHOW) && (a->_flags & kFlagsActing)) { - debugC(1, kDebugJobs, "Animation: %s, instruction: %s", a->_label._text, (*inst)->_index == INST_END ? "end" : _instructionNamesRes[(*inst)->_index - 1]); + debugC(9, kDebugJobs, "Animation: %s, instruction: %s", a->_label._text, (*inst)->_index == INST_END ? "end" : _instructionNamesRes[(*inst)->_index - 1]); switch ((*inst)->_index) { case INST_ENDLOOP: // endloop diff --git a/engines/parallaction/archive.cpp b/engines/parallaction/archive.cpp index ab913f5d54..3f9d0098cf 100644 --- a/engines/parallaction/archive.cpp +++ b/engines/parallaction/archive.cpp @@ -51,7 +51,7 @@ Archive::Archive() { } void Archive::open(const char *file) { - debugC(1, kDebugDisk, "open archive '%s'", file); + debugC(3, kDebugDisk, "Archive::open(%s)", file); if (_archive.isOpen()) close(); @@ -83,8 +83,6 @@ void Archive::open(const char *file) { void Archive::close() { - debugC(1, kDebugDisk, "close current archive"); - if (!_archive.isOpen()) return; resetArchivedFile(); @@ -96,6 +94,8 @@ void Archive::close() { bool Archive::openArchivedFile(const char *filename) { resetArchivedFile(); + debugC(3, kDebugDisk, "Archive::openArchivedFile(%s)", filename); + if (!_archive.isOpen()) error("Archive::openArchivedFile: the archive is not open"); @@ -105,7 +105,7 @@ bool Archive::openArchivedFile(const char *filename) { } if (i == _numFiles) return false; - debugC(1, kDebugDisk, "file '%s' found in slot %i", filename, i); + debugC(9, kDebugDisk, "Archive::openArchivedFile: '%s' found in slot %i", filename, i); _file = true; diff --git a/engines/parallaction/callables.cpp b/engines/parallaction/callables.cpp index 9117bbf686..ffd7a844e4 100644 --- a/engines/parallaction/callables.cpp +++ b/engines/parallaction/callables.cpp @@ -26,13 +26,10 @@ #include "common/file.h" -#include "parallaction/disk.h" #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" -#include "parallaction/inventory.h" #include "parallaction/menu.h" -#include "parallaction/music.h" -#include "parallaction/zone.h" +#include "parallaction/sound.h" + namespace Parallaction { @@ -55,7 +52,8 @@ void _c_play_boogie(void *parm) { return; flag = 0; - _vm->_midiPlayer->play("boogie2"); + _vm->_soundMan->setMusicFile("boogie2"); + _vm->_soundMan->playMusic(); return; } @@ -67,17 +65,18 @@ void _c_score(void *parm) { } void _c_fade(void *parm) { + _vm->_gfx->setBlackPalette(); - _vm->_gfx->swapBuffers(); - Gfx::Palette pal; + memset(pal, 0, sizeof(Gfx::Palette)); + for (uint16 _di = 0; _di < 64; _di++) { _vm->_gfx->fadePalette(pal); _vm->_gfx->setPalette(pal); - } - _vm->waitTime( 1 ); + _vm->waitTime( 1 ); + } return; } @@ -246,12 +245,13 @@ void _c_endComment(void *param) { _vm->_gfx->floodFill(Gfx::kBitFront, r, 0); r.setWidth(w+3); - r.setHeight(w+4); + r.setHeight(h+3); r.moveTo(7, 7); _vm->_gfx->floodFill(Gfx::kBitFront, r, 1); - _vm->_gfx->setFont("comic"); + _vm->_gfx->setFont(kFontDialogue); _vm->_gfx->displayWrappedString(_vm->_location._endComment, 3, 5, 130, 0); + _vm->_gfx->updateScreen(); uint32 di = 0; for (di = 0; di < PALETTE_COLORS; di++) { @@ -297,21 +297,24 @@ void _c_endComment(void *param) { } void _c_frankenstein(void *parm) { + Gfx::Palette pal0; + Gfx::Palette pal1; for (uint16 i = 0; i <= BASE_PALETTE_COLORS; i++) { pal0[(i+FIRST_BASE_COLOR)] = _vm->_gfx->_palette[i]; pal0[(i+FIRST_BASE_COLOR)*3+1] = 0; pal0[(i+FIRST_BASE_COLOR)*3+2] = 0; - pal0[(i+FIRST_EHB_COLOR)*3+1] = 0; - pal0[(i+FIRST_EHB_COLOR)*3+2] = 0; + + pal1[(i+FIRST_BASE_COLOR)*3+1] = 0; + pal1[(i+FIRST_BASE_COLOR)*3+2] = 0; } for (uint16 _di = 0; _di < 30; _di++) { g_system->delayMillis(20); _vm->_gfx->setPalette(pal0, FIRST_BASE_COLOR, BASE_PALETTE_COLORS); g_system->delayMillis(20); - _vm->_gfx->setPalette(pal0, FIRST_EHB_COLOR, EHB_PALETTE_COLORS); + _vm->_gfx->setPalette(pal1, FIRST_BASE_COLOR, BASE_PALETTE_COLORS); } _vm->_gfx->setPalette(_vm->_gfx->_palette); @@ -360,43 +363,30 @@ void _c_finito(void *parm) { streamDonna.close(); cleanInventory(); - refreshInventory(_vm->_characterName); - _vm->_gfx->extendPalette(_vm->_gfx->_palette); + _vm->_gfx->setPalette(_vm->_gfx->_palette); if (gameCompleted) { - _vm->_gfx->setFont("slide"); - _vm->_gfx->_proportionalFont = false; - uint16 _ax = _vm->_gfx->getStringWidth(v4C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 70, v4C[_language]); - _ax = _vm->_gfx->getStringWidth(v3C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 100, v3C[_language]); - _ax = _vm->_gfx->getStringWidth(v2C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 130, v2C[_language]); - _ax = _vm->_gfx->getStringWidth(v1C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 160, v1C[_language]); - - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBit2); + _vm->_gfx->setFont(kFontMenu); + _vm->_gfx->displayCenteredString(70, v4C[_language]); + _vm->_gfx->displayCenteredString(100, v3C[_language]); + _vm->_gfx->displayCenteredString(130, v2C[_language]); + _vm->_gfx->displayCenteredString(160, v1C[_language]); + + _vm->_gfx->updateScreen(); waitUntilLeftClick(); strcpy(_vm->_location._name, "estgrotta.drki"); _engineFlags |= kEngineChangeLocation; } else { - _vm->_gfx->setFont("slide"); - _vm->_gfx->_proportionalFont = false; - uint16 _ax = _vm->_gfx->getStringWidth(v8C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 70, v8C[_language]); - _ax = _vm->_gfx->getStringWidth(v7C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 100, v7C[_language]); - _ax = _vm->_gfx->getStringWidth(v6C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 130, v6C[_language]); - _ax = _vm->_gfx->getStringWidth(v5C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 160, v5C[_language]); - - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBit2); + _vm->_gfx->setFont(kFontMenu); + _vm->_gfx->displayCenteredString(70, v8C[_language]); + _vm->_gfx->displayCenteredString(100, v7C[_language]); + _vm->_gfx->displayCenteredString(130, v6C[_language]); + _vm->_gfx->displayCenteredString(160, v5C[_language]); + + _vm->_gfx->updateScreen(); waitUntilLeftClick(); _vm->_menu->selectCharacter(); @@ -436,13 +426,10 @@ void _c_testResult(void *parm) { _vm->_gfx->swapBuffers(); _vm->parseLocation("common"); - _vm->_gfx->setFont("slide"); - _vm->_gfx->_proportionalFont = false; + _vm->_gfx->setFont(kFontMenu); - uint16 _ax = _vm->_gfx->getStringWidth(_slideText[0]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 38, _slideText[0]); - _ax = _vm->_gfx->getStringWidth(_slideText[1]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 58, _slideText[1]); + _vm->_gfx->displayCenteredString(38, _slideText[0]); + _vm->_gfx->displayCenteredString(58, _slideText[1]); _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBit2); @@ -450,4 +437,19 @@ void _c_testResult(void *parm) { return; } +void _c_offSound(void*) { + _vm->_soundMan->stopSfx(0); + _vm->_soundMan->stopSfx(1); + _vm->_soundMan->stopSfx(2); + _vm->_soundMan->stopSfx(3); +} + +void _c_startMusic(void*) { + _vm->_soundMan->playMusic(); +} + +void _c_closeMusic(void*) { + _vm->_soundMan->stopMusic(); +} + } // namespace Parallaction diff --git a/engines/parallaction/commands.cpp b/engines/parallaction/commands.cpp index 087abed156..d53763dfa8 100644 --- a/engines/parallaction/commands.cpp +++ b/engines/parallaction/commands.cpp @@ -23,10 +23,7 @@ #include "common/stdafx.h" #include "parallaction/parallaction.h" -#include "parallaction/parser.h" -#include "parallaction/commands.h" -#include "parallaction/walk.h" -#include "parallaction/zone.h" + namespace Parallaction { diff --git a/engines/parallaction/commands.h b/engines/parallaction/commands.h index 91410218b9..dee063de66 100644 --- a/engines/parallaction/commands.h +++ b/engines/parallaction/commands.h @@ -73,7 +73,6 @@ struct Command { ~Command(); }; -//typedef Common::List<Command*> CommandList; typedef ManagedList<Command*> CommandList; } // namespace Parallaction diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp index 9b4b0e8932..9b48a187cc 100644 --- a/engines/parallaction/debug.cpp +++ b/engines/parallaction/debug.cpp @@ -23,45 +23,157 @@ #include "common/stdafx.h" #include "common/system.h" + #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" +#include "parallaction/debug.h" namespace Parallaction { const char *_jobDescriptions[] = { - "0 - draw label", - "1 - draw mouse", - "2 - delay remove Job (erase label) || show inventory", - "3 - draw animations", - "4 - NONE", - "5 - NONE", - "6 - NONE", - "7 - NONE", - "8 - NONE", - "9 - NONE", - "10 - NONE", - "11 - NONE", - "12 - NONE", - "13 - NONE", - "14 - NONE", - "15 - delay remove Job (erase label) || run scripts || erase animations", - "16 - NONE", - "17 - job_12d4 (put item on screen) || jobRemovePickedItem (remove item from screen)", - "18 - toggle door", - "19 - walk", - "20 - erase label || hide inventory", - "21 - erase mouse" + "draw label", + "draw mouse", + "delayed label deletion || show inventory", + "draw animations", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "delayed label deletion || run scripts || erase animations", + "NONE", + "put item || pickup item", + "toggle door", + "walk", + "erase label || hide inventory", + "erase mouse" }; -void beep() { -// sound(1500); -// delay(100); -// nosound(); - return; +Debugger::Debugger(Parallaction *vm) + : GUI::Debugger() { + _vm = vm; + + DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); + DCmd_Register("location", WRAP_METHOD(Debugger, Cmd_Location)); + DCmd_Register("give", WRAP_METHOD(Debugger, Cmd_Give)); + DCmd_Register("jobs", WRAP_METHOD(Debugger, Cmd_Jobs)); + DCmd_Register("zones", WRAP_METHOD(Debugger, Cmd_Zones)); + DCmd_Register("animations", WRAP_METHOD(Debugger, Cmd_Animations)); + + +} + + +void Debugger::preEnter() { +} + + +void Debugger::postEnter() { } +bool Debugger::Cmd_Location(int argc, const char **argv) { + char *character = _vm->_characterName; + char *location = _vm->_location._name; + switch (argc) { + case 3: + character = const_cast<char*>(argv[2]); + location = const_cast<char*>(argv[1]); + sprintf(_vm->_location._name, "%s.%s", location, character); + // TODO: check if location exists + _engineFlags |= kEngineChangeLocation; + break; + + case 2: + location = const_cast<char*>(argv[1]); + sprintf(_vm->_location._name, "%s", location); + // TODO: check if location exists + _engineFlags |= kEngineChangeLocation; + break; + + case 1: + DebugPrintf("location <location name> [character name]\n"); + + } + + return true; +} + + +bool Debugger::Cmd_Give(int argc, const char **argv) { + + if (argc == 1) { + DebugPrintf("give <item name>\n"); + } else { + int index = _vm->_objectsNames->lookup(argv[1]); + if (index != -1) + _vm->addInventoryItem(index + 4); + else + DebugPrintf("invalid item name '%s'\n", argv[1]); + } + + return true; +} + + +bool Debugger::Cmd_Jobs(int argc, const char **argv) { + + JobList::iterator b = _vm->_jobs.begin(); + JobList::iterator e = _vm->_jobs.end(); + + DebugPrintf("+---+-------------------------------------------------------------+\n" + "|tag| description |\n" + "+---+-------------------------------------------------------------+\n"); + for ( ; b != e; b++) { + DebugPrintf("|%3i| %-60s|\n", (*b)->_tag, _jobDescriptions[(*b)->_tag] ); + } + DebugPrintf("+---+-------------------------------------------------------------+\n"); + + + return true; +} + +bool Debugger::Cmd_Zones(int argc, const char **argv) { + + ZoneList::iterator b = _vm->_zones.begin(); + ZoneList::iterator e = _vm->_zones.end(); + + DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n" + "| name | l | t | r | b | type | flag |\n" + "+--------------------+---+---+---+---+--------+--------+\n"); + for ( ; b != e; b++) { + Zone *z = *b; + DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", z->_label._text, z->_left, z->_top, z->_right, z->_bottom, z->_type, z->_flags ); + } + DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n"); + + + return true; +} + +bool Debugger::Cmd_Animations(int argc, const char **argv) { + + AnimationList::iterator b = _vm->_animations.begin(); + AnimationList::iterator e = _vm->_animations.end(); + + DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n" + "| name | x | y | z | f | type | flag | \n" + "+--------------------+---+---+---+---+--------+--------+\n"); + for ( ; b != e; b++) { + Animation *a = *b; + DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", a->_label._text, a->_left, a->_top, a->_z, a->_frame, a->_type, a->_flags ); + } + DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n"); + + + return true; +} } // namespace Parallaction diff --git a/engines/parallaction/debug.h b/engines/parallaction/debug.h new file mode 100644 index 0000000000..17b3fbb14f --- /dev/null +++ b/engines/parallaction/debug.h @@ -0,0 +1,33 @@ + +#ifndef PARALLACTION_DEBUGGER_H +#define PARALLACTION_DEBUGGER_H + +#include "gui/debugger.h" + +namespace Parallaction { + +class Parallaction; + +class Debugger : public GUI::Debugger { +public: + Debugger(Parallaction *vm); + virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ + +protected: + Parallaction *_vm; + + virtual void preEnter(); + virtual void postEnter(); + + bool Cmd_DebugLevel(int argc, const char **argv); + bool Cmd_Location(int argc, const char **argv); + bool Cmd_Give(int argc, const char **argv); + bool Cmd_Jobs(int argc, const char **argv); + bool Cmd_Zones(int argc, const char **argv); + bool Cmd_Animations(int argc, const char **argv); + +}; + +} // End of namespace Parallaction + +#endif diff --git a/engines/parallaction/defs.h b/engines/parallaction/defs.h index 9e877db457..d2b8f049d9 100644 --- a/engines/parallaction/defs.h +++ b/engines/parallaction/defs.h @@ -28,6 +28,8 @@ namespace Parallaction { +#define PATH_LEN 200 + template <class T> class ManagedList : public Common::List<T> { diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp index 1206b25d4c..6d2e3cec51 100644 --- a/engines/parallaction/dialogue.cpp +++ b/engines/parallaction/dialogue.cpp @@ -22,15 +22,10 @@ #include "common/stdafx.h" -#include "parallaction/commands.h" +#include "common/events.h" #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" -#include "parallaction/disk.h" -#include "parallaction/inventory.h" -#include "parallaction/parser.h" -#include "parallaction/zone.h" -#include "common/events.h" + namespace Parallaction { @@ -184,7 +179,7 @@ char *Parallaction::parseDialogueString(Script &script) { } while (strlen(vD0) == 0); - vD0[strlen(vD0)-1] = '\0'; // deletes the trailing '0xA' inserted by parseNextLine + vD0[strlen(vD0)-1] = '\0'; // deletes the trailing '0xA' // this is critical for Gfx::displayBalloonString to work properly char *vCC = (char*)malloc(strlen(vD0)+1); @@ -217,7 +212,8 @@ uint16 Parallaction::askDialoguePassword(Dialogue *q, StaticCnv *face) { // FIXME: see comment for updateInput() if (!g_system->getEventManager()->pollEvent(e)) continue; if (e.type != Common::EVENT_KEYDOWN) continue; - if (e.type != Common::EVENT_QUIT) g_system->quit(); + if (e.type == Common::EVENT_QUIT) + g_system->quit(); if (!isdigit(e.kbd.ascii)) continue; password[passwordLen] = e.kbd.ascii; @@ -225,6 +221,7 @@ uint16 Parallaction::askDialoguePassword(Dialogue *q, StaticCnv *face) { password[passwordLen] = '\0'; _gfx->displayBalloonString(_answerBalloonX[0] + 5, _answerBalloonY[0] + _answerBalloonH[0] - 15, password, 0); + _gfx->updateScreen(); g_system->delayMillis(20); } @@ -286,6 +283,7 @@ bool Parallaction::displayAnswers(Dialogue *q) { } i++; } + _gfx->updateScreen(); return displayed; } @@ -310,6 +308,7 @@ void Parallaction::displayQuestion(Dialogue *q, Cnv *cnv) { _gfx->drawBalloon(r, q->_mood & 0x10); _gfx->displayWrappedString(q->_text, QUESTION_BALLOON_X, QUESTION_BALLOON_Y, MAX_BALLOON_WIDTH, 0); + _gfx->updateScreen(); waitUntilLeftClick(); @@ -348,7 +347,7 @@ void Parallaction::runDialogue(SpeakData *data) { enterDialogue(); - _gfx->setFont("comic"); + _gfx->setFont(kFontDialogue); bool isNpc = scumm_stricmp(data->_name, "yourself") && data->_name[0] != '\0'; Cnv *face = isNpc ? _disk->loadTalk(data->_name) : _char._talk; @@ -412,6 +411,7 @@ int16 Parallaction::selectAnswer(Question *q, StaticCnv *cnv) { cnv->_data0 = _char._talk->getFramePtr(q->_answers[_di]->_mood & 0xF); // cnv->_data1 = _char._talk->field_8[q->_answers[_di]->_mood & 0xF]; _gfx->flatBlitCnv(cnv, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y, Gfx::kBitFront); + _gfx->updateScreen(); waitUntilLeftClick(); return _di; } @@ -434,6 +434,7 @@ int16 Parallaction::selectAnswer(Question *q, StaticCnv *cnv) { _gfx->flatBlitCnv(cnv, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y, Gfx::kBitFront); } + _gfx->updateScreen(); g_system->delayMillis(30); v2 = _si; } diff --git a/engines/parallaction/disk.cpp b/engines/parallaction/disk.cpp index c224ac5801..35b97b64c7 100644 --- a/engines/parallaction/disk.cpp +++ b/engines/parallaction/disk.cpp @@ -22,101 +22,15 @@ #include "common/stdafx.h" -#include "parallaction/defs.h" -#include "parallaction/graphics.h" +#include "graphics/iff.h" #include "parallaction/parallaction.h" -#include "parallaction/disk.h" -#include "parallaction/walk.h" -#include "graphics/ilbm.h" -namespace Parallaction { - -class RLEStream : public Common::ReadStream { - - Common::ReadStream *_input; - - byte _rembuf[257]; - int32 _wpos; - int32 _rpos; - - int32 _toBeRead; - byte* _dst; - int32 _read; - - void store(byte b) { - if (_toBeRead > 0) { - *_dst++ = b; - _read++; - _wpos = 0; - _rpos = 0; - } else { - assert(_wpos < 257); - _rembuf[_wpos++] = b; - _rpos = 0; - } - - _toBeRead--; - } - - void feed() { - int32 len = MIN(_wpos - _rpos, _toBeRead); - if (len == 0) return; - - memcpy(_dst, _rembuf + _rpos, len); - - _rpos += len; - _read += len; - _toBeRead -= len; - } - - void unpack() { - byte byteRun; - byte idx; - - uint32 i, j; - - while (_toBeRead > 0 && !_input->eos()) { - byteRun = _input->readByte(); - if (byteRun <= 127) { - i = byteRun + 1; - for (j = 0; j < i; j++) { - idx = _input->readByte(); - store(idx); - } - } else if (byteRun != 128) { - i = (256 - byteRun) + 1; - idx = _input->readByte(); - for (j = 0; j < i; j++) { - store(idx); - } - } - } - - } - -public: - RLEStream(Common::ReadStream *input) : _input(input), _wpos(0), _rpos(0) { - } - - ~RLEStream() { - } - - bool eos() const { - return _input->eos() & (_rpos == _wpos); - } - - uint32 read(void *dataPtr, uint32 dataSize) { - _toBeRead = (int32)dataSize; - _dst = (byte*)dataPtr; - _read = 0; - - feed(); - unpack(); - return _read; - } -}; +namespace Audio { + AudioStream *make8SVXStream(Common::ReadStream &input); +} +namespace Parallaction { /* This stream class is just a wrapper around Archive, so @@ -290,7 +204,7 @@ Cnv* DosDisk::loadCnv(const char *filename) { uint32 decsize = numFrames * width * height; byte *data = (byte*)malloc(decsize); - RLEStream decoder(&_resArchive); + Graphics::PackBitsReadStream decoder(_resArchive); decoder.read(data, decsize); return new Cnv(numFrames, width, height, data); @@ -328,16 +242,22 @@ Script* DosDisk::loadLocation(const char *name) { if (IS_MINI_CHARACTER(_vm->_characterName)) { sprintf(archivefile, "%s%s", _vm->_characterName+4, _languageDir); } else { - if (IS_DUMMY_CHARACTER(_vm->_characterName)) strcpy(archivefile, _languageDir); - else { + if (IS_DUMMY_CHARACTER(_vm->_characterName)) { + strcpy(archivefile, _languageDir); + } else { sprintf(archivefile, "%s%s", _vm->_characterName, _languageDir); } } + strcat(archivefile, name); strcat(archivefile, ".loc"); + debugC(3, kDebugDisk, "DosDisk::loadLocation(%s): trying '%s'", name, archivefile); + if (!_locArchive.openArchivedFile(archivefile)) { sprintf(archivefile, "%s%s.loc", _languageDir, name); + debugC(3, kDebugDisk, "DosDisk::loadLocation(%s): trying '%s'", name, archivefile); + if (!_locArchive.openArchivedFile(archivefile)) errorFileNotFound(name); } @@ -365,7 +285,7 @@ StaticCnv* DosDisk::loadHead(const char* name) { name += 4; } - snprintf(path, 8, "%shead", name); + sprintf(path, "%shead", name); path[8] = '\0'; return loadExternalStaticCnv(path); @@ -377,10 +297,10 @@ StaticCnv* DosDisk::loadPointer() { } -Cnv* DosDisk::loadFont(const char* name) { +Font* DosDisk::loadFont(const char* name) { char path[PATH_LEN]; sprintf(path, "%scnv", name); - return loadExternalCnv(path); + return createFont(name, loadExternalCnv(path)); } @@ -416,7 +336,7 @@ StaticCnv* DosDisk::loadStatic(const char* name) { uint16 size = cnv->_width*cnv->_height; cnv->_data0 = (byte*)malloc(size); - RLEStream decoder(&_resArchive); + Graphics::PackBitsReadStream decoder(_resArchive); decoder.read(cnv->_data0, size); return cnv; @@ -489,12 +409,12 @@ void DosDisk::loadBackground(const char *filename) { byte *path = (byte*)calloc(1, SCREENPATH_WIDTH*SCREEN_HEIGHT); - RLEStream stream(&_resArchive); + Graphics::PackBitsReadStream stream(_resArchive); unpackBackground(&stream, bg, mask, path); _vm->_gfx->setBackground(bg); _vm->_gfx->setMask(mask); - setPath(path); + _vm->setPath(path); free(bg); free(mask); @@ -525,7 +445,7 @@ void DosDisk::loadMaskAndPath(const char *name) { _resArchive.read(maskBuf, SCREENMASK_WIDTH*SCREEN_HEIGHT); _vm->_gfx->setMask(maskBuf); - setPath(pathBuf); + _vm->setPath(pathBuf); return; } @@ -569,6 +489,26 @@ Table* DosDisk::loadTable(const char* name) { return t; } +Common::ReadStream* DosDisk::loadMusic(const char* name) { + char path[PATH_LEN]; + sprintf(path, "%s.mid", name); + + Common::File *stream = new Common::File; + if (!stream->open(path)) + errorFileNotFound(path); + + return stream; +} + + +Common::ReadStream* DosDisk::loadSound(const char* name) { + return NULL; +} + + + + + #pragma mark - @@ -736,7 +676,6 @@ public: - AmigaDisk::AmigaDisk(Parallaction *vm) : Disk(vm) { } @@ -916,23 +855,16 @@ StaticCnv* AmigaDisk::loadHead(const char* name) { return cnv; } -Cnv* AmigaDisk::loadFont(const char* name) { +Font* AmigaDisk::loadFont(const char* name) { debugC(1, kDebugDisk, "AmigaDisk::loadFont '%s'", name); char path[PATH_LEN]; - if (scumm_stricmp(name, "topaz")) - sprintf(path, "%sfont", name); - else - strcpy(path, "introfont"); + sprintf(path, "%sfont", name); if (!_resArchive.openArchivedFile(path)) errorFileNotFound(path); - // FIXME: actually read data from font file and create - // real font instead of this dummy one - byte *data = (byte*)malloc(256*8*8); - memset(data, 0, 256*8*8); - return new Cnv(256, 8, 8, data); + return createFont(name, _resArchive); } StaticCnv* AmigaDisk::loadStatic(const char* name) { @@ -985,34 +917,15 @@ Cnv* AmigaDisk::loadFrames(const char* name) { void AmigaDisk::loadSlide(const char *name) { debugC(1, kDebugDisk, "AmigaDisk::loadSlide '%s'", name); - - Common::SeekableReadStream *s = openArchivedFile(name, true); - - Graphics::Surface surf; - byte *pal; - - // CRNG headers may be safely ignored for slides - Graphics::ILBMDecoder decoder(*s); - decoder.decode(surf, pal); - - for (uint32 i = 0; i < PALETTE_SIZE; i++) - _vm->_gfx->_palette[i] = pal[i] >> 2; - free(pal); - _vm->_gfx->setPalette(_vm->_gfx->_palette); - - _vm->_gfx->setBackground(static_cast<byte*>(surf.pixels)); - surf.free(); - - delete s; - + loadBackground(name); return; } // FIXME: mask values are not computed correctly for level 1 and 2 void buildMask(byte* buf) { - byte mask0[16] = { 0, 0x80, 0x20, 0xA0, 8, 0x84, 0x28, 0xA8, 2, 0x82, 0x22, 0xA2, 0xA, 0x8A, 0x2A, 0xAA }; - byte mask1[16] = { 0, 0x40, 0x10, 0x50, 4, 0x42, 0x14, 0x54, 1, 0x41, 0x11, 0x51, 0x5, 0x45, 0x15, 0x55 }; + 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]; @@ -1036,18 +949,42 @@ class BackgroundDecoder : public Graphics::ILBMDecoder { uint32 _i; protected: - void readCRNG() { - _range[_i]._timer = _chunk.readUint16(); - _range[_i]._step = _chunk.readUint16(); - _range[_i]._flags = _chunk.readUint16(); - _range[_i]._first = _chunk.readByte(); - _range[_i]._last = _chunk.readByte(); + 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, PaletteFxRange *range) : ILBMDecoder(input), _range(range), _i(0) { + 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() { @@ -1055,18 +992,17 @@ public: } }; -void AmigaDisk::loadScenery(const char* background, const char* mask) { - debugC(1, kDebugDisk, "AmigaDisk::loadScenery '%s', '%s'", background, mask); + +void AmigaDisk::loadBackground(const char *name) { + + Common::SeekableReadStream *s = openArchivedFile(name, true); Graphics::Surface surf; byte *pal; - char path[PATH_LEN]; + BackgroundDecoder decoder(*s, surf, pal, _vm->_gfx->_palettefx); + decoder.decode(); - sprintf(path, "%s.bkgnd", background); - Common::SeekableReadStream *s = openArchivedFile(path, true); - BackgroundDecoder decoder(*s, _vm->_gfx->_palettefx); - decoder.decode(surf, pal); - for (uint32 i = 0; i < PALETTE_SIZE; i++) + for (uint32 i = 0; i < BASE_PALETTE_COLORS * 3; i++) _vm->_gfx->_palette[i] = pal[i] >> 2; free(pal); _vm->_gfx->setPalette(_vm->_gfx->_palette); @@ -1074,31 +1010,74 @@ void AmigaDisk::loadScenery(const char* background, const char* mask) { surf.free(); delete s; - sprintf(path, "%s.mask", background); - s = openArchivedFile(path, true); + return; + +} + +void AmigaDisk::loadMask(const char *name) { + + char path[PATH_LEN]; + sprintf(path, "%s.mask", name); + + Common::SeekableReadStream *s = openArchivedFile(path, true); + 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(); + + _vm->_gfx->_bgLayers[i] = (((r << 4) & 0xF00) | (g & 0xF0) | (b >> 4)) & 0xFF; + +// printf("rgb = (%x, %x, %x) -> %x\n", r, g, b, _vm->_gfx->_bgLayers[i]); + } + + s->seek(0x126, SEEK_SET); // HACK: skipping IFF/ILBM header should be done by analysis, not magic - RLEStream *stream2 = new RLEStream(s); + Graphics::PackBitsReadStream stream(*s); + byte *buf = (byte*)malloc(SCREENMASK_WIDTH*SCREEN_HEIGHT); - stream2->read(buf, SCREENMASK_WIDTH*SCREEN_HEIGHT); + stream.read(buf, SCREENMASK_WIDTH*SCREEN_HEIGHT); buildMask(buf); _vm->_gfx->setMask(buf); free(buf); delete s; - delete stream2; - sprintf(path, "%s.path", background); - s = openArchivedFile(path, false); + return; +} + +void AmigaDisk::loadPath(const char *name) { + + char path[PATH_LEN]; + sprintf(path, "%s.path", name); + + Common::SeekableReadStream *s = openArchivedFile(path, false); if (s == NULL) return; // no errors if missing path files: not every location has one + s->seek(0x120, SEEK_SET); // HACK: skipping IFF/ILBM header should be done by analysis, not magic - stream2 = new RLEStream(s); - buf = (byte*)malloc(SCREENPATH_WIDTH*SCREEN_HEIGHT); - stream2->read(buf, SCREENPATH_WIDTH*SCREEN_HEIGHT); - setPath(buf); + + Graphics::PackBitsReadStream stream(*s); + byte *buf = (byte*)malloc(SCREENPATH_WIDTH*SCREEN_HEIGHT); + stream.read(buf, SCREENPATH_WIDTH*SCREEN_HEIGHT); + _vm->setPath(buf); free(buf); delete s; - delete stream2; + + return; +} + +void AmigaDisk::loadScenery(const char* background, const char* mask) { + debugC(1, kDebugDisk, "AmigaDisk::loadScenery '%s', '%s'", background, mask); + + char path[PATH_LEN]; + sprintf(path, "%s.bkgnd", background); + + loadBackground(path); + loadMask(background); + loadPath(background); return; } @@ -1141,5 +1120,18 @@ Table* AmigaDisk::loadTable(const char* name) { return t; } +Common::ReadStream* AmigaDisk::loadMusic(const char* name) { + return openArchivedFile(name); +} + +Common::ReadStream* AmigaDisk::loadSound(const char* name) { + char path[PATH_LEN]; + sprintf(path, "%s.snd", name); + + openArchivedFile(path); + + return new DummyArchiveStream(_resArchive); +} + } // namespace Parallaction diff --git a/engines/parallaction/disk.h b/engines/parallaction/disk.h index 5e6233f3af..14c671b02b 100644 --- a/engines/parallaction/disk.h +++ b/engines/parallaction/disk.h @@ -26,6 +26,10 @@ #include "parallaction/defs.h" #include "common/file.h" +namespace Audio { + class AudioStream; +} + namespace Parallaction { //------------------------------------------------------ @@ -39,6 +43,7 @@ class Table; class Parallaction; class Gfx; class Script; +class Font; struct Cnv; struct StaticCnv; @@ -104,13 +109,14 @@ public: virtual Cnv* loadObjects(const char *name) = 0; virtual StaticCnv* loadPointer() = 0; virtual StaticCnv* loadHead(const char* name) = 0; - virtual Cnv* loadFont(const char* name) = 0; + virtual Font* loadFont(const char* name) = 0; virtual StaticCnv* loadStatic(const char* name) = 0; virtual Cnv* loadFrames(const char* name) = 0; virtual void loadSlide(const char *filename) = 0; virtual void loadScenery(const char* background, const char* mask) = 0; virtual Table* loadTable(const char* name) = 0; - + virtual Common::ReadStream* loadMusic(const char* name) = 0; + virtual Common::ReadStream* loadSound(const char* name) = 0; }; class DosDisk : public Disk { @@ -124,6 +130,7 @@ private: void loadMaskAndPath(const char *name); void parseDepths(Common::SeekableReadStream &stream); void parseBackground(Common::SeekableReadStream &stream); + Font *createFont(const char *name, Cnv* cnv); protected: Gfx *_gfx; @@ -138,12 +145,14 @@ public: Cnv* loadObjects(const char *name); StaticCnv* loadPointer(); StaticCnv* loadHead(const char* name); - Cnv* loadFont(const char* name); + Font* loadFont(const char* name); StaticCnv* loadStatic(const char* name); Cnv* loadFrames(const char* name); void loadSlide(const char *filename); void loadScenery(const char* background, const char* mask); Table* loadTable(const char* name); + Common::ReadStream* loadMusic(const char* name); + Common::ReadStream* loadSound(const char* name); }; class AmigaDisk : public Disk { @@ -153,6 +162,10 @@ protected: StaticCnv* makeStaticCnv(Common::SeekableReadStream &stream); void unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 planeSize); Common::SeekableReadStream *openArchivedFile(const char* name, bool errorOnFileNotFound = false); + Font *createFont(const char *name, Common::SeekableReadStream &stream); + void loadMask(const char *name); + void loadPath(const char *name); + void loadBackground(const char *name); public: AmigaDisk(Parallaction *vm); @@ -164,12 +177,14 @@ public: Cnv* loadObjects(const char *name); StaticCnv* loadPointer(); StaticCnv* loadHead(const char* name); - Cnv* loadFont(const char* name); + Font* loadFont(const char* name); StaticCnv* loadStatic(const char* name); Cnv* loadFrames(const char* name); void loadSlide(const char *filename); void loadScenery(const char* background, const char* mask); Table* loadTable(const char* name); + Common::ReadStream* loadMusic(const char* name); + Common::ReadStream* loadSound(const char* name); }; } // namespace Parallaction diff --git a/engines/parallaction/font.cpp b/engines/parallaction/font.cpp new file mode 100644 index 0000000000..ad06b2000b --- /dev/null +++ b/engines/parallaction/font.cpp @@ -0,0 +1,447 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" +#include "common/stream.h" + +#include "parallaction/parallaction.h" + +namespace Parallaction { + + +extern byte _amigaTopazFont[]; + +class DosFont : public Font { + +protected: + // drawing properties + byte *_cp; + + Cnv *_data; + byte _pitch; + uint32 _bufPitch; + +protected: + virtual uint16 drawChar(char c) = 0; + virtual uint16 width(byte c) = 0; + virtual uint16 height() = 0; + + byte mapChar(byte c) { + if (c == 0xA5) return 0x5F; + if (c == 0xDF) return 0x60; + + if (c > 0x7F) return c - 0x7F; + + return c - 0x20; + } + +public: + DosFont(Cnv *cnv) : _data(cnv), _pitch(cnv->_width) { + } + + ~DosFont() { + if (_data) + delete _data; + } + + void setData() { + + } + + uint32 getStringWidth(const char *s) { + uint32 len = 0; + + while (*s) { + byte c = mapChar(*s); + len += width(c); + s++; + } + + return len; + } + + void drawString(byte* buffer, uint32 pitch, const char *s) { + if (s == NULL) + return; + + _bufPitch = pitch; + + _cp = buffer; + while (*s) { + byte c = mapChar(*s); + _cp += drawChar(c); + s++; + } + } +}; + +class DosDialogueFont : public DosFont { + +private: + static const byte _glyphWidths[126]; + +protected: + uint16 width(byte c) { + return _glyphWidths[c]; + } + + uint16 height() { + return _data->_height; + } + +public: + DosDialogueFont(Cnv *cnv) : DosFont(cnv) { + } + +protected: + uint16 drawChar(char c) { + + byte *src = _data->getFramePtr(c); + byte *dst = _cp; + uint16 w = width(c); + + for (uint16 j = 0; j < height(); j++) { + for (uint16 k = 0; k < w; k++) { + + if (!*src) + *dst = _color; + + dst++; + src++; + } + + src += (_pitch - w); + dst += (_bufPitch - w); + } + + return w; + + } + +}; + +const byte DosDialogueFont::_glyphWidths[126] = { + 0x04, 0x03, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x04, 0x06, 0x06, 0x03, 0x05, 0x03, 0x05, + 0x06, 0x06, 0x06, 0x06, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x03, 0x03, 0x05, 0x04, 0x05, 0x05, + 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x07, 0x05, 0x06, 0x05, 0x08, 0x07, + 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x03, 0x04, 0x05, 0x05, 0x06, 0x06, 0x05, + 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x06, 0x07, 0x05, 0x05, 0x05, 0x05, 0x02, 0x05, 0x05, 0x07, + 0x08, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, + 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x06, 0x05, 0x05, 0x05, 0x05 +}; + + +class DosMonospacedFont : public DosFont { + +protected: + uint16 _width; + +protected: + uint16 width(byte c) { + return _width; + } + + uint16 height() { + return _data->_height; + } + + +public: + DosMonospacedFont(Cnv *cnv) : DosFont(cnv) { + _width = 8; + } + +}; + +class DosMenuFont : public DosMonospacedFont { + +public: + DosMenuFont(Cnv *cnv) : DosMonospacedFont(cnv) { + } + +protected: + uint16 drawChar(char c) { + + byte *src = _data->getFramePtr(c); + byte *dst = _cp; + + for (uint16 i = 0; i < height(); i++) { + for (uint16 j = 0; j < _width; j++) { + if (*src) + *dst = *src; + src++; + dst++; + } + + dst += (_bufPitch - _width); + src += (_pitch - _width); + } + + return _width; + } + +}; + + +class DosLabelFont : public DosMonospacedFont { + +public: + DosLabelFont(Cnv *cnv) : DosMonospacedFont(cnv) { + } + +protected: + uint16 drawChar(char c) { + + byte *src = _data->getFramePtr(c); + byte *dst = _cp; + + for (uint16 i = 0; i < height(); i++) { + memcpy(dst, src, _width); + dst += _bufPitch; + src += _pitch; + } + + return _width; + } + +}; + +class AmigaFont : public Font { + +#include "common/pack-start.h" + struct CharLoc { + uint16 _offset; + uint16 _length; + }; + + struct AmigaDiskFont { + uint16 _ySize; + byte _style; + byte _flags; + uint16 _xSize; + uint16 _baseline; + uint16 _boldSmear; + uint16 _accessors; // unused + byte _loChar; + byte _hiChar; + uint32 _charData; + uint16 _modulo; + uint32 _charLoc; + uint32 _charSpace; + uint32 _charKern; + }; +#include "common/pack-end.h" + + AmigaDiskFont *_font; + uint32 _dataSize; + byte *_data; + byte *_charData; + CharLoc *_charLoc; + uint16 *_charSpace; + uint16 *_charKern; + + byte *_cp; + uint32 _pitch; + +protected: + uint16 getSpacing(byte c); + void blitData(byte c); + uint16 getKerning(byte c); + uint16 getPixels(byte c); + uint16 getOffset(byte c); + uint16 width(byte c); + uint16 height(); + + byte mapChar(byte c); + +public: + AmigaFont(Common::SeekableReadStream &stream); + ~AmigaFont(); + + uint32 getStringWidth(const char *s); + void drawString(byte *buf, uint32 pitch, const char *s); + + + +}; + +AmigaFont::AmigaFont(Common::SeekableReadStream &stream) { + stream.seek(32); // skips dummy header + + _dataSize = stream.size() - stream.pos(); + _data = (byte*)malloc(_dataSize); + stream.read(_data, _dataSize); + + _font = (AmigaDiskFont*)(_data + 78); + _font->_ySize = FROM_BE_16(_font->_ySize); + _font->_xSize = FROM_BE_16(_font->_xSize); + _font->_baseline = FROM_BE_16(_font->_baseline); + _font->_modulo = FROM_BE_16(_font->_modulo); + + _charLoc = (CharLoc*)(_data + FROM_BE_32(_font->_charLoc)); + _charData = _data + FROM_BE_32(_font->_charData); + + _charSpace = 0; + _charKern = 0; + + if (_font->_charSpace != 0) + _charSpace = (uint16*)(_data + FROM_BE_32(_font->_charSpace)); + if (_font->_charKern != 0) + _charKern = (uint16*)(_data + FROM_BE_32(_font->_charKern)); + +} + +AmigaFont::~AmigaFont() { + if (_data) + free(_data); +} + +uint16 AmigaFont::getSpacing(byte c) { + return (_charSpace == 0) ? _font->_xSize : FROM_BE_16(_charSpace[c]); +} + +uint16 AmigaFont::getKerning(byte c) { + return (_charKern == 0) ? 0 : FROM_BE_16(_charKern[c]); +} + +uint16 AmigaFont::getPixels(byte c) { + return FROM_BE_16(_charLoc[c]._length); +} + +uint16 AmigaFont::getOffset(byte c) { + return FROM_BE_16(_charLoc[c]._offset); +} + +void AmigaFont::blitData(byte c) { + + int num = getPixels(c); + int bitOffset = getOffset(c); + + byte *d = _cp; + byte *s = _charData; + + for (int i = 0; i < _font->_ySize; i++) { + + for (int j = bitOffset; j < bitOffset + num; j++) { + byte *b = s + (j >> 3); + byte bit = *b & (0x80 >> (j & 7)); + + if (bit) + *d = _color; + + d++; + } + + s += _font->_modulo; + d += _pitch - num; + } + +} + +uint16 AmigaFont::width(byte c) { +// printf("kern(%i) = %i, space(%i) = %i\t", c, getKerning(c), c, getSpacing(c)); + return getKerning(c) + getSpacing(c); +} + +uint16 AmigaFont::height() { + return _font->_ySize; +} + +byte AmigaFont::mapChar(byte c) { + + if (c < _font->_loChar || c > _font->_hiChar) + error("character '%c (%x)' not supported by font", c, c); + + return c - _font->_loChar; +} + +uint32 AmigaFont::getStringWidth(const char *s) { + uint32 len = 0; + + while (*s) { + byte c = mapChar(*s); + len += width(c); + s++; + } + + return len; +} + +void AmigaFont::drawString(byte *buffer, uint32 pitch, const char *s) { + + _cp = buffer; + _pitch = pitch; + + byte c; + + while (*s) { + c = mapChar(*s); + _cp += getKerning(c); + blitData(c); + _cp += getSpacing(c); + s++; + } + +} + +Font *DosDisk::createFont(const char *name, Cnv* cnv) { + Font *f = 0; + + if (!scumm_stricmp(name, "comic")) + f = new DosDialogueFont(cnv); + else + if (!scumm_stricmp(name, "topaz")) + f = new DosLabelFont(cnv); + else + if (!scumm_stricmp(name, "slide")) + f = new DosMenuFont(cnv); + else + error("unknown dos font '%s'", name); + + return f; +} + +Font *AmigaDisk::createFont(const char *name, Common::SeekableReadStream &stream) { + // TODO: implement AmigaLabelFont for labels + return new AmigaFont(stream); +} + +void Gfx::initFonts() { + + if (_vm->getPlatform() == Common::kPlatformPC) { + _fonts[kFontDialogue] = _vm->_disk->loadFont("comic"); + _fonts[kFontLabel] = _vm->_disk->loadFont("topaz"); + _fonts[kFontMenu] = _vm->_disk->loadFont("slide"); + } else { + _fonts[kFontDialogue] = _vm->_disk->loadFont("comic"); + + Common::MemoryReadStream stream(_amigaTopazFont, 2600, false); + _fonts[kFontLabel] = new AmigaFont(stream); + + _fonts[kFontMenu] = _vm->_disk->loadFont("slide"); + } + +} + +} diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index 7d21c81a5a..e11edf06c0 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -24,32 +24,14 @@ #include "common/system.h" #include "common/file.h" -#include "parallaction/graphics.h" -#include "parallaction/parser.h" #include "parallaction/parallaction.h" -#include "parallaction/disk.h" -#include "parallaction/zone.h" + extern OSystem *g_system; namespace Parallaction { -// -// proportional font glyphs width -// -const byte _glyphWidths[126] = { - 0x04, 0x03, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x04, 0x06, 0x06, 0x03, 0x05, 0x03, 0x05, - 0x06, 0x06, 0x06, 0x06, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x03, 0x03, 0x05, 0x04, 0x05, 0x05, - 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x07, 0x05, 0x06, 0x05, 0x08, 0x07, - 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x03, 0x04, 0x05, 0x05, 0x06, 0x06, 0x05, - 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x06, 0x07, 0x05, 0x05, 0x05, 0x05, 0x02, 0x05, 0x05, 0x07, - 0x08, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, - 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x06, 0x05, 0x05, 0x05, 0x05 -}; - -bool Gfx::_proportionalFont = false; byte * Gfx::_buffers[]; #define BALLOON_WIDTH 12 @@ -119,19 +101,44 @@ void Gfx::drawBalloon(const Common::Rect& r, uint16 winding) { void Gfx::setPalette(Palette pal, uint32 first, uint32 num) { // printf("setPalette(%i, %i)\n", first, num); - if (first + num > PALETTE_COLORS) + if (first + num > BASE_PALETTE_COLORS) error("wrong parameters for setPalette()"); - byte syspal[PALETTE_COLORS*4]; + byte sysBasePal[EHB_PALETTE_COLORS*4]; + byte sysExtraPal[BASE_PALETTE_COLORS*4]; + byte r, g, b; + uint32 j = 0; for (uint32 i = first; i < first+num; i++) { - syspal[i*4] = (pal[i*3] << 2) | (pal[i*3] >> 4); - syspal[i*4+1] = (pal[i*3+1] << 2) | (pal[i*3+1] >> 4); - syspal[i*4+2] = (pal[i*3+2] << 2) | (pal[i*3+2] >> 4); - syspal[i*4+3] = 0; + r = (pal[i*3] << 2) | (pal[i*3] >> 4); + g = (pal[i*3+1] << 2) | (pal[i*3+1] >> 4); + b = (pal[i*3+2] << 2) | (pal[i*3+2] >> 4); + + sysBasePal[j*4] = r; + sysBasePal[j*4+1] = g; + sysBasePal[j*4+2] = b; + sysBasePal[j*4+3] = 0; + + if (_vm->getPlatform() == Common::kPlatformAmiga) { + sysExtraPal[j*4] = r >> 1; + sysExtraPal[j*4+1] = g >> 1; + sysExtraPal[j*4+2] = b >> 1; + sysExtraPal[j*4+3] = 0; + } else { + sysExtraPal[j*4] = 0; + sysExtraPal[j*4+1] = 0; + sysExtraPal[j*4+2] = 0; + sysExtraPal[j*4+3] = 0; + } + + j++; } - g_system->setPalette(syspal, first, num); + g_system->setPalette(sysBasePal, first, num); + + if (_vm->getPlatform() == Common::kPlatformAmiga) + g_system->setPalette(sysExtraPal, first+FIRST_EHB_COLOR, num); + g_system->updateScreen(); return; @@ -197,7 +204,7 @@ void Gfx::animatePalette() { } void Gfx::fadePalette(Palette pal) { - for (uint16 i = 0; i < PALETTE_SIZE; i++) + for (uint16 i = 0; i < BASE_PALETTE_COLORS * 3; i++) if (pal[i] < _palette[i]) pal[i]++; return; @@ -221,7 +228,7 @@ void Gfx::buildBWPalette(Palette pal) { void Gfx::quickFadePalette(Palette pal) { - for (uint16 i = 0; i < PALETTE_SIZE; i++) { + for (uint16 i = 0; i < BASE_PALETTE_COLORS * 3; i++) { if (pal[i] == _palette[i]) continue; pal[i] += (pal[i] < _palette[i] ? 4 : -4); } @@ -229,18 +236,22 @@ void Gfx::quickFadePalette(Palette pal) { return; } -void Gfx::extendPalette(Palette pal) { +void Gfx::setHalfbriteMode(bool enable) { +#ifdef HALFBRITE + if (_vm->getPlatform() != Common::kPlatformAmiga) return; + if (enable == _halfbrite) return; - for (uint16 i = 0; i < BASE_PALETTE_COLORS; i++) { - pal[(i+FIRST_EHB_COLOR)*3] = pal[i*3] / 2; - pal[(i+FIRST_EHB_COLOR)*3+1] = pal[i*3+1] / 2; - pal[(i+FIRST_EHB_COLOR)*3+2] = pal[i*3+2] / 2; - } - - setPalette(pal); -} + byte *buf = _buffers[kBitBack]; + for (uint32 i = 0; i < SCREEN_SIZE; i++) + *buf++ ^= 0x20; + buf = _buffers[kBitFront]; + for (uint32 i = 0; i < SCREEN_SIZE; i++) + *buf++ ^= 0x20; + _halfbrite = !_halfbrite; +#endif +} void Gfx::updateScreen() { // printf("Gfx::updateScreen()\n"); @@ -385,7 +396,7 @@ void Gfx::blit(const Common::Rect& r, uint16 z, byte *data, Gfx::Buffers buffer) void jobDisplayLabel(void *parm, Job *j) { Label *label = (Label*)parm; - debugC(1, kDebugJobs, "jobDisplayLabel (%p)", (const void*) label); + debugC(9, kDebugJobs, "jobDisplayLabel (%p)", (const void*) label); if (label->_cnv._width == 0) return; @@ -397,7 +408,7 @@ void jobDisplayLabel(void *parm, Job *j) { void jobEraseLabel(void *parm, Job *j) { Label *label = (Label*)parm; - debugC(1, kDebugJobs, "jobEraseLabel (%p)", (const void*) label); + debugC(9, kDebugJobs, "jobEraseLabel (%p)", (const void*) label); int16 _si, _di; @@ -537,69 +548,54 @@ void Gfx::restoreZoneBackground(const Common::Rect& r, byte *data) { return; } +void Gfx::makeCnvFromString(StaticCnv *cnv, char *text) { + assert(_font == _fonts[kFontLabel]); + + if (_vm->getPlatform() == Common::kPlatformAmiga) { + cnv->_width = _font->getStringWidth(text) + 16; + cnv->_height = 10; + cnv->_data0 = (byte*)malloc(cnv->_width * cnv->_height); + memset(cnv->_data0, 0, cnv->_width * cnv->_height); + + _font->setColor(7); + _font->drawString(cnv->_data0 + 1, cnv->_width, text); + _font->drawString(cnv->_data0 + 1 + cnv->_width * 2, cnv->_width, text); + _font->drawString(cnv->_data0 + cnv->_width, cnv->_width, text); + _font->drawString(cnv->_data0 + 2 + cnv->_width, cnv->_width, text); + _font->setColor(1); + _font->drawString(cnv->_data0 + 1 + cnv->_width, cnv->_width, text); + } else { + cnv->_width = _font->getStringWidth(text); + cnv->_height = _font->height(); + cnv->_data0 = (byte*)malloc(cnv->_width * cnv->_height); + memset(cnv->_data0, 0, cnv->_width * cnv->_height); + _font->drawString(cnv->_data0, cnv->_width, text); + } +} -// -// strings -// void Gfx::displayString(uint16 x, uint16 y, const char *text) { - if (text == NULL) - return; - - uint16 len = strlen(text); - StaticCnv tmp; - - for (uint16 i = 0; i < len; i++) { - byte c = mapChar(text[i]); - - tmp._width = _font->_width; - tmp._height = _font->_height; - tmp._data0 = _font->getFramePtr(c); - - flatBlitCnv(&tmp, x, y, kBitFront); - - x += (_proportionalFont ? _glyphWidths[(int)c] : 8); + assert(_font == _fonts[kFontMenu]); - } - - return; + byte *dst = _buffers[kBitFront] + x + y*SCREEN_WIDTH; + _font->setColor(1); + _font->drawString(dst, SCREEN_WIDTH, text); } +void Gfx::displayCenteredString(uint16 y, const char *text) { + uint16 x = (SCREEN_WIDTH - getStringWidth(text)) / 2; + displayString(x, y, text); +} void Gfx::displayBalloonString(uint16 x, uint16 y, const char *text, byte color) { + assert(_font == _fonts[kFontDialogue]); - uint16 len = strlen(text); - - for (uint16 i = 0; i < len; i++) { - - byte c = mapChar(text[i]); - uint16 w = _proportionalFont ? _glyphWidths[(int)c] : 8; - byte *s = _font->getFramePtr(c); - byte *d = _buffers[kBitFront] + x + y*SCREEN_WIDTH; - -// printf("%i\n", text[i]); - - for (uint16 j = 0; j < _font->_height; j++) { - for (uint16 k = 0; k < w; k++) { - *d = (*s) ? 1 : color; - d++; - s++; - } - - s += (8 - w); - d += (SCREEN_WIDTH - w); - } - - x += w; - } - - updateScreen(); + byte *dst = _buffers[kBitFront] + x + y*SCREEN_WIDTH; - return; + _font->setColor(color); + _font->drawString(dst, SCREEN_WIDTH, text); } - - bool Gfx::displayWrappedString(char *text, uint16 x, uint16 y, uint16 maxwidth, byte color) { // printf("Gfx::displayWrappedString(%s, %i, %i, %i, %i)...", text, x, y, maxwidth, color); @@ -607,7 +603,6 @@ bool Gfx::displayWrappedString(char *text, uint16 x, uint16 y, uint16 maxwidth, bool rv = false; uint16 linewidth = 0; - _proportionalFont = true; uint16 rx = x + 10; uint16 ry = y + 4; @@ -646,37 +641,16 @@ bool Gfx::displayWrappedString(char *text, uint16 x, uint16 y, uint16 maxwidth, } - - uint16 Gfx::getStringWidth(const char *text) { - if (text == NULL) return 0; - - uint16 len = strlen(text); - - if (_proportionalFont == 0) { - // fixed font - return len*8; - } - - // proportional font - uint16 w = 0; - for (uint16 i = 0; i < len; i++) { - byte c = mapChar(text[i]); - w += _glyphWidths[(int)c]; - } - - return w; + return _font->getStringWidth(text); } - void Gfx::getStringExtent(char *text, uint16 maxwidth, int16* width, int16* height) { uint16 lines = 0; uint16 w = 0; *width = 0; - _proportionalFont = true; - char token[40]; while (strlen(text) != 0) { @@ -706,10 +680,9 @@ void Gfx::getStringExtent(char *text, uint16 maxwidth, int16* width, int16* heig } -void Gfx::setFont(const char* name) { - if (_font) delete _font; - - _font = _vm->_disk->loadFont(name); +void Gfx::setFont(Fonts name) { + assert(name < 3); + _font = _fonts[name]; } @@ -742,50 +715,6 @@ void Gfx::restoreBackground(const Common::Rect& r) { return; } - -void Gfx::makeCnvFromString(StaticCnv *cnv, char *text) { -// printf("makeCnvFromString('%s')\n", text); - - uint16 len = strlen(text); - - cnv->_width = _font->_width * len; - cnv->_height = _font->_height; - -// printf("%i x %i\n", cnv->_width, cnv->_height); - - cnv->_data0 = (byte*)malloc(cnv->_width * cnv->_height); - - for (uint16 i = 0; i < len; i++) { - byte c = mapChar(text[i]); - - byte *s = _font->getFramePtr(c); - byte *d = cnv->_data0 + _font->_width * i; - - for (uint16 j = 0; j < _font->_height; j++) { - memcpy(d, s, 8); - - s += 8; - d += cnv->_width; - } - } - - return; -} - -// -// internal character mapping -// -byte Gfx::mapChar(byte c) { - - if (c == 0xA5) return 0x5F; - if (c == 0xDF) return 0x60; - - if (c > 0x7F) return c - 0x7F; - - return c - 0x20; -} - - void Gfx::freeStaticCnv(StaticCnv *cnv) { // printf("free_static_cnv()\n"); @@ -842,7 +771,7 @@ void Gfx::grabRect(byte *dst, const Common::Rect& r, Gfx::Buffers srcbuffer, uin } -void Gfx::maskOpNot(uint16 x, uint16 y, uint16 unused) { +void Gfx::plotMaskPixel(uint16 x, uint16 y, byte color) { uint16 _ax = x + y * SCREEN_WIDTH; _buffers[kMask0][_ax >> 2] &= ~(3 << ((_ax & 3) << 1)); @@ -852,12 +781,12 @@ void Gfx::maskOpNot(uint16 x, uint16 y, uint16 unused) { -void Gfx::maskClearRectangle(const Common::Rect& r) { +void Gfx::fillMaskRect(const Common::Rect& r, byte color) { uint16 _di = r.left/4 + r.top*80; for (uint16 _si = r.top; _si < r.bottom; _si++) { - memset(&_buffers[kMask0][_di], 0, r.width()/4+1); + memset(&_buffers[kMask0][_di], color, r.width()/4+1); _di += 80; } @@ -897,9 +826,15 @@ Gfx::Gfx(Parallaction* vm) : setBlackPalette(); + _bgLayers[0] = _bgLayers[1] = _bgLayers[2] = _bgLayers[3] = 0; + + memset(_palette, 0, sizeof(_palette)); memset(_palettefx, 0, sizeof(_palettefx)); initMouse( 0 ); + initFonts(); + + _halfbrite = false; _font = NULL; @@ -913,8 +848,13 @@ Gfx::~Gfx() { free(_buffers[kBitBack]); free(_buffers[kBit2]); - if (_font) delete _font; + delete _fonts[kFontDialogue]; + delete _fonts[kFontLabel]; + delete _fonts[kFontMenu]; + freeStaticCnv(_mouseComposedArrow); + delete _mouseComposedArrow; + return; } diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index 893946ecc2..ff9fed4b32 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -68,6 +68,27 @@ struct PaletteFxRange { #include "common/pack-end.h" // END STRUCT PACKING +class Font { + +protected: + byte _color; + + +public: + Font() {} + virtual ~Font() {} + + virtual void setColor(byte color) { + _color = color; + } + virtual uint32 getStringWidth(const char *s) = 0; + virtual uint16 height() = 0; + + virtual void drawString(byte* buffer, uint32 pitch, const char *s) = 0; + + +}; + struct StaticCnv { uint16 _width; // uint16 _height; // @@ -117,6 +138,12 @@ class Parallaction; struct DoorData; struct GetData; +enum Fonts { + kFontDialogue = 0, + kFontLabel = 1, + kFontMenu = 2 +}; + class Gfx { public: @@ -137,6 +164,7 @@ public: void drawBalloon(const Common::Rect& r, uint16 arg_8); void displayBalloonString(uint16 x, uint16 y, const char *text, byte color); void displayString(uint16 x, uint16 y, const char *text); + void displayCenteredString(uint16 y, const char *text); bool displayWrappedString(char *text, uint16 x, uint16 y, uint16 maxwidth, byte color); uint16 getStringWidth(const char *text); void getStringExtent(char *text, uint16 maxwidth, int16* width, int16* height); @@ -156,8 +184,8 @@ public: void restoreBackground(const Common::Rect& r); // intro - void maskClearRectangle(const Common::Rect& r); - void maskOpNot(uint16 x, uint16 y, uint16 unused); + void fillMaskRect(const Common::Rect& r, byte color); + void plotMaskPixel(uint16 x, uint16 y, byte color); // low level void swapBuffers(); @@ -175,13 +203,15 @@ public: void blitCnv(StaticCnv *cnv, int16 x, int16 y, uint16 z, Gfx::Buffers buffer); // palette - void setPalette(Palette palette, uint32 first = FIRST_BASE_COLOR, uint32 num = PALETTE_COLORS); + void setPalette(Palette palette, uint32 first = FIRST_BASE_COLOR, uint32 num = BASE_PALETTE_COLORS); void setBlackPalette(); void animatePalette(); void fadePalette(Palette palette); void buildBWPalette(Palette palette); void quickFadePalette(Palette palette); - void extendPalette(Palette palette); + + // amiga specific + void setHalfbriteMode(bool enable); // init Gfx(Parallaction* vm); @@ -189,11 +219,11 @@ public: void setMousePointer(int16 index); - void setFont(const char* name); + void initFonts(); + void setFont(Fonts name); public: Common::Point _labelPosition[2]; - static bool _proportionalFont; uint16 _bgLayers[4]; PaletteFxRange _palettefx[6]; Palette _palette; @@ -203,7 +233,9 @@ protected: static byte * _buffers[NUM_BUFFERS]; static byte _mouseArrow[256]; StaticCnv *_mouseComposedArrow; - Cnv *_font; + Font *_font; + Font *_fonts[3]; + bool _halfbrite; protected: byte mapChar(byte c); diff --git a/engines/parallaction/intro.cpp b/engines/parallaction/intro.cpp index 6995b41644..059555e862 100644 --- a/engines/parallaction/intro.cpp +++ b/engines/parallaction/intro.cpp @@ -24,9 +24,9 @@ #include "parallaction/parallaction.h" #include "parallaction/menu.h" -#include "parallaction/music.h" -#include "parallaction/graphics.h" -#include "parallaction/zone.h" +#include "parallaction/sound.h" + +#include "graphics/primitives.h" namespace Parallaction { @@ -123,10 +123,14 @@ static uint16 _rightHandPositions[684] = { extern Credit _credits[]; - void _c_startIntro(void *parm) { _rightHandAnim = _vm->findAnimation("righthand"); - _vm->_midiPlayer->play("intro"); + + if (_vm->getPlatform() == Common::kPlatformPC) { + _vm->_soundMan->setMusicFile("intro"); + _vm->_soundMan->playMusic(); + } + _engineFlags |= kEngineMouse; return; @@ -134,30 +138,40 @@ void _c_startIntro(void *parm) { void _c_endIntro(void *parm) { - _vm->_gfx->setFont("slide"); - _vm->_gfx->_proportionalFont = false; + _vm->_gfx->setFont(kFontMenu); + + debugC(1, kDebugLocation, "endIntro()"); - uint16 _di; - for (uint16 _si = 0; _si < 7; _si++) { - _di = _vm->_gfx->getStringWidth(_credits[_si]._role); - _vm->_gfx->displayString((SCREEN_WIDTH - _di)/2, 80, _credits[_si]._role); + for (uint16 _si = 0; _si < 6; _si++) { + _vm->_gfx->displayCenteredString(80, _credits[_si]._role); + _vm->_gfx->displayCenteredString(100, _credits[_si]._name); - _di = _vm->_gfx->getStringWidth(_credits[_si]._name); - _vm->_gfx->displayString((SCREEN_WIDTH - _di)/2, 100, _credits[_si]._name); + _vm->_gfx->updateScreen(); for (uint16 v2 = 0; v2 < 100; v2++) { + _mouseButtons = kMouseNone; _vm->updateInput(); - if (_mouseButtons != kMouseLeftUp) - _vm->waitTime( 1 ); + if (_mouseButtons == kMouseLeftUp) + break; + + _vm->waitTime( 1 ); } _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); } + debugC(1, kDebugLocation, "endIntro(): done showing credits"); - waitUntilLeftClick(); + if ((_vm->getFeatures() & GF_DEMO) == 0) { + _vm->_gfx->displayCenteredString(80, "CLICK MOUSE BUTTON TO START"); + _vm->_gfx->updateScreen(); - _engineFlags &= ~kEngineMouse; - _vm->_menu->selectCharacter(); + waitUntilLeftClick(); + + _engineFlags &= ~kEngineMouse; + _vm->_menu->selectCharacter(); + } else { + waitUntilLeftClick(); + } return; } @@ -190,133 +204,24 @@ void _c_moveSheet(void *parm) { return; } - -void introFunc1(uint16 oldX, uint16 oldY, uint16 newX, uint16 newY) { - - uint16 unused = 0; - int16 dx = newX - oldX; - int16 dy = newY - oldY; - - _vm->_gfx->maskOpNot(oldX, oldY, unused); - _vm->_gfx->maskOpNot(newX, newY, unused); - - if (abs(dx) >= abs(dy)) { - - int16 v4 = abs(dy); - if (dx >= 0 && dy >= 0) { - for (uint16 i = 1; i < dx; i++) { - v4 += dy; - if (abs(dx) < v4) { - oldY++; - v4 -= dx; - } - _vm->_gfx->maskOpNot(i + oldX, oldY, unused); - } - } - - if (dx < 0 && dy >= 0) { - for (uint16 i = 1; i > abs(dx); i++) { - v4 += dy; - if (abs(dx) < v4) { - oldY++; - v4 -= abs(dx); - } - _vm->_gfx->maskOpNot(oldX - i, oldY, unused); - } - } - - if (dx < 0 && dy < 0) { - for (uint16 i = 1; i > abs(dx); i++) { - v4 += dy; - if (abs(v4) > abs(dx)) { - oldY--; - v4 -= abs(dx); - } - _vm->_gfx->maskOpNot(oldX - i, oldY, unused); - } - } - - if (dx >= 0 && dy < 0) { - for (uint16 i = 1; i < dx; i++) { - v4 -= dy; - if (v4 > dx) { - oldY--; - v4 -= dx; - } - _vm->_gfx->maskOpNot(i + oldX, oldY, unused); - } - } - - } - - if (abs(dy) < abs(dx)) { - - int16 v4 = abs(dx); - - if (dx >= 0 && dy >= 0) { - for (uint16 i = 1; i < dy; i++) { - v4 += dx; - if (v4 > dy) { - oldX++; - v4 -= dy; - } - _vm->_gfx->maskOpNot(oldX, i + oldY, unused); - } - } - - if (dx < 0 && dy >= 0) { - for (uint16 i = 1; i < dy; i++) { - v4 -= dx; - if (v4 > dy) { - oldX--; - v4 -= dy; - } - _vm->_gfx->maskOpNot(oldX, i + oldY, unused); - } - } - - if (dx < 0 && dy < 0) { - for (uint16 i = 1; i < abs(dy); i++) { - v4 -= abs(dx); - if (v4 > abs(dy)) { - oldX--; - v4 -= abs(dy); - } - _vm->_gfx->maskOpNot(oldX, oldY - i, unused); - } - } - - if (dx >= 0 && dy < 0) { - for (uint16 i = 1; i < abs(dy); i++) { - v4 += abs(dx); - if (v4 > abs(dy)) { - oldX++; - v4 -= abs(dy); - } - _vm->_gfx->maskOpNot(oldX, oldY - i, unused); - } - } - - } - - - return; +void plotPixel(int x, int y, int color, void *data) { + _vm->_gfx->plotMaskPixel(x, y, color); } - void _c_sketch(void *parm) { static uint16 index = 1; - uint16 _4 = _rightHandPositions[2*index+1]; - uint16 _3 = _rightHandPositions[2*index]; - uint16 _2 = _rightHandPositions[2*(index-1)+1]; - uint16 _1 = _rightHandPositions[2*(index-1)]; + uint16 newy = _rightHandPositions[2*index+1]; + uint16 newx = _rightHandPositions[2*index]; - introFunc1(_1, _2, _3, _4); + uint16 oldy = _rightHandPositions[2*(index-1)+1]; + uint16 oldx = _rightHandPositions[2*(index-1)]; - _rightHandAnim->_left = _rightHandPositions[index*2]; - _rightHandAnim->_top = _rightHandPositions[index*2+1] - 20; + Graphics::drawLine(oldx, oldy, newx, newy, 0, plotPixel, NULL); + + _rightHandAnim->_left = newx; + _rightHandAnim->_top = newy - 20; index++; @@ -335,10 +240,78 @@ void _c_shade(void *parm) { _rightHandAnim->_top ); - _vm->_gfx->maskClearRectangle(r); + _vm->_gfx->fillMaskRect(r, 0); return; } +void _c_projector(void*) { +#ifdef HALFBRITE + static int dword_16032 = 0; + +// Bitmap bm; +// InitBitMap(&bm); + + if (dword_16032 != 0) { +/* // keep drawing spotlight in its final place + _vm->_gfx->flatBlitCnv(&scnv, 110, 25, Gfx::kBitFront); + BltBitMap(&bm, 0, 0, &_screen._bitMap, 110, 25, a3->??, a3->??, 0x20, 0x20); +*/ return; + } + + _vm->_gfx->setHalfbriteMode(true); +/* + // move spot light around the stage + int d7, d6; + for (d7 = 0; d7 < 150; d7++) { + + if (d7 < 100) { + int d1 = d7; + if (d1 < 0) + d1++; + + d1 >>= 1; + d6 = 50 - d1; + } else { + int d1 = d7 / 100; + if (d1 < 0) + d1++; + + d1 >>= 1; + d6 = d1; + } + + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+20, d6, a3->??, a3->??, 0x20, 0x20); + sub_1590C(d6 + a3->??); + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+20, d6, a3->??, a3->??, 0xFA, 0x20); + } + + for (d7 = 50; d7 > -10; d7--) { + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+120, d6, a3->??, a3->??, 0x20, 0x20); + sub_1590C(d6 + a3->??); + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+120, d6, a3->??, a3->??, 0xFA, 0x20); + } + + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+120, d6, a3->??, a3->??, 0x20, 0x20); + _vm->_gfx->flatBlitCnv(&scnv, d7+120, d6, Gfx::kBitFront); +*/ + + dword_16032 = 1; + return; +#endif +} + +void _c_HBOff(void*) { +#ifdef HALFBRITE + _vm->_gfx->setHalfbriteMode(false); +#endif +} + +void _c_HBOn(void*) { +#ifdef HALFBRITE + _vm->_gfx->setHalfbriteMode(true); +#endif +} + } // namespace Parallaction diff --git a/engines/parallaction/inventory.cpp b/engines/parallaction/inventory.cpp index 0e6a003b23..52dbd50db0 100644 --- a/engines/parallaction/inventory.cpp +++ b/engines/parallaction/inventory.cpp @@ -23,10 +23,7 @@ #include "common/stdafx.h" #include "parallaction/parallaction.h" -#include "parallaction/disk.h" -#include "parallaction/zone.h" -#include "parallaction/graphics.h" -#include "parallaction/inventory.h" + namespace Parallaction { @@ -40,6 +37,7 @@ namespace Parallaction { // #define INVENTORY_MAX_ITEMS 30 +#define INVENTORY_FIRST_ITEM 4 // first four entries are used up by verbs #define INVENTORYITEM_PITCH 32 #define INVENTORYITEM_WIDTH 24 @@ -96,72 +94,67 @@ void drawInventoryItem(uint16 pos, InventoryItem *item); // int16 Parallaction::getHoverInventoryItem(int16 x, int16 y) { - int16 _di = x; - - int16 _si = -1; + int16 slot = -1; do { - _si++; - } while (_inventory[_si]._id != 0); + slot++; + } while (_inventory[slot]._id != 0); - _si = (_si + 4) / INVENTORY_ITEMS_PER_LINE; + slot = (slot + 4) / INVENTORY_ITEMS_PER_LINE; - if (_invPosition.x >= _di) return -1; - if ((_invPosition.x + INVENTORY_WIDTH) <= _di) return -1; + if (_invPosition.x >= x) return -1; + if ((_invPosition.x + INVENTORY_WIDTH) <= x) return -1; if (_invPosition.y >= y) return -1; - if ((_si * INVENTORYITEM_HEIGHT + _invPosition.y) <= y) return -1; + if ((slot * INVENTORYITEM_HEIGHT + _invPosition.y) <= y) return -1; - return ((_di - _invPosition.x) / INVENTORYITEM_WIDTH) + (INVENTORY_ITEMS_PER_LINE * ((y - _invPosition.y) / INVENTORYITEM_HEIGHT)); + return ((x - _invPosition.x) / INVENTORYITEM_WIDTH) + (INVENTORY_ITEMS_PER_LINE * ((y - _invPosition.y) / INVENTORYITEM_HEIGHT)); } -int16 Parallaction::pickupItem(Zone *z) { - - uint16 _si; - for (_si = 0; _inventory[_si]._id != 0; _si++) ; - if (_si == INVENTORY_MAX_ITEMS) - return -1; - - _inventory[_si]._id = MAKE_INVENTORY_ID(z->u.get->_icon); - _inventory[_si]._index = z->u.get->_icon; - - addJob(&jobRemovePickedItem, z, kPriority17 ); - - if (_inventory[_si]._id == 0) return 0; +void refreshInventory(const char *character) { + for (uint16 i = 0; i < INVENTORY_MAX_ITEMS; i++) { + drawInventoryItem(i, &_inventory[i]); + } + return; +} - refreshInventoryItem(_characterName, _si); - return 0; +void refreshInventoryItem(const char *character, uint16 index) { + drawInventoryItem(index, &_inventory[index]); + return; } +int Parallaction::addInventoryItem(uint16 item) { -void Parallaction::addInventoryItem(uint16 item) { + uint16 slot = 0; + while (_inventory[slot]._id != 0) + slot++; - uint16 _si = 0; - while (_inventory[_si]._id != 0) _si++; + if (slot == INVENTORY_MAX_ITEMS) + return -1; - _inventory[_si]._id = MAKE_INVENTORY_ID(item); - _inventory[_si]._index = item; + _inventory[slot]._id = MAKE_INVENTORY_ID(item); + _inventory[slot]._index = item; - refreshInventoryItem(_characterName, _si); + refreshInventoryItem(_characterName, slot); - return; + return 0; } void Parallaction::dropItem(uint16 v) { - uint16 _di = 0; - for (uint16 _si = 0; _si < INVENTORY_MAX_ITEMS - 1; _si++) { + bool found = false; + for (uint16 slot = 0; slot < INVENTORY_MAX_ITEMS - 1; slot++) { - if (v + 4 == _inventory[_si]._index) { - _di = 1; + if (v + INVENTORY_FIRST_ITEM == _inventory[slot]._index) { + found = true; } - if (_di == 0) continue; + if (!found) continue; - memcpy(&_inventory[_si], &_inventory[_si+1], sizeof(InventoryItem)); + memcpy(&_inventory[slot], &_inventory[slot+1], sizeof(InventoryItem)); } refreshInventory(_characterName); @@ -172,8 +165,8 @@ void Parallaction::dropItem(uint16 v) { int16 Parallaction::isItemInInventory(int32 v) { - for (uint16 _si = 0; _si < INVENTORY_MAX_ITEMS; _si++) { - if (_inventory[_si]._id == (uint)v) + for (uint16 slot = 0; slot < INVENTORY_MAX_ITEMS; slot++) { + if (_inventory[slot]._id == (uint)v) return 1; } @@ -182,6 +175,9 @@ int16 Parallaction::isItemInInventory(int32 v) { + + + void drawInventoryItem(uint16 pos, InventoryItem *item) { uint16 line = pos / INVENTORY_ITEMS_PER_LINE; @@ -263,12 +259,11 @@ void jobShowInventory(void *parm, Job *j) { // printf("job_showInventory()..."); _numInvLines = 0; - while (_inventory[_numInvLines]._id != 0) _numInvLines++; - _numInvLines = (_numInvLines + 4) / INVENTORY_ITEMS_PER_LINE; Common::Rect r(INVENTORY_WIDTH, _numInvLines * INVENTORYITEM_HEIGHT); + r.moveTo(_invPosition); _vm->_gfx->copyRect( @@ -308,14 +303,13 @@ void jobHideInventory(void *parm, Job *j) { void openInventory() { -// printf("openInventory()\n"); - - uint16 _si = 0; _engineFlags |= kEngineInventory; - while (_inventory[_si]._id != 0) _si++; + uint16 slot = 0; + while (_inventory[slot]._id != 0) + slot++; - uint16 _LOCALinventory_lines = (_si + 4) / INVENTORY_ITEMS_PER_LINE; + uint16 lines = (slot + 4) / INVENTORY_ITEMS_PER_LINE; _invPosition.x = _vm->_mousePos.x - (INVENTORY_WIDTH / 2); if (_invPosition.x < 0) @@ -324,12 +318,12 @@ void openInventory() { if ((_invPosition.x + INVENTORY_WIDTH) > SCREEN_WIDTH) _invPosition.x = SCREEN_WIDTH - INVENTORY_WIDTH; - _invPosition.y = _vm->_mousePos.y - 2 - (_LOCALinventory_lines * INVENTORYITEM_HEIGHT); + _invPosition.y = _vm->_mousePos.y - 2 - (lines * INVENTORYITEM_HEIGHT); if (_invPosition.y < 0) _invPosition.y = 0; - if (_invPosition.y > SCREEN_HEIGHT - _LOCALinventory_lines * INVENTORYITEM_HEIGHT) - _invPosition.y = SCREEN_HEIGHT - _LOCALinventory_lines * INVENTORYITEM_HEIGHT; + if (_invPosition.y > SCREEN_HEIGHT - lines * INVENTORYITEM_HEIGHT) + _invPosition.y = SCREEN_HEIGHT - lines * INVENTORYITEM_HEIGHT; return; @@ -338,53 +332,28 @@ void openInventory() { void closeInventory() { -// printf("closeInventory()\n"); - _engineFlags &= ~kEngineInventory; } - - -// refreshes inventory view -// -void redrawInventory() { - - - for (uint16 _si = 0; _si < INVENTORY_MAX_ITEMS; _si++) { - drawInventoryItem(_si, &_inventory[_si]); - } - -} - void initInventory() { - _buffer = (byte*)malloc(INVENTORY_WIDTH * INVENTORY_HEIGHT); // this buffer is also used by menu so it must stay this size + _buffer = (byte*)malloc(INVENTORY_WIDTH * INVENTORY_HEIGHT); +} +void destroyInventory() { + if (_buffer) + free(_buffer); + _buffer = 0; } void cleanInventory() { - for (uint16 _si = 4; _si < 30; _si++) { - _inventory[_si]._id = 0; - _inventory[_si]._index = 0; + for (uint16 slot = INVENTORY_FIRST_ITEM; slot < INVENTORY_MAX_ITEMS; slot++) { + _inventory[slot]._id = 0; + _inventory[slot]._index = 0; } return; } - - -void refreshInventory(const char *character) { - redrawInventory(); - - return; -} - - -void refreshInventoryItem(const char *character, uint16 index) { - drawInventoryItem(index, &_inventory[index]); - - return; -} - } // namespace Parallaction diff --git a/engines/parallaction/inventory.h b/engines/parallaction/inventory.h index 8adf546529..36ea39ed03 100644 --- a/engines/parallaction/inventory.h +++ b/engines/parallaction/inventory.h @@ -41,15 +41,14 @@ struct InventoryItem { extern InventoryItem _inventory[]; void initInventory(); +void destroyInventory(); void openInventory(); void closeInventory(); int16 isItemInInventory(int32 v); void cleanInventory(); void addInventoryItem(uint16 item); -void redrawInventory(); void highlightInventoryItem(int16 pos, byte color); -void refreshInventoryItem(const char *character, uint16 index); void refreshInventory(const char *character); void extractInventoryGraphics(int16 pos, byte *dst); diff --git a/engines/parallaction/location.cpp b/engines/parallaction/location.cpp index 8066c65afd..012e351ab5 100644 --- a/engines/parallaction/location.cpp +++ b/engines/parallaction/location.cpp @@ -23,34 +23,21 @@ #include "common/stdafx.h" #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" -#include "parallaction/disk.h" -#include "parallaction/parser.h" -#include "parallaction/music.h" -#include "parallaction/commands.h" -#include "parallaction/walk.h" -#include "parallaction/zone.h" +#include "parallaction/sound.h" namespace Parallaction { -void resolveLocationForwards(); -void switchBackground(const char* background, const char* mask); - - void Parallaction::parseLocation(const char *filename) { -// printf("parseLocation(%s)", filename); debugC(1, kDebugLocation, "parseLocation('%s')", filename); uint16 _si = 1; - _gfx->_proportionalFont = false; - _gfx->setFont("topaz"); + _gfx->setFont(kFontLabel); Script *_locationScript = _disk->loadLocation(filename); fillBuffers(*_locationScript, true); while (scumm_stricmp(_tokens[0], "ENDLOCATION")) { -// printf("token[0] = %s", _tokens[0]); if (!scumm_stricmp(_tokens[0], "LOCATION")) { // The parameter for location is 'location.mask'. @@ -135,6 +122,7 @@ void Parallaction::parseLocation(const char *filename) { } if (!scumm_stricmp(_tokens[0], "COMMENT")) { _location._comment = parseComment(*_locationScript); + debugC(3, kDebugLocation, "Location comment: '%s'", _location._comment); } if (!scumm_stricmp(_tokens[0], "ENDCOMMENT")) { _location._endComment = parseComment(*_locationScript); @@ -151,6 +139,14 @@ void Parallaction::parseLocation(const char *filename) { if (!scumm_stricmp(_tokens[0], "SOUND")) { strcpy(_soundFile, _tokens[1]); } + if (!scumm_stricmp(_tokens[0], "MUSIC")) { + if (getPlatform() == Common::kPlatformAmiga) + _soundMan->setMusicFile(_tokens[1]); + } + if (!scumm_stricmp(_tokens[0], "SOUND")) { +// if (getPlatform() == Common::kPlatformAmiga) +// _soundMan->loadSfx(_tokens[1], atoi(_tokens[2])); + } fillBuffers(*_locationScript, true); } @@ -162,8 +158,6 @@ void Parallaction::parseLocation(const char *filename) { } void Parallaction::resolveLocationForwards() { -// printf("resolveLocationForwards()"); -// printf("# forwards: %i", _numForwards); for (uint16 _si = 0; _forwardedCommands[_si]; _si++) { _forwardedCommands[_si]->u._animation = findAnimation(_forwardedAnimationNames[_si]); @@ -178,36 +172,36 @@ void Parallaction::resolveLocationForwards() { void Parallaction::freeLocation() { debugC(7, kDebugLocation, "freeLocation"); + _soundMan->stopSfx(0); + _soundMan->stopSfx(1); + _soundMan->stopSfx(2); + _soundMan->stopSfx(3); + if (_localFlagNames) delete _localFlagNames; - _localFlagNames = new Table(120); - _localFlagNames->addData("visited"); - - debugC(7, kDebugLocation, "freeLocation: localflags names freed"); - + + // HACK: prevents leakage. A routine like this + // should allocate memory at all, though. + if ((_engineFlags & kEngineQuit) == 0) { + _localFlagNames = new Table(120); + _localFlagNames->addData("visited"); + } + _location._walkNodes.clear(); - debugC(7, kDebugLocation, "freeLocation: walk nodes freed"); // TODO (LIST): helperNode should be rendered useless by the use of a Common::List<> // to store Zones and Animations. Right now, it holds a list of Zones to be preserved // but that'll pretty meaningless with a single list approach. freeZones(); - debugC(7, kDebugLocation, "freeLocation: zones freed"); - freeAnimations(); - debugC(7, kDebugLocation, "freeLocation: animations freed"); if (_location._comment) { free(_location._comment); } _location._comment = NULL; - debugC(7, kDebugLocation, "freeLocation: comments freed"); _location._commands.clear(); - debugC(7, kDebugLocation, "freeLocation: commands freed"); - _location._aCommands.clear(); - debugC(7, kDebugLocation, "freeLocation: acommands freed"); return; } @@ -252,7 +246,7 @@ void Parallaction::switchBackground(const char* background, const char* mask) { _si += 3; } - _gfx->extendPalette(pal); + _gfx->setPalette(pal); } _disk->loadScenery(background, mask); @@ -267,18 +261,15 @@ extern Job *_jEraseLabel; void Parallaction::showSlide(const char *name) { _disk->loadSlide(name); - _gfx->extendPalette(_gfx->_palette); + _gfx->setPalette(_gfx->_palette); _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); debugC(1, kDebugLocation, "changeLocation: new background set"); - _gfx->_proportionalFont = false; - _gfx->setFont("slide"); + _gfx->setFont(kFontMenu); - uint16 _ax = strlen(_slideText[0]); - _ax <<= 3; // text width - uint16 _dx = (SCREEN_WIDTH - _ax) >> 1; // center text - _gfx->displayString(_dx, 14, _slideText[0]); // displays text on screen + _gfx->displayCenteredString(14, _slideText[0]); // displays text on screen + _gfx->updateScreen(); waitUntilLeftClick(); @@ -306,9 +297,9 @@ void Parallaction::showSlide(const char *name) { is commented out, and would definitely crash the current implementation. */ void Parallaction::changeLocation(char *location) { - debugC(1, kDebugLocation, "changeLocation to '%s'", location); + debugC(1, kDebugLocation, "changeLocation(%s)", location); - pickMusic(location); + _soundMan->playLocationMusic(location); // WORKAROUND: this if-statement has been added to avoid crashes caused by // execution of label jobs after a location switch. The other workaround in @@ -324,15 +315,11 @@ void Parallaction::changeLocation(char *location) { _hoverZone = NULL; if (_engineFlags & kEngineMouse) { changeCursor( kCursorArrow ); - debugC(2, kDebugLocation, "changeLocation: changed cursor"); } _animations.remove(&_char._ani); - debugC(2, kDebugLocation, "changeLocation: removed character from the animation list"); freeLocation(); - debugC(1, kDebugLocation, "changeLocation: old location free'd"); - char buf[100]; strcpy(buf, location); @@ -361,14 +348,10 @@ void Parallaction::changeLocation(char *location) { } _animations.push_front(&_char._ani); - debugC(2, kDebugLocation, "changeLocation: new character added to the animation list"); strcpy(_saveData1, list[0].c_str()); parseLocation(list[0].c_str()); - _gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); - debugC(1, kDebugLocation, "changeLocation: new location '%s' parsed", _saveData1); - _char._ani._oldPos.x = -1000; _char._ani._oldPos.y = -1000; @@ -379,14 +362,12 @@ void Parallaction::changeLocation(char *location) { _char._ani._frame = _location._startFrame; _location._startPosition.y = -1000; _location._startPosition.x = -1000; - - debugC(2, kDebugLocation, "changeLocation: initial position set to x: %i, y: %i, f: %i", _location._startPosition.x, _location._startPosition.y, _location._startFrame); } - byte palette[PALETTE_SIZE]; - for (uint16 _si = 0; _si < PALETTE_SIZE; _si++) palette[_si] = 0; - _gfx->extendPalette(palette); + _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); + _gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); + _gfx->setBlackPalette(); if (_location._commands.size() > 0) { runCommands(_location._commands); @@ -395,22 +376,22 @@ void Parallaction::changeLocation(char *location) { runJobs(); _gfx->swapBuffers(); } - + if (_location._comment) { doLocationEnterTransition(); - debugC(2, kDebugLocation, "changeLocation: shown location comment"); } - + runJobs(); _gfx->swapBuffers(); - _gfx->extendPalette(_gfx->_palette); + _gfx->setPalette(_gfx->_palette); if (_location._aCommands.size() > 0) { runCommands(_location._aCommands); - debugC(1, kDebugLocation, "changeLocation: location acommands run"); } - debugC(1, kDebugLocation, "changeLocation completed"); +// _soundMan->playSfx(0); + + debugC(1, kDebugLocation, "changeLocation() done"); return; @@ -428,46 +409,43 @@ void Parallaction::changeLocation(char *location) { void Parallaction::doLocationEnterTransition() { debugC(1, kDebugLocation, "doLocationEnterTransition"); - if (_localFlags[_currentLocationIndex] & kFlagsVisited) return; // visited - + if (_localFlags[_currentLocationIndex] & kFlagsVisited) { + debugC(3, kDebugLocation, "skipping location transition"); + return; // visited + } + byte pal[PALETTE_SIZE]; _gfx->buildBWPalette(pal); - _gfx->setPalette(pal, FIRST_BASE_COLOR, BASE_PALETTE_COLORS); + _gfx->setPalette(pal); jobRunScripts(NULL, NULL); jobEraseAnimations(NULL, NULL); jobDisplayAnimations(NULL, NULL); - _gfx->setFont("comic"); + _gfx->setFont(kFontDialogue); _gfx->swapBuffers(); _gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - int16 v7C, v7A; - _gfx->getStringExtent(_location._comment, 130, &v7C, &v7A); + int16 w, h; + _gfx->getStringExtent(_location._comment, 130, &w, &h); - Common::Rect r(10 + v7C, 5 + v7A); + Common::Rect r(10 + w, 5 + h); r.moveTo(5, 5); _gfx->floodFill(Gfx::kBitFront, r, 0); r.grow(-1); _gfx->floodFill(Gfx::kBitFront, r, 1); _gfx->displayWrappedString(_location._comment, 3, 5, 130, 0); - // FIXME: ??? -#if 0 - do { - mouseFunc1(); - } while (_mouseButtons != kMouseLeftUp); -#endif - + _gfx->updateScreen(); waitUntilLeftClick(); _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront ); // fades maximum intensity palette towards approximation of main palette for (uint16 _si = 0; _si<6; _si++) { - waitTime( 1 ); _gfx->quickFadePalette(pal); _gfx->setPalette(pal); + waitTime( 1 ); } debugC(1, kDebugLocation, "doLocationEnterTransition completed"); @@ -475,8 +453,4 @@ void Parallaction::doLocationEnterTransition() { return; } -void mouseFunc1() { - // FIXME: implement this -} - } // namespace Parallaction diff --git a/engines/parallaction/menu.cpp b/engines/parallaction/menu.cpp index 6ae01a2774..ecd5f0157e 100644 --- a/engines/parallaction/menu.cpp +++ b/engines/parallaction/menu.cpp @@ -23,11 +23,9 @@ #include "common/stdafx.h" #include "common/system.h" -#include "parallaction/menu.h" -#include "parallaction/disk.h" -#include "parallaction/music.h" -#include "parallaction/graphics.h" #include "parallaction/parallaction.h" +#include "parallaction/menu.h" +#include "parallaction/sound.h" namespace Parallaction { @@ -94,6 +92,7 @@ static uint16 _doughKey[] = { 1, 7 ,7, 2, 2, 6 }; Menu::Menu(Parallaction *vm) { _vm = vm; + } Menu::~Menu() { @@ -105,68 +104,55 @@ void Menu::start() { _vm->_disk->selectArchive((_vm->getPlatform() == Common::kPlatformPC) ? "disk1" : "disk0"); - _vm->_gfx->_proportionalFont = false; - _vm->_gfx->setFont("slide"); + splash(); + + _language = chooseLanguage(); + _vm->_disk->setLanguage(_language); + + int game = selectGame(); + if (game == 0) + newGame(); + + return; +} + +void Menu::splash() { _vm->_disk->loadSlide("intro"); - _vm->_gfx->extendPalette(_vm->_gfx->_palette); + _vm->_gfx->setPalette(_vm->_gfx->_palette); _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); - g_system->delayMillis(2000); _vm->_disk->loadSlide("minintro"); - _vm->_gfx->extendPalette(_vm->_gfx->_palette); + _vm->_gfx->setPalette(_vm->_gfx->_palette); _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); - g_system->delayMillis(2000); - if (_vm->getPlatform() == Common::kPlatformPC) { - - _vm->_disk->loadSlide("lingua"); - _vm->_gfx->extendPalette(_vm->_gfx->_palette); - _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); - - _vm->_gfx->displayString(60, 30, "SELECT LANGUAGE"); - - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); - _language = chooseLanguage(); - - _vm->_disk->setLanguage(_language); - - if (selectGame() == 0) { - newGame(); - } - } else { - _vm->_disk->setLanguage(1); - } - - return; } void Menu::newGame() { + if (_vm->getFeatures() & GF_DEMO) { + // character screen is not shown on demo + // so user warps to the playable intro + strcpy(_vm->_location._name, "fognedemo"); + return; + } + const char **v14 = introMsg3; _vm->_disk->loadScenery("test", NULL); - _vm->_gfx->extendPalette(_vm->_gfx->_palette); + _vm->_gfx->setPalette(_vm->_gfx->_palette); _vm->_gfx->swapBuffers(); - uint16 _ax = (SCREEN_WIDTH - _vm->_gfx->getStringWidth(v14[0])) / 2; - _vm->_gfx->displayString(_ax, 50, v14[0]); - - _ax = (SCREEN_WIDTH - _vm->_gfx->getStringWidth(v14[1])) / 2; - _vm->_gfx->displayString(_ax, 70, v14[1]); - - _ax = (SCREEN_WIDTH - _vm->_gfx->getStringWidth(v14[2])) / 2; - _vm->_gfx->displayString(_ax, 100, v14[2]); - - _ax = (SCREEN_WIDTH - _vm->_gfx->getStringWidth(v14[3])) / 2; - _vm->_gfx->displayString(_ax, 120, v14[3]); + _vm->_gfx->displayCenteredString(50, v14[0]); + _vm->_gfx->displayCenteredString(70, v14[1]); + _vm->_gfx->displayCenteredString(100, v14[2]); + _vm->_gfx->displayCenteredString(120, v14[3]); + _vm->_gfx->updateScreen(); _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - _mouseButtons = kMouseNone; for (; _mouseButtons != kMouseLeftUp; ) { @@ -174,8 +160,10 @@ void Menu::newGame() { if (_mouseButtons == kMouseRightUp) break; } - if (_mouseButtons != kMouseRightUp) + if (_mouseButtons != kMouseRightUp) { + strcpy(_vm->_location._name, "fogne"); return; // show intro + } selectCharacter(); @@ -187,6 +175,25 @@ void Menu::newGame() { uint16 Menu::chooseLanguage() { + if (_vm->getPlatform() == Common::kPlatformAmiga) { + // TODO: should return the language ID supported by this version + // this can be done with some flags in the detection structures + return 1; + } + + // user can choose language in dos version + + _vm->_gfx->setFont(kFontMenu); + + _vm->_disk->loadSlide("lingua"); + _vm->_gfx->setPalette(_vm->_gfx->_palette); + _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); + + _vm->_gfx->displayString(60, 30, "SELECT LANGUAGE"); + + _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); + _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); + _vm->changeCursor(kCursorArrow); do { @@ -220,9 +227,12 @@ uint16 Menu::chooseLanguage() { uint16 Menu::selectGame() { // printf("selectGame()\n"); + if (_vm->getFeatures() & GF_DEMO) { + return 0; // can't load a savegame in demo versions + } _vm->_disk->loadSlide("restore"); - _vm->_gfx->extendPalette(_vm->_gfx->_palette); + _vm->_gfx->setPalette(_vm->_gfx->_palette); _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); @@ -255,6 +265,7 @@ uint16 Menu::selectGame() { _vm->_gfx->displayString(60, 30, newGameMsg[_language]); } + _vm->_gfx->updateScreen(); _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); } @@ -263,6 +274,11 @@ uint16 Menu::selectGame() { // load game + // TODO: allow the user to change her mind in this screen, that is + // don't force her to start at the intro when she closes her load + // game window without picking a savegame. + // The 2 strcpy's below act as workaround to prevent crashes for + // time being. strcpy(_vm->_location._name, "fogne"); strcpy(_vm->_characterName, "dough"); @@ -276,6 +292,7 @@ uint16 Menu::selectGame() { // character selection and protection // void Menu::selectCharacter() { + debugC(1, kDebugMenu, "Menu::selectCharacter()"); uint16 _di = 0; bool askPassword = true; @@ -291,10 +308,9 @@ void Menu::selectCharacter() { v14._height = BLOCK_HEIGHT; _vm->changeCursor(kCursorArrow); - _vm->_midiPlayer->stop(); + _vm->_soundMan->stopMusic(); - _vm->_gfx->_proportionalFont = false; - _vm->_gfx->setFont("slide"); + _vm->_gfx->setFont(kFontMenu); _vm->_disk->selectArchive((_vm->getPlatform() == Common::kPlatformPC) ? "disk1" : "disk0"); @@ -302,7 +318,7 @@ void Menu::selectCharacter() { _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); // _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); // - _vm->_gfx->extendPalette(_vm->_gfx->_palette); + _vm->_gfx->setPalette(_vm->_gfx->_palette); while (askPassword == true) { @@ -359,6 +375,7 @@ void Menu::selectCharacter() { _vm->_gfx->copyScreen(Gfx::kBit2, Gfx::kBitFront); _vm->_gfx->displayString(60, 30, introMsg2[_language]); + _vm->_gfx->updateScreen(); g_system->delayMillis(2000); diff --git a/engines/parallaction/menu.h b/engines/parallaction/menu.h index 666305e693..8f9c870a84 100644 --- a/engines/parallaction/menu.h +++ b/engines/parallaction/menu.h @@ -41,6 +41,7 @@ public: void selectCharacter(); protected: + void splash(); void newGame(); uint16 chooseLanguage(); uint16 selectGame(); diff --git a/engines/parallaction/module.mk b/engines/parallaction/module.mk index b95cfb7c30..592c0cb6a3 100644 --- a/engines/parallaction/module.mk +++ b/engines/parallaction/module.mk @@ -9,15 +9,16 @@ MODULE_OBJS := \ detection.o \ dialogue.o \ disk.o \ + font.o \ graphics.o \ intro.o \ inventory.o \ location.o \ menu.o \ - music.o \ parser.o \ parallaction.o \ saveload.o \ + sound.o \ staticres.o \ walk.o \ zone.o diff --git a/engines/parallaction/music.cpp b/engines/parallaction/music.cpp deleted file mode 100644 index b203b453be..0000000000 --- a/engines/parallaction/music.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2006 The ScummVM project - * - * 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/stdafx.h" -#include "common/file.h" -#include "parallaction/parallaction.h" - -#include "common/stream.h" - -#include "sound/midiparser.h" - -#include "parallaction/music.h" - - -namespace Parallaction { - -MidiPlayer::MidiPlayer(MidiDriver *driver) - : _driver(driver), _parser(0), _midiData(0), _isLooping(false), _isPlaying(false), _masterVolume(0) { - assert(_driver); - memset(_channelsTable, 0, sizeof(_channelsTable)); - memset(_channelsVolume, 0, sizeof(_channelsVolume)); - - open(); -} - -MidiPlayer::~MidiPlayer() { - close(); -} - -void MidiPlayer::play(const char *filename) { - stop(); - - if (!scumm_strnicmp(_vm->_location._name, "museo", 5)) return; - if (!scumm_strnicmp(_vm->_location._name, "intgrottadopo", 13)) return; - if (!scumm_strnicmp(_vm->_location._name, "caveau", 6)) return; - if (!scumm_strnicmp(_vm->_location._name, "estgrotta", 9)) return; - if (!scumm_strnicmp(_vm->_location._name, "plaza1", 6)) return; - if (!scumm_strnicmp(_vm->_location._name, "endtgz", 6)) return; - - char path[PATH_LEN]; - sprintf(path, "%s.mid", filename); - - Common::File stream; - - if (!stream.open(path)) - return; - - int size = stream.size(); - - _midiData = (uint8 *)malloc(size); - if (_midiData) { - stream.read(_midiData, size); - _mutex.lock(); - _parser->loadMusic(_midiData, size); - _parser->setTrack(0); - _isLooping = true; - _isPlaying = true; - _mutex.unlock(); - } -} - -void MidiPlayer::stop() { - _mutex.lock(); - if (_isPlaying) { - _isPlaying = false; - _parser->unloadMusic(); - free(_midiData); - _midiData = 0; - } - _mutex.unlock(); -} - -void MidiPlayer::updateTimer() { - _mutex.lock(); - if (_isPlaying) { - _parser->onTimer(); - } - _mutex.unlock(); -} - -void MidiPlayer::adjustVolume(int diff) { - setVolume(_masterVolume + diff); -} - -void MidiPlayer::setVolume(int volume) { - _masterVolume = CLIP(volume, 0, 255); - _mutex.lock(); - for (int i = 0; i < NUM_CHANNELS; ++i) { - if (_channelsTable[i]) { - _channelsTable[i]->volume(_channelsVolume[i] * _masterVolume / 255); - } - } - _mutex.unlock(); -} - -int MidiPlayer::open() { - int ret = _driver->open(); - if (ret == 0) { - _parser = MidiParser::createParser_SMF(); - _parser->setMidiDriver(this); - _parser->setTimerRate(_driver->getBaseTempo()); - _driver->setTimerCallback(this, &timerCallback); - } - return ret; -} - -void MidiPlayer::close() { - stop(); - _mutex.lock(); - _driver->setTimerCallback(NULL, NULL); - _driver->close(); - _driver = 0; - _parser->setMidiDriver(NULL); - delete _parser; - _mutex.unlock(); -} - -void MidiPlayer::send(uint32 b) { - byte volume, ch = (byte)(b & 0xF); - switch (b & 0xFFF0) { - case 0x07B0: // volume change - volume = (byte)((b >> 16) & 0x7F); - _channelsVolume[ch] = volume; - volume = volume * _masterVolume / 255; - b = (b & 0xFF00FFFF) | (volume << 16); - break; - case 0x7BB0: // all notes off - if (!_channelsTable[ch]) { - // channel not yet allocated, no need to send the event - return; - } - break; - } - - if (!_channelsTable[ch]) { - _channelsTable[ch] = (ch == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); - } - if (_channelsTable[ch]) { - _channelsTable[ch]->send(b); - } -} - -void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) { - switch (type) { - case 0x2F: // end of Track - if (_isLooping) { - _parser->jumpToTick(0); - } else { - stop(); - } - break; - default: -// warning("Unhandled meta event: %02x", type); - break; - } -} - -void MidiPlayer::timerCallback(void *p) { - MidiPlayer *player = (MidiPlayer *)p; - - player->updateTimer(); -} - -} // namespace Parallaction diff --git a/engines/parallaction/music.h b/engines/parallaction/music.h deleted file mode 100644 index eef249a7d4..0000000000 --- a/engines/parallaction/music.h +++ /dev/null @@ -1,80 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2006 The ScummVM project - * - * 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef PARALLACTION_MUSIC_H -#define PARALLACTION_MUSIC_H - -#include "common/util.h" -#include "common/mutex.h" - -#include "sound/mididrv.h" - -class MidiParser; - -namespace Parallaction { - -class MidiPlayer : public MidiDriver { -public: - - enum { - NUM_CHANNELS = 16 - }; - - MidiPlayer(MidiDriver *driver); - ~MidiPlayer(); - - void play(const char *filename); - void stop(); - void updateTimer(); - void adjustVolume(int diff); - void setVolume(int volume); - int getVolume() const { return _masterVolume; } - void setLooping(bool loop) { _isLooping = loop; } - - // MidiDriver interface - int open(); - void close(); - void send(uint32 b); - void metaEvent(byte type, byte *data, uint16 length); - void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { } - uint32 getBaseTempo() { return _driver ? _driver->getBaseTempo() : 0; } - MidiChannel *allocateChannel() { return 0; } - MidiChannel *getPercussionChannel() { return 0; } - -private: - - static void timerCallback(void *p); - - MidiDriver *_driver; - MidiParser *_parser; - uint8 *_midiData; - bool _isLooping; - bool _isPlaying; - int _masterVolume; - MidiChannel *_channelsTable[NUM_CHANNELS]; - uint8 _channelsVolume[NUM_CHANNELS]; - Common::Mutex _mutex; -}; - -} // namespace Parallaction - -#endif diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index 490ca38e31..1cf285ba57 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -31,14 +31,10 @@ #include "sound/mixer.h" #include "parallaction/parallaction.h" +#include "parallaction/debug.h" #include "parallaction/menu.h" -#include "parallaction/parser.h" -#include "parallaction/disk.h" -#include "parallaction/music.h" -#include "parallaction/inventory.h" -#include "parallaction/graphics.h" -#include "parallaction/walk.h" -#include "parallaction/zone.h" +#include "parallaction/sound.h" + namespace Parallaction { @@ -119,12 +115,15 @@ Parallaction::Parallaction(OSystem *syst) : Common::addSpecialDebugLevel(kDebugGraphics, "gfx", "Gfx debug level"); Common::addSpecialDebugLevel(kDebugJobs, "jobs", "Jobs debug level"); Common::addSpecialDebugLevel(kDebugInput, "input", "Input debug level"); - + Common::addSpecialDebugLevel(kDebugAudio, "audio", "Audio debug level"); + Common::addSpecialDebugLevel(kDebugMenu, "menu", "Menu debug level"); } Parallaction::~Parallaction() { - delete _midiPlayer; + delete _debugger; + + delete _soundMan; delete _disk; delete _globalTable; @@ -139,6 +138,12 @@ Parallaction::~Parallaction() { if (_localFlagNames) delete _localFlagNames; + + delete _gfx; + + freeLocation(); + freeCharacter(); + destroyInventory(); } @@ -163,17 +168,19 @@ int Parallaction::init() { _activeItem._id = 0; _procCurrentHoverItem = -1; - _musicData1 = 0; +// _musicData1 = 0; strcpy(_characterName1, "null"); - _midiPlayer = 0; + _soundMan = 0; _baseTime = 0; if (getPlatform() == Common::kPlatformPC) _disk = new DosDisk(this); - else + else { _disk = new AmigaDisk(this); + _disk->selectArchive("disk0"); + } _engineFlags = 0; @@ -186,11 +193,6 @@ int Parallaction::init() { _location._startPosition.y = -1000; _location._startFrame = 0; - if (getFeatures() & GF_DEMO) - strcpy(_location._name, "fognedemo"); - else - strcpy(_location._name, "fogne"); - _location._comment = NULL; _location._endComment = NULL; @@ -201,11 +203,16 @@ int Parallaction::init() { _animations.push_front(&_vm->_char._ani); _gfx = new Gfx(this); - int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - MidiDriver *driver = MidiDriver::createMidi(midiDriver); - _midiPlayer = new MidiPlayer(driver); + if (getPlatform() == Common::kPlatformPC) { + int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + MidiDriver *driver = MidiDriver::createMidi(midiDriver); + _soundMan = new DosSoundMan(this, driver); + _soundMan->setMusicVolume(ConfMan.getInt("music_volume")); + } else { + _soundMan = new AmigaSoundMan(this); + } - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); + _debugger = new Debugger(this); return 0; } @@ -276,6 +283,8 @@ uint16 Parallaction::updateInput() { case Common::EVENT_KEYDOWN: if (e.kbd.ascii == 'l') KeyDown = kEvLoadGame; if (e.kbd.ascii == 's') KeyDown = kEvSaveGame; + if (e.kbd.flags == Common::KBD_CTRL && e.kbd.keycode == 'd') + _debugger->attach(); break; case Common::EVENT_LBUTTONDOWN: @@ -299,7 +308,7 @@ uint16 Parallaction::updateInput() { break; case Common::EVENT_QUIT: - _system->quit(); + _engineFlags |= kEngineQuit; break; default: @@ -309,6 +318,9 @@ uint16 Parallaction::updateInput() { } + if (_debugger->isAttached()) + _debugger->onFrame(); + return KeyDown; } @@ -326,7 +338,7 @@ void waitUntilLeftClick() { break; if (e.type == Common::EVENT_QUIT) { - g_system->quit(); + _engineFlags |= kEngineQuit; break; } @@ -349,8 +361,6 @@ void Parallaction::runGame() { if (_location._commands.size() > 0) runCommands(_location._commands); - runJobs(); - _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); if (_location._comment) @@ -694,6 +704,7 @@ void Parallaction::changeCursor(int32 index) { void Parallaction::freeCharacter() { + debugC(3, kDebugLocation, "freeCharacter()"); if (!IS_DUMMY_CHARACTER(_vm->_characterName)) { if (_objectsNames) @@ -702,66 +713,27 @@ void Parallaction::freeCharacter() { if (_vm->_char._ani._cnv) delete _vm->_char._ani._cnv; + _vm->_char._ani._cnv = NULL; if (_vm->_char._talk) delete _vm->_char._talk; + _vm->_char._talk = NULL; _vm->_gfx->freeStaticCnv(_vm->_char._head); if (_vm->_char._head) delete _vm->_char._head; + _vm->_char._head = NULL; if (_vm->_char._objs) delete _vm->_char._objs; + _vm->_char._objs = NULL; } return; } -void Parallaction::selectCharacterMusic(const char *name) { - if (IS_MINI_CHARACTER(name)) - name+=4; - - if (!scumm_stricmp(name, _dinoName)) { - _midiPlayer->play("dino"); - } else if (!scumm_stricmp(name, _donnaName)) { - _midiPlayer->play("donna"); - } else { - _midiPlayer->play("nuts"); - } - - return; -} - -void Parallaction::pickMusic(const char *location) { - if (_musicData1 != 0) { - selectCharacterMusic(_vm->_characterName); - _musicData1 = 0; - debugC(2, kDebugLocation, "changeLocation: started character specific music"); - } - - if (!scumm_stricmp(location, "night") || !scumm_stricmp(location, "intsushi")) { - _vm->_midiPlayer->play("soft"); - - debugC(2, kDebugLocation, "changeLocation: started music 'soft'"); - } - - if (!scumm_stricmp(location, "museo") || - !scumm_stricmp(location, "caveau") || - !scumm_strnicmp(location, "plaza1", 6) || - !scumm_stricmp(location, "estgrotta") || - !scumm_stricmp(location, "intgrottadopo") || - !scumm_stricmp(location, "endtgz") || - !scumm_stricmp(location, "common")) { - - _vm->_midiPlayer->stop(); - _musicData1 = 1; - - debugC(2, kDebugLocation, "changeLocation: music stopped"); - } -} - - void Parallaction::changeCharacter(const char *name) { + debugC(1, kDebugLocation, "changeCharacter(%s)", name); char baseName[20]; if (IS_MINI_CHARACTER(name)) { @@ -782,6 +754,7 @@ void Parallaction::changeCharacter(const char *name) { freeCharacter(); _disk->selectArchive((_vm->getPlatform() == Common::kPlatformPC) ? "disk1" : "disk0"); + _vm->_char._ani._cnv = _disk->loadFrames(fullName); if (!IS_DUMMY_CHARACTER(name)) { _vm->_char._head = _disk->loadHead(baseName); @@ -790,18 +763,17 @@ void Parallaction::changeCharacter(const char *name) { _objectsNames = _disk->loadTable(baseName); refreshInventory(baseName); - _vm->_char._ani._cnv = _disk->loadFrames(fullName); + _soundMan->playCharacterMusic(name); - if (scumm_stricmp(name, "night") && scumm_stricmp(name, "intsushi")) - selectCharacterMusic(name); + if ((getFeatures() & GF_DEMO) == 0) + parseLocation("common"); } } - if (!(getFeatures() & GF_DEMO)) - parseLocation("common"); - strcpy(_characterName1, fullName); + debugC(1, kDebugLocation, "changeCharacter() done"); + return; } @@ -810,11 +782,11 @@ void Parallaction::changeCharacter(const char *name) { (higher priorities values comes first in the list) */ int compareJobPriority(const JobPointer &j1, const JobPointer &j2) { - if (j1->_tag == j2->_tag) return 0; return (j1->_tag >= j2->_tag ? -1 : 1); } Job *Parallaction::addJob(JobFn fn, void *parm, uint16 tag) { + debugC(3, kDebugJobs, "addJob(%i)", tag); Job *v8 = new Job; @@ -830,16 +802,22 @@ Job *Parallaction::addJob(JobFn fn, void *parm, uint16 tag) { } void Parallaction::removeJob(Job *j) { + debugC(3, kDebugJobs, "addJob(%i)", j->_tag); + j->_finished = 1; return; } void Parallaction::pauseJobs() { + debugC(3, kDebugJobs, "pausing jobs execution"); + _engineFlags |= kEnginePauseJobs; return; } void Parallaction::resumeJobs() { + debugC(3, kDebugJobs, "resuming jobs execution"); + _engineFlags &= ~kEnginePauseJobs; return; } @@ -858,7 +836,7 @@ void Parallaction::runJobs() { it = _jobs.begin(); while (it != _jobs.end()) { - debugC(3, kDebugJobs, "runJobs: %i", (*it)->_tag); + debugC(9, kDebugJobs, "runJobs: %i", (*it)->_tag); (*(*it)->_fn)((*it)->_parm, (*it)); it++; } diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index 0a63ee9380..6a64ced769 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -51,7 +51,9 @@ enum { kDebugDialogue = 1 << 3, kDebugGraphics = 1 << 4, kDebugJobs = 1 << 5, - kDebugInput = 1 << 6 + kDebugInput = 1 << 6, + kDebugAudio = 1 << 7, + kDebugMenu = 1 << 8 }; enum { @@ -196,8 +198,6 @@ extern const char *_minidrkiName; #define IS_MINI_CHARACTER(s) (((s)[0] == 'm')) #define IS_DUMMY_CHARACTER(s) (((s)[0] == 'D')) -#define PATH_LEN 200 - void waitUntilLeftClick(); @@ -216,9 +216,10 @@ void jobEraseLabel(void *parm, Job *j); +class Debugger; class Gfx; class Menu; -class MidiPlayer; +class SoundMan; @@ -283,6 +284,7 @@ public: class Parallaction : public Engine { + friend class Debugger; public: @@ -313,6 +315,11 @@ public: void resumeJobs(); void runJobs(); + void setPath(byte *path); + void finalizeWalk(WalkNodeList *list); + int16 selectWalkFrame(const Common::Point& pos, const WalkNode* from); + void clipMove(Common::Point& pos, const WalkNode* from); + Zone *findZone(const char *name); Zone *hitZone(uint32 type, uint16 x, uint16 y); uint16 runZone(Zone*); @@ -347,8 +354,7 @@ private: const PARALLACTIONGameDescription *_gameDescription; public: - - MidiPlayer *_midiPlayer; + SoundMan *_soundMan; Gfx* _gfx; Menu* _menu; @@ -371,6 +377,8 @@ public: protected: // data + Debugger *_debugger; + struct InputData { uint16 _event; Common::Point _mousePos; @@ -391,35 +399,32 @@ protected: // data int16 _transCurrentHoverItem; uint32 _baseTime; - - uint16 _musicData1; // only used in changeLocation char _characterName1[50]; // only used in changeCharacter int16 _keyDown; JobList _jobs; + Common::String _saveFileName; + + protected: // members bool detectGame(void); void initGame(); void initGlobals(); - - Common::String _saveFileName; - int buildSaveFileList(Common::StringList& l); - int selectSaveFile(uint16 arg_0, const char* caption, const char* button); - void doLoadGame(uint16 slot); - void doSaveGame(uint16 slot, const char* name); - + void initResources(); void runGame(); + uint32 getElapsedTime(); + void resetTimer(); InputData *translateInput(); void processInput(InputData*); - int16 getHoverInventoryItem(int16 x, int16 y); - - uint32 getElapsedTime(); - void resetTimer(); + int buildSaveFileList(Common::StringList& l); + int selectSaveFile(uint16 arg_0, const char* caption, const char* button); + void doLoadGame(uint16 slot); + void doSaveGame(uint16 slot, const char* name); void doLocationEnterTransition(); void changeLocation(char *location); @@ -430,10 +435,13 @@ protected: // members void parseZone(Script &script, ZoneList &list, char *name); void parseZoneTypeBlock(Script &script, Zone *z); - void parseWalkNodes(Script& script, WalkNodeList &list); void displayCharacterComment(ExamineData *data); void displayItemComment(ExamineData *data); + void parseWalkNodes(Script& script, WalkNodeList &list); + void initWalk(); + uint16 checkDoor(); + Animation * parseAnimation(Script &script, AnimationList &list, char *name); void parseScriptLine(Instruction *inst, Animation *a, LocalVariable *locals); void loadProgram(Animation *a, char *filename); @@ -441,13 +449,8 @@ protected: // members void parseCommands(Script &script, CommandList&); - void pickMusic(const char *location); - void selectCharacterMusic(const char *name); - void freeCharacter(); - void initResources(); - uint16 askDialoguePassword(Dialogue *q, StaticCnv *face); bool displayAnswer(Dialogue *q, uint16 i); bool displayAnswers(Dialogue *q); @@ -457,10 +460,11 @@ protected: // members void enterDialogue(); void exitDialogue(); - void addInventoryItem(uint16 item); + int addInventoryItem(uint16 item); void dropItem(uint16 item); int16 pickupItem(Zone *z); int16 isItemInInventory(int32 v); + int16 getHoverInventoryItem(int16 x, int16 y); }; // FIXME: remove global diff --git a/engines/parallaction/parser.cpp b/engines/parallaction/parser.cpp index 45b19544a3..f913e4abd0 100644 --- a/engines/parallaction/parser.cpp +++ b/engines/parallaction/parser.cpp @@ -20,10 +20,10 @@ * */ -#include "parallaction/defs.h" -#include "parallaction/parser.h" +#include "common/stdafx.h" + #include "parallaction/parallaction.h" -#include "parallaction/disk.h" + namespace Parallaction { diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h index a6a2019743..e5a2577ca2 100644 --- a/engines/parallaction/parser.h +++ b/engines/parallaction/parser.h @@ -29,7 +29,6 @@ namespace Parallaction { -char *parseNextLine(char *s, uint16 count); uint16 fillBuffers(Common::SeekableReadStream &stream, bool errorOnEOF = false); char *parseNextToken(char *s, char *tok, uint16 count, const char *brk); diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp index db1cd636b0..251f35a24e 100644 --- a/engines/parallaction/saveload.cpp +++ b/engines/parallaction/saveload.cpp @@ -28,9 +28,7 @@ #include "gui/message.h" #include "parallaction/parallaction.h" -#include "parallaction/disk.h" -#include "parallaction/graphics.h" -#include "parallaction/zone.h" + /* Nippon Safes savefiles are called 'game.0' to 'game.9'. The game conventiently allows users to * give meanigful name to savegames, and it uses an extra file 'savegame' to keep track of these diff --git a/engines/parallaction/sound.cpp b/engines/parallaction/sound.cpp new file mode 100644 index 0000000000..fec03e9291 --- /dev/null +++ b/engines/parallaction/sound.cpp @@ -0,0 +1,418 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/file.h" + +#include "common/stream.h" + +#include "sound/mixer.h" +#include "sound/midiparser.h" +#include "sound/mods/protracker.h" + +#include "parallaction/sound.h" +#include "parallaction/parallaction.h" + + +namespace Parallaction { + +class MidiPlayer : public MidiDriver { +public: + + enum { + NUM_CHANNELS = 16 + }; + + MidiPlayer(MidiDriver *driver); + ~MidiPlayer(); + + void play(const char *filename); + void stop(); + void updateTimer(); + void adjustVolume(int diff); + void setVolume(int volume); + int getVolume() const { return _masterVolume; } + void setLooping(bool loop) { _isLooping = loop; } + + // MidiDriver interface + int open(); + void close(); + void send(uint32 b); + void metaEvent(byte type, byte *data, uint16 length); + void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { } + uint32 getBaseTempo() { return _driver ? _driver->getBaseTempo() : 0; } + MidiChannel *allocateChannel() { return 0; } + MidiChannel *getPercussionChannel() { return 0; } + +private: + + static void timerCallback(void *p); + + MidiDriver *_driver; + MidiParser *_parser; + uint8 *_midiData; + bool _isLooping; + bool _isPlaying; + int _masterVolume; + MidiChannel *_channelsTable[NUM_CHANNELS]; + uint8 _channelsVolume[NUM_CHANNELS]; + Common::Mutex _mutex; +}; + +MidiPlayer::MidiPlayer(MidiDriver *driver) + : _driver(driver), _parser(0), _midiData(0), _isLooping(false), _isPlaying(false), _masterVolume(0) { + assert(_driver); + memset(_channelsTable, 0, sizeof(_channelsTable)); + memset(_channelsVolume, 0, sizeof(_channelsVolume)); + + open(); +} + +MidiPlayer::~MidiPlayer() { + close(); +} + +void MidiPlayer::play(const char *filename) { + stop(); + + if (!scumm_strnicmp(_vm->_location._name, "museo", 5)) return; + if (!scumm_strnicmp(_vm->_location._name, "intgrottadopo", 13)) return; + if (!scumm_strnicmp(_vm->_location._name, "caveau", 6)) return; + if (!scumm_strnicmp(_vm->_location._name, "estgrotta", 9)) return; + if (!scumm_strnicmp(_vm->_location._name, "plaza1", 6)) return; + if (!scumm_strnicmp(_vm->_location._name, "endtgz", 6)) return; + + char path[PATH_LEN]; + sprintf(path, "%s.mid", filename); + + Common::File stream; + + if (!stream.open(path)) + return; + + int size = stream.size(); + + _midiData = (uint8 *)malloc(size); + if (_midiData) { + stream.read(_midiData, size); + _mutex.lock(); + _parser->loadMusic(_midiData, size); + _parser->setTrack(0); + _isLooping = true; + _isPlaying = true; + _mutex.unlock(); + } +} + +void MidiPlayer::stop() { + _mutex.lock(); + if (_isPlaying) { + _isPlaying = false; + _parser->unloadMusic(); + free(_midiData); + _midiData = 0; + } + _mutex.unlock(); +} + +void MidiPlayer::updateTimer() { + _mutex.lock(); + if (_isPlaying) { + _parser->onTimer(); + } + _mutex.unlock(); +} + +void MidiPlayer::adjustVolume(int diff) { + setVolume(_masterVolume + diff); +} + +void MidiPlayer::setVolume(int volume) { + _masterVolume = CLIP(volume, 0, 255); + _mutex.lock(); + for (int i = 0; i < NUM_CHANNELS; ++i) { + if (_channelsTable[i]) { + _channelsTable[i]->volume(_channelsVolume[i] * _masterVolume / 255); + } + } + _mutex.unlock(); +} + +int MidiPlayer::open() { + int ret = _driver->open(); + if (ret == 0) { + _parser = MidiParser::createParser_SMF(); + _parser->setMidiDriver(this); + _parser->setTimerRate(_driver->getBaseTempo()); + _driver->setTimerCallback(this, &timerCallback); + } + return ret; +} + +void MidiPlayer::close() { + stop(); + _mutex.lock(); + _driver->setTimerCallback(NULL, NULL); + _driver->close(); + _driver = 0; + _parser->setMidiDriver(NULL); + delete _parser; + _mutex.unlock(); +} + +void MidiPlayer::send(uint32 b) { + byte volume, ch = (byte)(b & 0xF); + switch (b & 0xFFF0) { + case 0x07B0: // volume change + volume = (byte)((b >> 16) & 0x7F); + _channelsVolume[ch] = volume; + volume = volume * _masterVolume / 255; + b = (b & 0xFF00FFFF) | (volume << 16); + break; + case 0x7BB0: // all notes off + if (!_channelsTable[ch]) { + // channel not yet allocated, no need to send the event + return; + } + break; + } + + if (!_channelsTable[ch]) { + _channelsTable[ch] = (ch == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); + } + if (_channelsTable[ch]) { + _channelsTable[ch]->send(b); + } +} + +void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) { + switch (type) { + case 0x2F: // end of Track + if (_isLooping) { + _parser->jumpToTick(0); + } else { + stop(); + } + break; + default: +// warning("Unhandled meta event: %02x", type); + break; + } +} + +void MidiPlayer::timerCallback(void *p) { + MidiPlayer *player = (MidiPlayer *)p; + + player->updateTimer(); +} + + +DosSoundMan::DosSoundMan(Parallaction *vm, MidiDriver *midiDriver) : SoundMan(vm), _musicData1(0) { + _midiPlayer = new MidiPlayer(midiDriver); +} + +DosSoundMan::~DosSoundMan() { + debugC(1, kDebugAudio, "DosSoundMan::playMusic()"); + + delete _midiPlayer; +} + +void DosSoundMan::playMusic() { + debugC(1, kDebugAudio, "DosSoundMan::playMusic()"); + + _midiPlayer->play(_musicFile); +} + +void DosSoundMan::stopMusic() { + _midiPlayer->stop(); +} + +void DosSoundMan::playCharacterMusic(const char *character) { + + if (!scumm_stricmp(_vm->_location._name, "night") || + !scumm_stricmp(_vm->_location._name, "intsushi")) { + return; + } + + char *name = const_cast<char*>(character); + + if (IS_MINI_CHARACTER(name)) + name+=4; + + if (!scumm_stricmp(name, _dinoName)) { + setMusicFile("dino"); + } else + if (!scumm_stricmp(name, _donnaName)) { + setMusicFile("dough"); + } else + if (!scumm_stricmp(name, _doughName)) { + setMusicFile("nuts"); + } else { + warning("unknown character '%s' in DosSoundMan::playCharacterMusic", character); + return; + } + + playMusic(); +} + +void DosSoundMan::playLocationMusic(const char *location) { + if (_musicData1 != 0) { + playCharacterMusic(_vm->_characterName); + _musicData1 = 0; + debugC(2, kDebugLocation, "changeLocation: started character specific music"); + } + + if (!scumm_stricmp(location, "night") || !scumm_stricmp(location, "intsushi")) { + setMusicFile("nuts"); + playMusic(); + + debugC(2, kDebugLocation, "changeLocation: started music 'soft'"); + } + + if (!scumm_stricmp(location, "museo") || + !scumm_stricmp(location, "caveau") || + !scumm_strnicmp(location, "plaza1", 6) || + !scumm_stricmp(location, "estgrotta") || + !scumm_stricmp(location, "intgrottadopo") || + !scumm_stricmp(location, "endtgz") || + !scumm_stricmp(location, "common")) { + + stopMusic(); + _musicData1 = 1; + + debugC(2, kDebugLocation, "changeLocation: music stopped"); + } +} + +AmigaSoundMan::AmigaSoundMan(Parallaction *vm) : SoundMan(vm) { + _musicStream = 0; + _channels[0].data = 0; + _channels[1].data = 0; + _channels[2].data = 0; + _channels[3].data = 0; +} + +AmigaSoundMan::~AmigaSoundMan() { + stopMusic(); + stopSfx(0); + stopSfx(1); + stopSfx(2); + stopSfx(3); +} + +void AmigaSoundMan::playSfx(const char *filename, uint channel, bool looping, int volume, int rate) { + if (channel >= NUM_AMIGA_CHANNELS) { + warning("unknown sfx channel"); + return; + } + + debugC(1, kDebugAudio, "AmigaSoundMan::playSfx(%s, %i)", filename, channel); + + Channel *ch = &_channels[channel]; + Common::ReadStream *stream = _vm->_disk->loadSound(filename); + Audio::A8SVXDecoder decoder(*stream, ch->header, ch->data, ch->dataSize); + decoder.decode(); + delete stream; + + uint32 loopStart, loopEnd, flags; + if (looping) { + // the standard way to loop 8SVX audio implies use of the oneShotHiSamples and + // repeatHiSamples fields, but Nippon Safes handles loops according to flags + // set in its location scripts and always operates on the whole data. + loopStart = 0; + loopEnd = ch->header.oneShotHiSamples + ch->header.repeatHiSamples; + flags = Audio::Mixer::FLAG_LOOP; + } else { + loopStart = loopEnd = 0; + flags = 0; + } + + if (volume == -1) { + volume = ch->header.volume; + } + + if (rate == -1) { + rate = ch->header.samplesPerSec; + } + + _mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize, rate, flags, -1, volume, 0, loopStart, loopEnd); +} + +void AmigaSoundMan::stopSfx(uint channel) { + if (channel >= NUM_AMIGA_CHANNELS) { + warning("unknown sfx channel"); + return; + } + + if (_channels[channel].data) { + debugC(1, kDebugAudio, "AmigaSoundMan::stopSfx(%i)", channel); + _mixer->stopHandle(_channels[channel].handle); + free(_channels[channel].data); + _channels[channel].data = 0; + } +} + +void AmigaSoundMan::playMusic() { + stopMusic(); + + debugC(1, kDebugAudio, "AmigaSoundMan::playMusic()"); + + Common::ReadStream *stream = _vm->_disk->loadMusic(_musicFile); + _musicStream = Audio::makeProtrackerStream(stream); + delete stream; + + debugC(3, kDebugAudio, "AmigaSoundMan::playMusic(): created new music stream"); + + _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, _musicStream, -1, 255, 0, false, false); +} + +void AmigaSoundMan::stopMusic() { + debugC(1, kDebugAudio, "AmigaSoundMan::stopMusic()"); + + if (_mixer->isSoundHandleActive(_musicHandle)) { + _mixer->stopHandle(_musicHandle); + delete _musicStream; + _musicStream = 0; + } +} + +void AmigaSoundMan::playCharacterMusic(const char *character) { +} + +void AmigaSoundMan::playLocationMusic(const char *location) { +} + + +SoundMan::SoundMan(Parallaction *vm) : _vm(vm) { + _mixer = _vm->_mixer; +} + +void SoundMan::setMusicVolume(int value) { + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, value); +} + +void SoundMan::setMusicFile(const char *filename) { + strcpy(_musicFile, filename); +} + + +} // namespace Parallaction diff --git a/engines/parallaction/sound.h b/engines/parallaction/sound.h new file mode 100644 index 0000000000..ae2f9c8716 --- /dev/null +++ b/engines/parallaction/sound.h @@ -0,0 +1,110 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef PARALLACTION_MUSIC_H +#define PARALLACTION_MUSIC_H + +#include "common/util.h" +#include "common/mutex.h" + +#include "sound/audiostream.h" +#include "sound/iff.h" +#include "sound/mixer.h" +#include "sound/mididrv.h" + +#include "parallaction/defs.h" + +class MidiParser; + +namespace Parallaction { + +class Parallaction; +class MidiPlayer; + +class SoundMan { + +protected: + Parallaction *_vm; + Audio::Mixer *_mixer; + char _musicFile[PATH_LEN]; + +public: + SoundMan(Parallaction *vm); + virtual ~SoundMan() {} + + virtual void playSfx(const char *filename, uint channel, bool looping, int volume = -1, int rate = -1) { } + virtual void stopSfx(uint channel) { } + + void setMusicFile(const char *filename); + virtual void playMusic() = 0; + virtual void stopMusic() = 0; + virtual void playCharacterMusic(const char *character) = 0; + virtual void playLocationMusic(const char *location) = 0; + void setMusicVolume(int value); +}; + +class DosSoundMan : public SoundMan { + + MidiPlayer *_midiPlayer; + int _musicData1; + +public: + DosSoundMan(Parallaction *vm, MidiDriver *midiDriver); + ~DosSoundMan(); + void playMusic(); + void stopMusic(); + + void playCharacterMusic(const char *character); + void playLocationMusic(const char *location); +}; + +#define NUM_AMIGA_CHANNELS 4 + +class AmigaSoundMan : public SoundMan { + + Audio::AudioStream *_musicStream; + Audio::SoundHandle _musicHandle; + + struct Channel { + Audio::Voice8Header header; + byte *data; + uint32 dataSize; + Audio::SoundHandle handle; + uint32 flags; + } _channels[NUM_AMIGA_CHANNELS]; + +public: + AmigaSoundMan(Parallaction *vm); + ~AmigaSoundMan(); + void playMusic(); + void stopMusic(); + + void playSfx(const char *filename, uint channel, bool looping, int volume, int rate); + void stopSfx(uint channel); + + void playCharacterMusic(const char *character); + void playLocationMusic(const char *location); +}; + +} // namespace Parallaction + +#endif diff --git a/engines/parallaction/staticres.cpp b/engines/parallaction/staticres.cpp index 9c3bc47b60..00317521a2 100644 --- a/engines/parallaction/staticres.cpp +++ b/engines/parallaction/staticres.cpp @@ -23,7 +23,6 @@ #include "common/stdafx.h" #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" namespace Parallaction { @@ -48,6 +47,174 @@ byte Gfx::_mouseArrow[256] = { }; +byte _amigaTopazFont[2600] = +{ + 0x00, 0x00, 0x03, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x79, 0x00, 0x00, 0x03, 0xe9, 0x00, 0x00, 0x02, 0x79, + 0x70, 0xff, 0x4e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x1a, 0x0f, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x45, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x09, 0x74, 0x00, 0x08, + 0x00, 0x40, 0x00, 0x08, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x20, 0xff, 0x00, 0x00, 0x00, 0x6e, + 0x00, 0xbe, 0x00, 0x00, 0x06, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x6c, 0x6c, 0x18, 0x00, 0x38, 0x18, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3c, 0x18, + 0x3c, 0x3c, 0x1c, 0x7e, 0x1c, 0x7e, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7c, 0x3c, + 0x7c, 0x1e, 0x78, 0x7e, 0x7e, 0x3c, 0x66, 0x3c, 0x06, 0xc6, 0x60, 0xc6, 0xc6, 0x3c, 0x7c, 0x78, + 0x7c, 0x3c, 0x7e, 0x66, 0x66, 0xc6, 0xc3, 0xc3, 0xfe, 0x3c, 0xc0, 0x3c, 0x10, 0x00, 0x18, 0x00, + 0x60, 0x00, 0x06, 0x00, 0x1c, 0x00, 0x60, 0x18, 0x0c, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x70, 0x72, 0x0f, 0x00, 0x18, + 0x00, 0x1c, 0x42, 0xc3, 0x18, 0x3c, 0x66, 0x7e, 0x1c, 0x00, 0x3e, 0x7e, 0x7e, 0x3c, 0x18, 0x78, + 0x78, 0x18, 0x00, 0x3e, 0x00, 0x00, 0x30, 0x38, 0x00, 0x40, 0x40, 0xc0, 0x18, 0x3c, 0x3c, 0x7e, + 0x06, 0x66, 0x18, 0x7e, 0x7e, 0x36, 0x0c, 0x0c, 0x18, 0x3c, 0xc6, 0x3c, 0x60, 0x76, 0x18, 0x00, + 0x0c, 0x7e, 0x71, 0x66, 0x00, 0x66, 0x60, 0x0e, 0x7e, 0x66, 0x18, 0x6e, 0x3c, 0x00, 0x18, 0x7e, + 0x06, 0x66, 0x18, 0x00, 0x7e, 0x34, 0x0c, 0x0c, 0x18, 0x0c, 0x60, 0x00, 0x18, 0x3c, 0x0c, 0x00, + 0x0c, 0x00, 0x71, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x7e, 0x00, 0x18, 0x3c, 0x00, 0x18, 0x6c, 0x6c, + 0x3e, 0x66, 0x6c, 0x18, 0x18, 0x18, 0x66, 0x18, 0x00, 0x00, 0x00, 0x06, 0x66, 0x38, 0x66, 0x66, + 0x3c, 0x60, 0x30, 0x06, 0x66, 0x66, 0x18, 0x18, 0x06, 0x00, 0x60, 0x66, 0xc6, 0x66, 0x66, 0x30, + 0x6c, 0x60, 0x60, 0x66, 0x66, 0x18, 0x06, 0xcc, 0x60, 0xee, 0xe6, 0x66, 0x66, 0xcc, 0x66, 0x66, + 0x18, 0x66, 0x66, 0xc6, 0x66, 0x66, 0x0c, 0x30, 0x60, 0x0c, 0x38, 0x00, 0x18, 0x00, 0x60, 0x00, + 0x06, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x9c, 0x3c, 0x7e, 0x00, 0x0c, 0x36, + 0x3c, 0x66, 0x18, 0x60, 0x66, 0x81, 0x24, 0x33, 0x06, 0x81, 0x00, 0x66, 0x18, 0x0c, 0x0c, 0x30, + 0x00, 0x7a, 0x00, 0x00, 0x70, 0x44, 0xcc, 0xc6, 0xc6, 0x23, 0x00, 0x66, 0x18, 0x00, 0x1c, 0x00, + 0x24, 0x60, 0x00, 0x1c, 0x18, 0x18, 0x00, 0x66, 0xcc, 0x00, 0x60, 0x3c, 0x30, 0xc6, 0x18, 0x00, + 0x8e, 0x00, 0xc6, 0x66, 0x60, 0x38, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x24, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x7e, + 0x8e, 0x66, 0x18, 0x00, 0x18, 0x18, 0x00, 0x66, 0x00, 0x18, 0x00, 0x18, 0x00, 0xfe, 0x60, 0xac, + 0x68, 0x30, 0x30, 0x0c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x6e, 0x78, 0x06, 0x06, 0x6c, 0x7c, + 0x60, 0x06, 0x66, 0x66, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x06, 0xde, 0x66, 0x66, 0x60, 0x66, 0x60, + 0x60, 0x60, 0x66, 0x18, 0x06, 0xd8, 0x60, 0xfe, 0xf6, 0x66, 0x66, 0xcc, 0x66, 0x70, 0x18, 0x66, + 0x66, 0xc6, 0x3c, 0x3c, 0x18, 0x30, 0x30, 0x0c, 0x6c, 0x00, 0x0c, 0x3c, 0x7c, 0x3c, 0x3e, 0x3c, + 0x7c, 0x3e, 0x7c, 0x18, 0x0c, 0x66, 0x18, 0xec, 0x7c, 0x3c, 0x7c, 0x3e, 0x7c, 0x3c, 0x7c, 0x66, + 0x66, 0xc6, 0xc6, 0x66, 0x7e, 0x18, 0x18, 0x18, 0x00, 0xf0, 0x66, 0x18, 0x3e, 0x30, 0x66, 0x3c, + 0x18, 0x3c, 0x00, 0x9d, 0x44, 0x66, 0x00, 0xb9, 0x00, 0x3c, 0x7e, 0x18, 0x18, 0x60, 0x66, 0x7a, + 0x18, 0x00, 0x30, 0x44, 0x66, 0x4c, 0x4c, 0x66, 0x18, 0x66, 0x18, 0x3c, 0x3c, 0x3c, 0x3c, 0x60, + 0x7e, 0x3c, 0x7e, 0x7e, 0x7e, 0x60, 0xd8, 0x3c, 0x60, 0x66, 0xc6, 0xe6, 0x3c, 0x3c, 0x3c, 0x3c, + 0x6c, 0x66, 0x6c, 0x66, 0x66, 0x66, 0x7e, 0x7e, 0x66, 0x3c, 0x18, 0x3c, 0x18, 0x3c, 0x3c, 0x3c, + 0x3c, 0x18, 0x3c, 0x7e, 0x3c, 0x3e, 0x6c, 0x00, 0x18, 0x3c, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x1e, 0x3c, 0x66, 0x00, 0x7e, 0x7e, 0x00, 0x18, 0x00, 0x6c, 0x3c, 0xd8, 0x76, 0x00, + 0x30, 0x0c, 0xff, 0x7e, 0x00, 0x7e, 0x00, 0x18, 0x7e, 0x18, 0x0c, 0x1c, 0xcc, 0x06, 0x7c, 0x0c, + 0x3c, 0x3e, 0x00, 0x00, 0x60, 0x00, 0x06, 0x0c, 0xd6, 0x7e, 0x7c, 0x60, 0x66, 0x78, 0x78, 0x6e, + 0x7e, 0x18, 0x06, 0xf0, 0x60, 0xd6, 0xde, 0x66, 0x7c, 0xcc, 0x7c, 0x3c, 0x18, 0x66, 0x66, 0xd6, + 0x18, 0x18, 0x30, 0x30, 0x18, 0x0c, 0xc6, 0x00, 0x00, 0x06, 0x66, 0x60, 0x66, 0x66, 0x30, 0x66, + 0x66, 0x18, 0x0c, 0x6c, 0x18, 0xfe, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x30, 0x66, 0x66, 0xc6, + 0x6c, 0x66, 0x0c, 0x70, 0x18, 0x0e, 0x00, 0xc3, 0x66, 0x18, 0x6c, 0x78, 0x3c, 0x18, 0x00, 0x66, + 0x00, 0xb1, 0x3c, 0xcc, 0x00, 0xa5, 0x00, 0x00, 0x18, 0x30, 0x0c, 0x00, 0x66, 0x3a, 0x18, 0x00, + 0x30, 0x38, 0x33, 0x58, 0x58, 0x2c, 0x30, 0x7e, 0x18, 0x66, 0x66, 0x66, 0x66, 0x78, 0x60, 0x66, + 0x60, 0x4c, 0x60, 0x6e, 0xf0, 0x18, 0x60, 0x30, 0xe6, 0xf6, 0x66, 0x66, 0x66, 0x66, 0x38, 0x66, + 0x70, 0x30, 0x66, 0x66, 0x4c, 0x4c, 0x6c, 0x06, 0x18, 0x06, 0x3c, 0x06, 0x06, 0x66, 0x66, 0x3c, + 0x66, 0x0c, 0x66, 0x66, 0x78, 0x18, 0x18, 0x60, 0x7c, 0x66, 0x3c, 0x3c, 0x3c, 0x3c, 0x7e, 0x66, + 0x78, 0x60, 0x66, 0x66, 0x0c, 0x0c, 0x00, 0x18, 0x00, 0xfe, 0x06, 0x36, 0xdc, 0x00, 0x30, 0x0c, + 0x3c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x76, 0x18, 0x18, 0x06, 0xfe, 0x06, 0x66, 0x18, 0x66, 0x06, + 0x00, 0x00, 0x18, 0x7e, 0x18, 0x18, 0xde, 0x66, 0x66, 0x60, 0x66, 0x60, 0x60, 0x66, 0x66, 0x18, + 0x06, 0xd8, 0x60, 0xc6, 0xce, 0x66, 0x60, 0xcc, 0x6c, 0x0e, 0x18, 0x66, 0x3c, 0xfe, 0x3c, 0x18, + 0x60, 0x30, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x60, 0x66, 0x7e, 0x30, 0x66, 0x66, 0x18, + 0x0c, 0x78, 0x18, 0xd6, 0x66, 0x66, 0x66, 0x66, 0x60, 0x3c, 0x30, 0x66, 0x66, 0xd6, 0x38, 0x66, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x0f, 0x66, 0x18, 0x3e, 0x30, 0x42, 0x3c, 0x18, 0x3c, 0x00, 0x9d, + 0x00, 0x66, 0x00, 0xb9, 0x00, 0x00, 0x18, 0x7c, 0x78, 0x00, 0x66, 0x0a, 0x00, 0x00, 0x30, 0x00, + 0x66, 0x32, 0x3e, 0xd9, 0x60, 0x66, 0x18, 0x7e, 0x40, 0x7e, 0x7e, 0x60, 0x78, 0x40, 0x78, 0x18, + 0x78, 0x66, 0xd8, 0x18, 0x60, 0x0c, 0xf6, 0xde, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x66, 0xe0, 0x0c, + 0x66, 0x66, 0x18, 0x18, 0x66, 0x3e, 0x18, 0x3e, 0x60, 0x3e, 0x3e, 0x7e, 0x7e, 0x60, 0x7e, 0x18, + 0x7e, 0x66, 0x6c, 0x18, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x18, 0x3c, + 0x66, 0x66, 0x18, 0x18, 0x00, 0x00, 0x00, 0x6c, 0x7c, 0x6a, 0xce, 0x00, 0x18, 0x18, 0x66, 0x18, + 0x18, 0x00, 0x18, 0x60, 0x66, 0x18, 0x30, 0x66, 0x0c, 0x66, 0x66, 0x18, 0x66, 0x0c, 0x18, 0x18, + 0x06, 0x00, 0x60, 0x00, 0xc0, 0x66, 0x66, 0x30, 0x6c, 0x60, 0x60, 0x66, 0x66, 0x18, 0x66, 0xcc, + 0x60, 0xc6, 0xc6, 0x66, 0x60, 0xdc, 0x66, 0x66, 0x18, 0x66, 0x3c, 0xee, 0x66, 0x18, 0xc0, 0x30, + 0x06, 0x0c, 0x00, 0x00, 0x00, 0x66, 0x66, 0x60, 0x66, 0x60, 0x30, 0x3e, 0x66, 0x18, 0x0c, 0x6c, + 0x18, 0xc6, 0x66, 0x66, 0x7c, 0x3e, 0x60, 0x06, 0x30, 0x66, 0x3c, 0xfe, 0x6c, 0x3c, 0x30, 0x18, + 0x18, 0x18, 0x00, 0x3c, 0x66, 0x18, 0x0c, 0x30, 0x00, 0x18, 0x18, 0x06, 0x00, 0x81, 0x7e, 0x33, + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x0a, 0x00, 0x00, 0x00, 0x7c, 0xcc, 0x66, + 0x62, 0x33, 0x66, 0x66, 0x18, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x66, 0x60, 0x32, 0x60, 0x3e, + 0xcc, 0x18, 0x7e, 0x66, 0xde, 0xce, 0x66, 0x66, 0x66, 0x66, 0xc6, 0x66, 0x60, 0x66, 0x66, 0x66, + 0x32, 0x32, 0x66, 0x66, 0x18, 0x66, 0x60, 0x66, 0x66, 0x60, 0x60, 0x60, 0x60, 0x30, 0x60, 0x3e, + 0x66, 0x18, 0x18, 0x06, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x18, 0x66, 0x18, 0x06, 0x66, 0x66, + 0x30, 0x30, 0x00, 0x18, 0x00, 0x6c, 0x18, 0xcc, 0x7b, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x18, 0x00, + 0x18, 0xc0, 0x3c, 0x18, 0x7e, 0x3c, 0x0c, 0x3c, 0x3c, 0x18, 0x3c, 0x38, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x18, 0x78, 0x66, 0x7c, 0x1e, 0x78, 0x7e, 0x60, 0x3e, 0x66, 0x3c, 0x3c, 0xc6, 0x7e, 0xc6, + 0xc6, 0x3c, 0x60, 0x7e, 0x66, 0x3c, 0x18, 0x3c, 0x18, 0xc6, 0xc3, 0x18, 0xfe, 0x3c, 0x03, 0x3c, + 0x00, 0x00, 0x00, 0x3e, 0x7c, 0x3c, 0x3e, 0x3c, 0x30, 0x06, 0x66, 0x0c, 0x0c, 0x66, 0x0c, 0xc6, + 0x66, 0x3c, 0x60, 0x06, 0x60, 0x7c, 0x1c, 0x3e, 0x18, 0x6c, 0xc6, 0x18, 0x7e, 0x0e, 0x18, 0x70, + 0x00, 0xf0, 0x7e, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x3c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x81, + 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7f, 0x0a, 0x00, 0x18, 0x00, 0x00, 0x00, 0xcf, 0xc4, 0x67, + 0x3c, 0x67, 0x3e, 0x66, 0x3c, 0x66, 0x66, 0x7f, 0x7e, 0x3c, 0x7e, 0x7e, 0x7e, 0x18, 0x30, 0x3c, + 0x18, 0x3c, 0xce, 0x18, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x3f, 0x7e, 0x3c, 0x3c, 0x3c, 0x7e, 0x7e, + 0x6c, 0x3f, 0x1e, 0x3e, 0x3c, 0x3e, 0x3e, 0x3c, 0x3c, 0x3c, 0x3c, 0x7e, 0x3c, 0x06, 0x18, 0x0c, + 0x0c, 0x7c, 0x66, 0x18, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x3f, 0x0c, 0x7c, 0x3e, 0x3e, 0x7e, 0x7e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x01, 0x00, 0x03, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x00, 0x30, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x03, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x00, 0x18, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x08, 0x00, 0x18, 0x00, 0x08, 0x00, 0x20, + 0x00, 0x08, 0x00, 0x28, 0x00, 0x08, 0x00, 0x30, 0x00, 0x08, 0x00, 0x38, 0x00, 0x08, 0x00, 0x40, + 0x00, 0x08, 0x00, 0x48, 0x00, 0x08, 0x00, 0x50, 0x00, 0x08, 0x00, 0x58, 0x00, 0x08, 0x00, 0x60, + 0x00, 0x08, 0x00, 0x68, 0x00, 0x08, 0x00, 0x70, 0x00, 0x08, 0x00, 0x78, 0x00, 0x08, 0x00, 0x80, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x08, 0x00, 0x90, 0x00, 0x08, 0x00, 0x98, 0x00, 0x08, 0x00, 0xa0, + 0x00, 0x08, 0x00, 0xa8, 0x00, 0x08, 0x00, 0xb0, 0x00, 0x08, 0x00, 0xb8, 0x00, 0x08, 0x00, 0xc0, + 0x00, 0x08, 0x00, 0xc8, 0x00, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x00, 0xd8, 0x00, 0x08, 0x00, 0xe0, + 0x00, 0x08, 0x00, 0xe8, 0x00, 0x08, 0x00, 0xf0, 0x00, 0x08, 0x00, 0xf8, 0x00, 0x08, 0x01, 0x00, + 0x00, 0x08, 0x01, 0x08, 0x00, 0x08, 0x01, 0x10, 0x00, 0x08, 0x01, 0x18, 0x00, 0x08, 0x01, 0x20, + 0x00, 0x08, 0x01, 0x28, 0x00, 0x08, 0x01, 0x30, 0x00, 0x08, 0x01, 0x38, 0x00, 0x08, 0x01, 0x40, + 0x00, 0x08, 0x01, 0x48, 0x00, 0x08, 0x01, 0x50, 0x00, 0x08, 0x01, 0x58, 0x00, 0x08, 0x01, 0x60, + 0x00, 0x08, 0x01, 0x68, 0x00, 0x08, 0x01, 0x70, 0x00, 0x08, 0x01, 0x78, 0x00, 0x08, 0x01, 0x80, + 0x00, 0x08, 0x01, 0x88, 0x00, 0x08, 0x01, 0x90, 0x00, 0x08, 0x01, 0x98, 0x00, 0x08, 0x01, 0xa0, + 0x00, 0x08, 0x01, 0xa8, 0x00, 0x08, 0x01, 0xb0, 0x00, 0x08, 0x01, 0xb8, 0x00, 0x08, 0x01, 0xc0, + 0x00, 0x08, 0x01, 0xc8, 0x00, 0x08, 0x01, 0xd0, 0x00, 0x08, 0x01, 0xd8, 0x00, 0x08, 0x01, 0xe0, + 0x00, 0x08, 0x01, 0xe8, 0x00, 0x08, 0x01, 0xf0, 0x00, 0x08, 0x01, 0xf8, 0x00, 0x08, 0x02, 0x00, + 0x00, 0x08, 0x02, 0x08, 0x00, 0x08, 0x02, 0x10, 0x00, 0x08, 0x02, 0x18, 0x00, 0x08, 0x02, 0x20, + 0x00, 0x08, 0x02, 0x28, 0x00, 0x08, 0x02, 0x30, 0x00, 0x08, 0x02, 0x38, 0x00, 0x08, 0x02, 0x40, + 0x00, 0x08, 0x02, 0x48, 0x00, 0x08, 0x02, 0x50, 0x00, 0x08, 0x02, 0x58, 0x00, 0x08, 0x02, 0x60, + 0x00, 0x08, 0x02, 0x68, 0x00, 0x08, 0x02, 0x70, 0x00, 0x08, 0x02, 0x78, 0x00, 0x08, 0x02, 0x80, + 0x00, 0x08, 0x02, 0x88, 0x00, 0x08, 0x02, 0x90, 0x00, 0x08, 0x02, 0x98, 0x00, 0x08, 0x02, 0xa0, + 0x00, 0x08, 0x02, 0xa8, 0x00, 0x08, 0x02, 0xb0, 0x00, 0x08, 0x02, 0xb8, 0x00, 0x08, 0x02, 0xc0, + 0x00, 0x08, 0x02, 0xc8, 0x00, 0x08, 0x02, 0xd0, 0x00, 0x08, 0x02, 0xd8, 0x00, 0x08, 0x02, 0xe0, + 0x00, 0x08, 0x02, 0xe8, 0x00, 0x08, 0x02, 0xf0, 0x00, 0x08, 0x02, 0xf8, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x08, 0x03, 0x08, 0x00, 0x08, 0x03, 0x10, 0x00, 0x08, 0x03, 0x18, 0x00, 0x08, 0x03, 0x20, + 0x00, 0x08, 0x03, 0x28, 0x00, 0x08, 0x03, 0x30, 0x00, 0x08, 0x03, 0x38, 0x00, 0x08, 0x03, 0x40, + 0x00, 0x08, 0x03, 0x48, 0x00, 0x08, 0x03, 0x50, 0x00, 0x08, 0x03, 0x58, 0x00, 0x08, 0x03, 0x60, + 0x00, 0x08, 0x00, 0x68, 0x00, 0x08, 0x03, 0x68, 0x00, 0x08, 0x03, 0x70, 0x00, 0x08, 0x03, 0x78, + 0x00, 0x08, 0x03, 0x80, 0x00, 0x08, 0x03, 0x88, 0x00, 0x08, 0x03, 0x90, 0x00, 0x08, 0x03, 0x98, + 0x00, 0x08, 0x03, 0xa0, 0x00, 0x08, 0x03, 0xa8, 0x00, 0x08, 0x03, 0xb0, 0x00, 0x08, 0x03, 0xb8, + 0x00, 0x08, 0x03, 0xc0, 0x00, 0x08, 0x03, 0xc8, 0x00, 0x08, 0x03, 0xd0, 0x00, 0x08, 0x03, 0xd8, + 0x00, 0x08, 0x03, 0xe0, 0x00, 0x08, 0x03, 0xe8, 0x00, 0x08, 0x03, 0xf0, 0x00, 0x08, 0x03, 0xf8, + 0x00, 0x08, 0x04, 0x00, 0x00, 0x08, 0x04, 0x08, 0x00, 0x08, 0x04, 0x10, 0x00, 0x08, 0x04, 0x18, + 0x00, 0x08, 0x04, 0x20, 0x00, 0x08, 0x04, 0x28, 0x00, 0x08, 0x04, 0x30, 0x00, 0x08, 0x04, 0x38, + 0x00, 0x08, 0x04, 0x40, 0x00, 0x08, 0x04, 0x48, 0x00, 0x08, 0x04, 0x50, 0x00, 0x08, 0x04, 0x58, + 0x00, 0x08, 0x04, 0x60, 0x00, 0x08, 0x04, 0x68, 0x00, 0x08, 0x04, 0x70, 0x00, 0x08, 0x04, 0x78, + 0x00, 0x08, 0x04, 0x80, 0x00, 0x08, 0x04, 0x88, 0x00, 0x08, 0x04, 0x90, 0x00, 0x08, 0x04, 0x98, + 0x00, 0x08, 0x04, 0xa0, 0x00, 0x08, 0x04, 0xa8, 0x00, 0x08, 0x04, 0xb0, 0x00, 0x08, 0x04, 0xb8, + 0x00, 0x08, 0x04, 0xc0, 0x00, 0x08, 0x04, 0xc8, 0x00, 0x08, 0x04, 0xd0, 0x00, 0x08, 0x04, 0xd8, + 0x00, 0x08, 0x04, 0xe0, 0x00, 0x08, 0x04, 0xe8, 0x00, 0x08, 0x04, 0xf0, 0x00, 0x08, 0x04, 0xf8, + 0x00, 0x08, 0x05, 0x00, 0x00, 0x08, 0x05, 0x08, 0x00, 0x08, 0x05, 0x10, 0x00, 0x08, 0x05, 0x18, + 0x00, 0x08, 0x05, 0x20, 0x00, 0x08, 0x05, 0x28, 0x00, 0x08, 0x05, 0x30, 0x00, 0x08, 0x05, 0x38, + 0x00, 0x08, 0x05, 0x40, 0x00, 0x08, 0x05, 0x48, 0x00, 0x08, 0x05, 0x50, 0x00, 0x08, 0x05, 0x58, + 0x00, 0x08, 0x05, 0x60, 0x00, 0x08, 0x05, 0x68, 0x00, 0x08, 0x05, 0x70, 0x00, 0x08, 0x05, 0x78, + 0x00, 0x08, 0x05, 0x80, 0x00, 0x08, 0x05, 0x88, 0x00, 0x08, 0x05, 0x90, 0x00, 0x08, 0x05, 0x98, + 0x00, 0x08, 0x05, 0xa0, 0x00, 0x08, 0x05, 0xa8, 0x00, 0x08, 0x05, 0xb0, 0x00, 0x08, 0x05, 0xb8, + 0x00, 0x08, 0x05, 0xc0, 0x00, 0x08, 0x05, 0xc8, 0x00, 0x08, 0x05, 0xd0, 0x00, 0x08, 0x05, 0xd8, + 0x00, 0x08, 0x05, 0xe0, 0x00, 0x08, 0x05, 0xe8, 0x00, 0x08, 0x00, 0x38, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x62, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf2 +}; + + const char *_zoneFlagNamesRes[] = { "closed", @@ -133,8 +300,8 @@ const char *_instructionNamesRes[] = { }; const char *_callableNamesRes[] = { - "HBOff", "Projector", + "HBOff", "StartIntro", "EndIntro", "MoveSheet", @@ -160,9 +327,10 @@ const char *_callableNamesRes[] = { "TestResult" }; +typedef void (*callable)(void*); + void _c_play_boogie(void*); -void _c_play_boogie(void*); void _c_startIntro(void*); void _c_endIntro(void*); void _c_moveSheet(void*); @@ -170,7 +338,6 @@ void _c_sketch(void*); void _c_shade(void*); void _c_score(void*); void _c_fade(void*); -void _c_play_boogie(void*); void _c_moveSarc(void*); void _c_contaFoglie(void*); void _c_zeroFoglie(void*); @@ -185,35 +352,14 @@ void _c_ridux(void*); void _c_testResult(void*); void _c_null(void*); -typedef void (*callable)(void*); +void _c_projector(void*); +void _c_HBOff(void*); +void _c_offSound(void*); +void _c_startMusic(void*); +void _c_closeMusic(void*); +void _c_HBOn(void*); -callable _callables[] = { - _c_play_boogie, - _c_play_boogie, - _c_startIntro, - _c_endIntro, - _c_moveSheet, - _c_sketch, - _c_shade, - _c_score, - _c_null, - _c_null, - _c_null, - _c_fade, - _c_play_boogie, - _c_moveSarc, - _c_contaFoglie, - _c_zeroFoglie, - _c_trasformata, - _c_offMouse, - _c_onMouse, - _c_setMask, - _c_endComment, - _c_frankenstein, - _c_finito, - _c_ridux, - _c_testResult -}; +callable _callables[25]; Credit _credits[] = { @@ -222,8 +368,7 @@ Credit _credits[] = { {"Project Manager", "LOVRANO CANEPA"}, {"Production", "BRUNO BOZ"}, {"Special Thanks to", "LUIGI BENEDICENTI - GILDA and DANILO"}, - {"Copyright 1992 Euclidea s.r.l ITALY", "All rights reserved"}, - {"CLICK MOUSE BUTTON TO START", 0} + {"Copyright 1992 Euclidea s.r.l ITALY", "All rights reserved"} }; const char *_dinoName = "dino"; @@ -248,6 +393,60 @@ void Parallaction::initResources() { _localFlagNames = new Table(120); _localFlagNames->addData("visited"); + if (getPlatform() == Common::kPlatformPC) { + _callables[0] = _c_play_boogie; + _callables[1] = _c_play_boogie; + _callables[2] = _c_startIntro; + _callables[3] = _c_endIntro; + _callables[4] = _c_moveSheet; + _callables[5] = _c_sketch; + _callables[6] = _c_shade; + _callables[7] = _c_score; + _callables[8] = _c_null; + _callables[9] = _c_null; + _callables[10] = _c_null; + _callables[11] = _c_fade; + _callables[12] = _c_play_boogie; + _callables[13] = _c_moveSarc; + _callables[14] = _c_contaFoglie; + _callables[15] = _c_zeroFoglie; + _callables[16] = _c_trasformata; + _callables[17] = _c_offMouse; + _callables[18] = _c_onMouse; + _callables[19] = _c_setMask; + _callables[20] = _c_endComment; + _callables[21] = _c_frankenstein; + _callables[22] = _c_finito; + _callables[23] = _c_ridux; + _callables[24] = _c_testResult; + } else { + _callables[0] = _c_projector; + _callables[1] = _c_HBOff; + _callables[2] = _c_startIntro; + _callables[3] = _c_endIntro; + _callables[4] = _c_moveSheet; + _callables[5] = _c_sketch; + _callables[6] = _c_shade; + _callables[7] = _c_score; + _callables[8] = _c_offSound; + _callables[9] = _c_startMusic; + _callables[10] = _c_closeMusic; + _callables[11] = _c_fade; + _callables[12] = _c_HBOn; + _callables[13] = _c_moveSarc; + _callables[14] = _c_contaFoglie; + _callables[15] = _c_zeroFoglie; + _callables[16] = _c_trasformata; + _callables[17] = _c_offMouse; + _callables[18] = _c_onMouse; + _callables[19] = _c_setMask; + _callables[20] = _c_endComment; + _callables[21] = _c_frankenstein; + _callables[22] = _c_finito; + _callables[23] = _c_ridux; + _callables[24] = _c_testResult; + } + } diff --git a/engines/parallaction/walk.cpp b/engines/parallaction/walk.cpp index 4910bc07ba..aae5233e61 100644 --- a/engines/parallaction/walk.cpp +++ b/engines/parallaction/walk.cpp @@ -20,17 +20,12 @@ * */ -#include "parallaction/defs.h" +#include "common/stdafx.h" + #include "parallaction/parallaction.h" -#include "parallaction/commands.h" -#include "parallaction/graphics.h" -#include "parallaction/walk.h" -#include "parallaction/zone.h" namespace Parallaction { -uint16 walkFunc1(int16, int16, WalkNode *); - static byte *_buffer; static uint16 _doorData1 = 1000; @@ -40,6 +35,17 @@ static uint16 walkData1 = 0; static uint16 walkData2 = 0; // next walk frame +uint16 queryPath(uint16 x, uint16 y) { + + // NOTE: a better solution would have us mirror each byte in the mask in the loading routine + // AmigaDisk::loadPath() instead of doing it here. + + byte _al = _buffer[y*40 + x/8]; + byte _dl = (_vm->getPlatform() == Common::kPlatformPC) ? (x & 7) : (7 - (x & 7)); + + return _al & (1 << _dl); +} + // adjusts position towards nearest walkable point // void PathBuilder::correctPathPoint(Common::Point &to) { @@ -135,7 +141,15 @@ uint32 PathBuilder::buildSubPath(const Common::Point& pos, const Common::Point& return v34; } +#if 0 +void printNodes(WalkNodeList *list, const char* text) { + printf("%s\n-------------------\n", text); + for (WalkNodeList::iterator it = list->begin(); it != list->end(); it++) + printf("node [%p] (%i, %i)\n", *it, (*it)->_x, (*it)->_y); + return; +} +#endif // // x, y: mouse click (foot) coordinates // @@ -163,10 +177,12 @@ WalkNodeList *PathBuilder::buildPath(uint16 x, uint16 y) { // path is obstructed: look for alternative _list = new WalkNodeList; _list->push_back(v48); +#if 0 + printNodes(_list, "start"); +#endif Common::Point stop(v48->_x, v48->_y); Common::Point pos(_vm->_char._ani._left, _vm->_char._ani._top); - uint32 v34 = buildSubPath(pos, stop); if (v38 != 0 && v34 > v38) { // no alternative path (gap?) @@ -175,14 +191,16 @@ WalkNodeList *PathBuilder::buildPath(uint16 x, uint16 y) { return _list; } _list->insert(_list->begin(), _subPath.begin(), _subPath.end()); +#if 0 + printNodes(_list, "first segment"); +#endif (*_list->begin())->getPoint(stop); - buildSubPath(pos, stop); _list->insert(_list->begin(), _subPath.begin(), _subPath.end()); - - for (WalkNodeList::iterator it = _list->begin(); it != _list->end(); it++) - printf("node (%i, %i)\n", (*it)->_x, (*it)->_y); +#if 0 + printNodes(_list, "complete"); +#endif delete v44; return _list; @@ -196,7 +214,7 @@ WalkNodeList *PathBuilder::buildPath(uint16 x, uint16 y) { // 1 : Point reachable in a straight line // other values: square distance to target (point not reachable in a straight line) // -uint16 walkFunc1(int16 x, int16 y, WalkNode *Node) { +uint16 PathBuilder::walkFunc1(int16 x, int16 y, WalkNode *Node) { Common::Point arg(x, y); @@ -249,7 +267,7 @@ uint16 walkFunc1(int16 x, int16 y, WalkNode *Node) { return 1; } -void clipMove(Common::Point& pos, const WalkNode* from) { +void Parallaction::clipMove(Common::Point& pos, const WalkNode* from) { if ((pos.x < from->_x) && (pos.x < SCREEN_WIDTH) && (queryPath(_vm->_char._ani.width()/2 + pos.x + 2, _vm->_char._ani.height() + pos.y) != 0)) { pos.x = (pos.x + 2 < from->_x) ? pos.x + 2 : from->_x; @@ -270,7 +288,7 @@ void clipMove(Common::Point& pos, const WalkNode* from) { return; } -int16 selectWalkFrame(const Common::Point& pos, const WalkNode* from) { +int16 Parallaction::selectWalkFrame(const Common::Point& pos, const WalkNode* from) { Common::Point dist(from->_x - pos.x, from->_y - pos.y); @@ -312,51 +330,7 @@ int16 selectWalkFrame(const Common::Point& pos, const WalkNode* from) { return v16; } -void finalizeWalk(WalkNodeList *list) { - checkDoor(); - delete list; -} - -void jobWalk(void *parm, Job *j) { - WalkNodeList *list = (WalkNodeList*)parm; - - Common::Point pos(_vm->_char._ani._left, _vm->_char._ani._top); - _vm->_char._ani._oldPos = pos; - - WalkNodeList::iterator it = list->begin(); - - if ((*it)->_x == pos.x && (*it)->_y == pos.y) { - debugC(1, kDebugWalk, "jobWalk moving to next node (%i, %i)", (*it)->_x, (*it)->_y); - it = list->erase(it); - } - if (it == list->end()) { - debugC(1, kDebugWalk, "jobWalk reached last node"); - j->_finished = 1; - finalizeWalk(list); - return; - } - j->_parm = list; - - // selectWalkFrame must be performed before position is changed by clipMove - int16 v16 = selectWalkFrame(pos, *it); - clipMove(pos, *it); - - _vm->_char._ani._left = pos.x; - _vm->_char._ani._top = pos.y; - - if (pos == _vm->_char._ani._oldPos) { - debugC(1, kDebugWalk, "jobWalk was blocked by an unforeseen obstacle"); - j->_finished = 1; - finalizeWalk(list); - } else { - _vm->_char._ani._frame = v16 + walkData2 + 1; - } - - return; -} - - -uint16 checkDoor() { +uint16 Parallaction::checkDoor() { // printf("checkDoor()..."); if (_vm->_currentLocationIndex != _doorData1) { @@ -404,20 +378,58 @@ uint16 checkDoor() { return _vm->_char._ani._frame; } -uint16 queryPath(uint16 x, uint16 y) { - byte _al = _buffer[y*40 + x/8]; - byte _dl = 1 << (x % 8); +void Parallaction::finalizeWalk(WalkNodeList *list) { + checkDoor(); + delete list; +} + +void jobWalk(void *parm, Job *j) { + WalkNodeList *list = (WalkNodeList*)parm; + + Common::Point pos(_vm->_char._ani._left, _vm->_char._ani._top); + _vm->_char._ani._oldPos = pos; + + WalkNodeList::iterator it = list->begin(); + + if (it != list->end()) { + if ((*it)->_x == pos.x && (*it)->_y == pos.y) { + debugC(1, kDebugWalk, "jobWalk reached node (%i, %i)", (*it)->_x, (*it)->_y); + it = list->erase(it); + } + } + if (it == list->end()) { + debugC(1, kDebugWalk, "jobWalk reached last node"); + j->_finished = 1; + _vm->finalizeWalk(list); + return; + } + j->_parm = list; - return _al & _dl; + // selectWalkFrame must be performed before position is changed by clipMove + int16 v16 = _vm->selectWalkFrame(pos, *it); + _vm->clipMove(pos, *it); + _vm->_char._ani._left = pos.x; + _vm->_char._ani._top = pos.y; + + if (pos == _vm->_char._ani._oldPos) { + debugC(1, kDebugWalk, "jobWalk was blocked by an unforeseen obstacle"); + j->_finished = 1; + _vm->finalizeWalk(list); + } else { + _vm->_char._ani._frame = v16 + walkData2 + 1; + } + + return; } -void setPath(byte *path) { + +void Parallaction::setPath(byte *path) { memcpy(_buffer, path, SCREENPATH_WIDTH*SCREEN_HEIGHT); } -void initWalk() { +void Parallaction::initWalk() { _buffer = (byte*)malloc(SCREENPATH_WIDTH * SCREEN_HEIGHT); } @@ -425,7 +437,7 @@ void initWalk() { WalkNode::WalkNode() : _x(0), _y(0) { } -WalkNode::WalkNode(int32 x, int32 y) : _x(x), _y(y) { +WalkNode::WalkNode(int16 x, int16 y) : _x(x), _y(y) { } WalkNode::WalkNode(const WalkNode& w) : _x(w._x), _y(w._y) { diff --git a/engines/parallaction/walk.h b/engines/parallaction/walk.h index 8b8e189df7..eb0aa3643f 100644 --- a/engines/parallaction/walk.h +++ b/engines/parallaction/walk.h @@ -31,12 +31,12 @@ struct Animation; struct Job; struct WalkNode { - int32 _x; - int32 _y; + int16 _x; + int16 _y; public: WalkNode(); - WalkNode(int32 x, int32 y); + WalkNode(int16 x, int16 y); WalkNode(const WalkNode& w); void getPoint(Common::Point &p) const; @@ -44,22 +44,20 @@ public: typedef ManagedList<WalkNode*> WalkNodeList; -//WalkNode *buildWalkPath(uint16 x, uint16 y); + void jobWalk(void*, Job *j); -uint16 checkDoor(); -void setPath(byte *path); -void initWalk(); -uint16 queryPath(uint16 x, uint16 y); + class PathBuilder { Animation *_anim; WalkNodeList *_list; - WalkNodeList _subPath; + Common::List<WalkNode*> _subPath; void correctPathPoint(Common::Point &to); uint32 buildSubPath(const Common::Point& pos, const Common::Point& stop); + uint16 walkFunc1(int16 x, int16 y, WalkNode *Node); public: PathBuilder(Animation *anim); diff --git a/engines/parallaction/zone.cpp b/engines/parallaction/zone.cpp index ebf2136f05..16581e9174 100644 --- a/engines/parallaction/zone.cpp +++ b/engines/parallaction/zone.cpp @@ -21,11 +21,10 @@ */ -#include "parallaction/parser.h" +#include "common/stdafx.h" + #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" -#include "parallaction/inventory.h" -#include "parallaction/zone.h" +#include "parallaction/sound.h" namespace Parallaction { @@ -271,6 +270,10 @@ void Parallaction::parseZoneTypeBlock(Script &script, Zone *z) { case kZoneHear: // hear Zone init if (!scumm_stricmp(_tokens[0], "sound")) { strcpy(u->hear->_name, _tokens[1]); + z->u.hear->_channel = atoi(_tokens[2]); + } + if (!scumm_stricmp(_tokens[0], "freq")) { + z->u.hear->_freq = atoi(_tokens[1]); } break; @@ -304,7 +307,7 @@ void Parallaction::displayCharacterComment(ExamineData *data) { v3C._data0 = _char._talk->getFramePtr(0); v3C._data1 = NULL; //_talk->field_8[0]; - _gfx->setFont("comic"); + _gfx->setFont(kFontDialogue); _gfx->flatBlitCnv(&v3C, 190, 80, Gfx::kBitFront); int16 v26, v28; @@ -314,6 +317,8 @@ void Parallaction::displayCharacterComment(ExamineData *data) { _gfx->drawBalloon(r, 0); _gfx->displayWrappedString(data->_description, 140, 10, 130, 0); + _gfx->updateScreen(); + waitUntilLeftClick(); _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); @@ -334,6 +339,8 @@ void Parallaction::displayItemComment(ExamineData *data) { if (data->_description == NULL) return; + _gfx->setHalfbriteMode(true); + char v68[PATH_LEN]; strcpy(v68, data->_filename); data->_cnv = _disk->loadStatic(v68); @@ -343,7 +350,7 @@ void Parallaction::displayItemComment(ExamineData *data) { int16 v6A = 0, v6C = 0; - _gfx->setFont("comic"); + _gfx->setFont(kFontDialogue); _gfx->getStringExtent(data->_description, 130, &v6C, &v6A); Common::Rect r(v6C, v6A); r.moveTo(0, 90); @@ -352,9 +359,11 @@ void Parallaction::displayItemComment(ExamineData *data) { _gfx->displayWrappedString(data->_description, 0, 90, 130, 0); jobEraseAnimations((void*)1, NULL); + _gfx->updateScreen(); waitUntilLeftClick(); + _gfx->setHalfbriteMode(false); _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); return; @@ -394,7 +403,7 @@ uint16 Parallaction::runZone(Zone *z) { break; case kZoneHear: - strcpy(_soundFile, z->u.hear->_name); + _soundMan->playSfx(z->u.hear->_name, z->u.hear->_channel, (z->_flags & kFlagsLooping) == kFlagsLooping, 60); break; case kZoneSpeak: @@ -446,13 +455,18 @@ void jobToggleDoor(void *parm, Job *j) { - - - // // ZONE TYPE: GET // +int16 Parallaction::pickupItem(Zone *z) { + int r = addInventoryItem(z->u.get->_icon); + if (r == 0) + addJob(&jobRemovePickedItem, z, kPriority17 ); + + return r; +} + void jobRemovePickedItem(void *parm, Job *j) { Zone *z = (Zone*)parm; @@ -480,7 +494,7 @@ void jobDisplayDroppedItem(void *parm, Job *j) { Zone *z = (Zone*)parm; if (z->u.get->_cnv) { - if (z->u.get->_cnv->_data0 != NULL) { + if (j->_count == 0) { _vm->_gfx->backupGetBackground(z->u.get, z->_left, z->_top); } @@ -601,7 +615,7 @@ Zone::Zone() { } Zone::~Zone() { - printf("~Zone(%s)\n", _label._text); +// printf("~Zone(%s)\n", _label._text); switch (_type & 0xFFFF) { case kZoneExamine: @@ -642,11 +656,6 @@ Zone::~Zone() { default: break; } - - free(_label._text); - _label._text = NULL; - _vm->_gfx->freeStaticCnv(&_label._cnv); - } void Zone::getRect(Common::Rect& r) const { @@ -671,5 +680,15 @@ uint16 Zone::height() const { return _bottom - _top; } +Label::Label() { + _text = NULL; +} + +Label::~Label() { + _vm->_gfx->freeStaticCnv(&_cnv); + if (_text) + free(_text); +} + } // namespace Parallaction diff --git a/engines/parallaction/zone.h b/engines/parallaction/zone.h index 1a0a616624..a2a852f31c 100644 --- a/engines/parallaction/zone.h +++ b/engines/parallaction/zone.h @@ -26,6 +26,7 @@ #include "common/list.h" #include "parallaction/defs.h" + #include "parallaction/commands.h" #include "parallaction/graphics.h" @@ -147,8 +148,12 @@ struct DoorData { // size = 28 }; struct HearData { // size = 20 char _name[20]; + int _channel; + int _freq; HearData() { + _channel = -1; + _freq = -1; _name[0] = '\0'; } }; @@ -184,9 +189,8 @@ struct Label { char* _text; StaticCnv _cnv; - Label() { - _text = NULL; - } + Label(); + ~Label(); }; struct Zone { @@ -308,13 +312,6 @@ struct Animation : public Zone { typedef Animation* AnimationPointer; typedef ManagedList<AnimationPointer> AnimationList; -void dropItem(uint16 v); -int16 pickupItem(Zone *z); - - -void loadProgram(Animation *, char *filename); - - } // namespace Parallaction |
