Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,172 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ACCESS_MARTIAN_MARTIAN_DUCT_H
#define ACCESS_MARTIAN_MARTIAN_DUCT_H
#include "common/scummsys.h"
#include "common/array.h"
#include "common/rect.h"
#include "common/events.h"
#include "access/martian/martian_resources.h" // For Point3 .. move it?
namespace Access {
namespace Martian {
enum MoveIntent {
kMoveIntentNone,
kMoveIntentUp,
kMoveIntentLeft,
kMoveIntentDown,
kMoveIntentRight,
};
// Move angles - in the original these are indexes into sin/cos lookup tables.
// Add Invalid to ensure at least 2-byte length.
enum MoveAngle {
kMoveAngleNorth = 0,
kMoveAngleEast = 0x40,
kMoveAngleSouth = 0x80,
kMoveAngleWest = 0xC0,
kMoveAngleInvalid = 0xffff,
};
enum DuctFlags {
kDuctFlagNone = 0,
kDuctFlagZLessThanX = 1,
kDuctFlagXLessThanNegZ = 2,
kDuctFlagYLessThanNegZ = 4,
kDuctFlagZLessThanY = 8,
kDuctFlagZLessThan2 = 16,
};
struct RenderShape {
byte _col;
Common::Array<uint16> _pointIdxs;
};
class MartianEngine;
class MartianDuct {
public:
MartianDuct(MartianEngine *vm);
~MartianDuct();
void duct2();
void duct4();
private:
void doDuct();
void drawArrowSprites();
void drawArrowSprites2();
void clearWorkScreenArea();
void copyBufBlockToScreen();
void waitForMoveUpdate();
void storeLastValsToPrimArray(const Point3 &pt1, const Point3 &pt2);
void updatePlayerPos();
void updateMatrix();
void applyMatrixToMapData();
void updatePrimsAndDraw();
bool updateMapLocation();
void checkFinished();
void doMatrixMulAndAddPoint(int16 x, int16 y, int16 z);
bool doPrimArrayUpdates(int &tempIdx);
void doDraw(int counter);
void getPointValuesFromArray(int offset, Point3 &pt1, Point3 &pt2) const;
Common::Rect calcFinalLineSegment(const Point3 &pt1, const Point3 &pt2) const;
bool checkAndUpdatePrimArray1(int &offset);
bool checkAndUpdatePrimArray2(int &offset);
bool checkAndUpdatePrimArray3(int &offset);
bool checkAndUpdatePrimArray4(int &offset);
bool checkAndUpdatePrimArray5(int &offset);
bool checkAndUpdatePrimArrayForFlag(int &offset, DuctFlags flag, int divmulNum);
static Point3 divmul1(const Point3 &pt1, const Point3 &pt2);
static Point3 divmul2(const Point3 &pt1, const Point3 &pt2);
static Point3 divmul3(const Point3 &pt1, const Point3 &pt2);
static Point3 divmul4(const Point3 &pt1, const Point3 &pt2);
static Point3 divmul5(const Point3 &pt1, const Point3 &pt2);
bool checkMove0();
bool checkMove1();
bool checkMove2();
bool checkMove3();
bool checkMove4();
bool checkMove5();
bool checkMove6();
bool checkMove7();
bool checkMove8();
bool checkMove9();
bool checkMove10();
bool checkMove11();
bool checkMove12();
bool checkMove13_14();
void getXYandRBFlags(DuctFlags &xyflags, DuctFlags &rbflags, const Point3 &pt1, const Point3 &pt2);
int addPointsToMainPrimArray(int tempCount);
static DuctFlags getComparisonFlags(int16 x, int16 y, int16 z);
MartianEngine *_vm;
int16 _playerX;
int16 _preYOffset;
int16 _playerY;
int16 _nextPlayerX;
int16 _nextPlayerY;
int16 _xOffset;
int16 _yOffset;
int16 _xScale;
int16 _yScale;
uint16 _mapLoc;
MoveAngle _moveAngle;
int16 _crawlFrame;
bool _stopMoveLoop;
int16 _threshold1;
int16 _drawDistX;
int16 _drawDistY;
MoveIntent _moveIntent;
// NOTE: Original uses fixed point sin/cos with a lookup table.
float _matrix[3][3];
int16 _primArrayIdx;
Common::Array<Point3> _renderPoints;
Common::Array<RenderShape> _renderShapes;
Common::Array<int16> _primX1Array;
Common::Array<int16> _primY1Array;
Common::Array<int16> _primZ1Array;
Common::Array<int16> _primX2Array;
Common::Array<int16> _primY2Array;
Common::Array<int16> _primZ2Array;
Point3 _tempPoints[32];
};
}
} // end namespace Access
#endif // ACCESS_MARTIAN_MARTIAN_DUCT_H

View File

@@ -0,0 +1,427 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "access/resources.h"
#include "access/martian/martian_game.h"
#include "access/martian/martian_resources.h"
#include "access/martian/martian_room.h"
#include "access/martian/martian_scripts.h"
#include "access/amazon/amazon_resources.h"
namespace Access {
namespace Martian {
MartianEngine::MartianEngine(OSystem *syst, const AccessGameDescription *gameDesc) :
AccessEngine(syst, gameDesc), _skipStart(false),
_creditsStream(nullptr)
{
}
MartianEngine::~MartianEngine() {
_skipStart = false;
_creditsStream = nullptr;
}
void MartianEngine::initObjects() {
_room = new MartianRoom(this);
_scripts = new MartianScripts(this);
}
void MartianEngine::configSelect() {
// No implementation required in MM
}
void MartianEngine::initVariables() {
// Set player room and position
_player->_roomNumber = 7;
_inventory->_startInvItem = 0;
_inventory->_startInvBox = 0;
Common::fill(&_objectsTable[0], &_objectsTable[100], (SpriteResource *)nullptr);
_player->_playerOff = false;
setupTimers();
_player->_playerX = _player->_rawPlayer.x = _res->ROOMTBL[_player->_roomNumber]._travelPos.x;
_player->_playerY = _player->_rawPlayer.y = _res->ROOMTBL[_player->_roomNumber]._travelPos.y;
_room->_selectCommand = -1;
_events->setNormalCursor(CURSOR_CROSSHAIRS);
_mouseMode = 0;
_animation->clearTimers();
ARRAYCLEAR(_travel);
_travel[7] = 1;
ARRAYCLEAR(_ask);
_ask[33] = 1;
ARRAYCLEAR(_flags);
}
void MartianEngine::setNoteParams() {
_events->hideCursor();
_screen->_orgX1 = 58;
_screen->_orgY1 = 124;
_screen->_orgX2 = 297;
_screen->_orgY2 = 199;
_screen->_lColor = 51;
_screen->drawRect();
_events->showCursor();
}
void MartianEngine::displayNote(const Common::String &msg) {
_fonts._charSet._lo = 1;
_fonts._charSet._hi = 8;
_fonts._charFor._lo = 0;
_fonts._charFor._hi = 255;
Font::_fontColors[3] = 0;
_screen->_maxChars = 40;
_screen->_printOrg = _screen->_printStart = Common::Point(59, 124);
setNoteParams();
Common::String lines = msg;
Common::String line;
int width = 0;
bool lastLine = false;
do {
lastLine = _fonts._font1->getLine(lines, _screen->_maxChars, line, width, Font::kWidthInChars);
_bubbleBox->printString(line);
_screen->_printOrg = Common::Point(_screen->_printStart.x, _screen->_printOrg.y + 6);
if (_screen->_printOrg.y == 196) {
_events->waitKeyActionMouse();
setNoteParams();
_screen->_printOrg = _screen->_printStart;
}
} while (!lastLine);
_events->waitKeyActionMouse();
}
void MartianEngine::doSpecial5(int param1) {
// Seems redundant to store the song as this is
// only ever called from restart or load?
debug("TODO: Push midi song?");
_midi->stopSong();
_midi->setLoop(false);
_midi->loadMusic(47, 4);
_midi->midiPlay();
_screen->setDisplayScan();
_events->clearEvents();
_screen->forceFadeOut();
_events->hideCursor();
_files->loadScreen("DATA.SC");
_events->showCursor();
_screen->setIconPalette();
_screen->forceFadeIn();
Resource *cellsRes = _files->loadFile("CELLS00.LZ");
_objectsTable[0] = new SpriteResource(this, cellsRes);
delete cellsRes;
_timers[20]._timer = _timers[20]._initTm = 30;
Resource *notesRes = _files->loadFile("NOTES.DAT");
notesRes->_stream->skip(param1 * 2);
int pos = notesRes->_stream->readUint16LE();
notesRes->_stream->seek(pos);
Common::String msg = notesRes->_stream->readString();
delete notesRes;
displayNote(msg);
_midi->stopSong();
_midi->freeMusic();
_midi->setLoop(true);
}
void MartianEngine::playGame() {
// Initialize Martian Memorandum game-specific objects
initObjects();
// Setup the game
setupGame();
configSelect();
if (_loadSaveSlot == -1) {
// Do introduction
doCredits();
if (shouldQuit())
return;
// Display Notes screen
doSpecial5(4);
if (shouldQuit())
return;
_screen->forceFadeOut();
}
do {
_restartFl = false;
_screen->clearScreen();
_screen->setPanel(0);
_screen->forceFadeOut();
_events->showCursor();
initVariables();
// If there's a pending savegame to load, load it
if (_loadSaveSlot != -1) {
loadGameState(_loadSaveSlot);
_loadSaveSlot = -1;
}
// Execute the room
_room->doRoom();
} while (_restartFl);
}
bool MartianEngine::showCredits() {
_events->hideCursor();
_screen->clearScreen();
_destIn = _screen;
int posX = _creditsStream->readSint16LE();
int posY = 0;
while (posX != -1) {
posY = _creditsStream->readSint16LE();
int frameNum = _creditsStream->readSint16LE();
_screen->plotImage(_objectsTable[41], frameNum, Common::Point(posX, posY));
posX = _creditsStream->readSint16LE();
}
posY = _creditsStream->readSint16LE();
if (posY == -1) {
_events->showCursor();
_screen->forceFadeOut();
return true;
}
_screen->forceFadeIn();
_timers[3]._timer = _timers[3]._initTm = posY;
while (!shouldQuit() && !_events->isKeyActionMousePressed() && _timers[3]._timer) {
_events->pollEventsAndWait();
}
_events->showCursor();
_screen->forceFadeOut();
if (_events->_rightButton)
return true;
else
return false;
}
void MartianEngine::doCredits() {
_midi->setLoop(false);
_midi->loadMusic(47, 3);
_midi->midiPlay();
_screen->setDisplayScan();
_events->hideCursor();
_screen->forceFadeOut();
Resource *data = _files->loadFile(41, 1);
_objectsTable[41] = new SpriteResource(this, data);
delete data;
_files->loadScreen(41, 0);
_buffer2.copyFrom(*_screen);
_buffer1.copyFrom(*_screen);
_events->showCursor();
_creditsStream = new Common::MemoryReadStream(CREDIT_DATA, 180);
if (!showCredits()) {
_screen->copyFrom(_buffer2);
_screen->forceFadeIn();
_events->_vbCount = 550;
while (!shouldQuit() && !_events->isKeyActionMousePressed() && _events->_vbCount > 0)
_events->pollEventsAndWait();
_screen->forceFadeOut();
while (!shouldQuit() && !_events->isKeyActionMousePressed()&& !showCredits())
_events->pollEventsAndWait();
delete _objectsTable[41];
_objectsTable[41] = nullptr;
_midi->freeMusic();
}
_midi->setLoop(true);
}
void MartianEngine::setupTimers() {
_timers.clear();
const int TIMER_DEFAULTS[] = { 4, 10, 8, 1, 1, 1, 1, 2 };
for (int i = 0; i < 32; ++i) {
TimerEntry te;
te._initTm = te._timer = (i < 8) ? TIMER_DEFAULTS[i] : 1;
te._flag = 1;
_timers.push_back(te);
}
}
void MartianEngine::setupGame() {
// Load death list
_deaths.resize(_res->DEATHS.size());
for (uint idx = 0; idx < _deaths.size(); ++idx) {
_deaths[idx]._screenId = _res->DEATHS[idx]._screenId;
_deaths[idx]._msg = _res->DEATHS[idx]._msg;
}
setupTimers();
// Miscellaneous
Martian::MartianResources &res = *((Martian::MartianResources *)_res);
_fonts.load(res._font1, res._font2, res._bitFont);
// Set player room and position
_player->_roomNumber = 7;
_player->_playerX = _player->_rawPlayer.x = _res->ROOMTBL[_player->_roomNumber]._travelPos.x;
_player->_playerY = _player->_rawPlayer.y = _res->ROOMTBL[_player->_roomNumber]._travelPos.y;
}
void MartianEngine::showExpositionText(Common::String msg) {
Common::String line = "";
int width = 0;
bool lastLine;
do {
lastLine = _fonts._font2->getLine(msg, _screen->_maxChars, line, width, Font::kWidthInChars);
// Draw the text
_bubbleBox->printString(line);
_screen->_printOrg.y += 6;
_screen->_printOrg.x = _screen->_printStart.x;
if (_screen->_printOrg.y == 180) {
_events->waitKeyActionMouse();
_screen->copyBuffer(&_buffer2);
_screen->_printOrg.y = _screen->_printStart.y;
}
} while (!lastLine);
// Avoid re-using double-click
_events->clearEvents();
_events->waitKeyActionMouse();
}
void MartianEngine::dead(int deathId) {
// Load and display death screen
_events->hideCursor();
_screen->forceFadeOut();
_files->loadScreen(48, _deaths[deathId]._screenId - 1);
_screen->setIconPalette();
_buffer2.copyBuffer(_screen);
_screen->forceFadeIn();
_events->showCursor();
// Setup fonts
_fonts._charSet._hi = 10;
_fonts._charSet._lo = 1;
_fonts._charFor._lo = 247;
_fonts._charFor._hi = 255;
Font::_fontColors[3] = 247;
_screen->_maxChars = 50;
_screen->_printOrg = Common::Point(24, 18);
_screen->_printStart = Common::Point(24, 18);
// Display death message
showExpositionText(_deaths[deathId]._msg);
_screen->forceFadeOut();
_room->clearRoom();
freeChar();
// The original was jumping to the restart label in main
_restartFl = true;
_events->pollEvents();
}
void MartianEngine::establish(int estabIndex, int sub) {
_fonts._charSet._hi = 10;
Font::_fontColors[0] = 0xff;
Font::_fontColors[1] = 0xf7;
Font::_fontColors[2] = 0xff;
Font::_fontColors[3] = 0xf7;
_screen->_maxChars = 50;
_screen->_printOrg = _screen->_printStart = Common::Point(24, 18);
// TODO: Original has a small delay here.
Resource *notesRes = _files->loadFile("ETEXT.DAT");
notesRes->_stream->seek(2 * sub);
uint16 msgOffset = notesRes->_stream->readUint16LE();
if (msgOffset == 0 || msgOffset >= notesRes->_stream->size()) {
error("MartianEngine::establish: Invalid message offset %d for msg %d", msgOffset, sub);
}
notesRes->_stream->seek(msgOffset);
Common::String msg = notesRes->_stream->readString();
showExpositionText(msg);
_events->hideCursor();
if (sub != 0x3f) {
_screen->forceFadeOut();
_screen->clearScreen();
}
_events->showCursor();
}
void MartianEngine::synchronize(Common::Serializer &s) {
AccessEngine::synchronize(s);
for (int i = 0; i < ARRAYSIZE(_travel); i++) {
s.syncAsByte(_travel[i]);
}
for (int i = 0; i < ARRAYSIZE(_ask); i++) {
s.syncAsByte(_ask[i]);
}
/*
TODO: Do any of these need to be synchronized here?
Mostly involved in modal dialogs.
_startTravelItem
_startTravelBox
_startAboutItem
_startAboutBox
_byte26CB5
_bcnt
_boxDataStart
_boxDataEnd
_boxSelectY
_boxSelectYOld
_numLines
*/
}
} // End of namespace Martian
} // End of namespace Access

View File

@@ -0,0 +1,80 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ACCESS_MARTIAN_GAME_H
#define ACCESS_MARTIAN_GAME_H
#include "access/access.h"
namespace Access {
namespace Martian {
class MartianEngine : public AccessEngine {
private:
bool _skipStart;
Common::MemoryReadStream *_creditsStream;
/**
* Do the game introduction
*/
void doCredits();
bool showCredits();
/**
* Setup variables for the game
*/
void setupGame();
void initObjects();
void configSelect();
void initVariables();
void setupTimers();
protected:
/**
* Play the game
*/
void playGame() override;
void dead(int deathId) override;
void setNoteParams();
void displayNote(const Common::String &msg);
public:
MartianEngine(OSystem *syst, const AccessGameDescription *gameDesc);
~MartianEngine() override;
void doSpecial5(int param1);
void showExpositionText(Common::String msg);
void establish(int estabIndex, int sub) override;
/**
* Synchronize savegame data
*/
void synchronize(Common::Serializer &s) override;
};
} // End of namespace Martian
} // End of namespace Access
#endif /* ACCESS_MARTIAN_GAME_H */

View File

@@ -0,0 +1,68 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/scummsys.h"
#include "access/access.h"
#include "access/room.h"
#include "access/martian/martian_game.h"
#include "access/martian/martian_player.h"
#include "access/martian/martian_resources.h"
namespace Access {
namespace Martian {
MartianPlayer::MartianPlayer(AccessEngine *vm) : Player(vm) {
_game = (MartianEngine *)vm;
}
void MartianPlayer::load() {
Player::load();
// Overwrite game-specific values
_playerOffset.x = _vm->_screen->_scaleTable1[20];
_playerOffset.y = _vm->_screen->_scaleTable1[62];
_leftDelta = -9;
_rightDelta = 33;
_upDelta = 5;
_downDelta = -5;
_scrollConst = 5;
for (uint8 i = 0; i < _vm->_playerDataCount; ++i) {
_walkOffRight[i] = SIDEOFFR[i];
_walkOffLeft[i] = SIDEOFFL[i];
_walkOffUp[i] = SIDEOFFU[i];
_walkOffDown[i] = SIDEOFFD[i];
}
_sideWalkMin = 0;
_sideWalkMax = 7;
_upWalkMin = 8;
_upWalkMax = 14;
_downWalkMin = 15;
_downWalkMax = 23;
// playerPalette is configured in Player::load.
}
} // End of namespace Martian
} // End of namespace Access

View File

@@ -0,0 +1,46 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ACCESS_MARTIAN_PLAYER_H
#define ACCESS_MARTIAN_PLAYER_H
#include "common/scummsys.h"
#include "access/player.h"
namespace Access {
namespace Martian {
class MartianEngine;
class MartianPlayer : public Player {
private:
MartianEngine *_game;
public:
MartianPlayer(AccessEngine *vm);
void load() override;
};
} // End of namespace Martian
} // End of namespace Access
#endif /* ACCESS_MARTIAN_PLAYER_H */

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,106 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ACCESS_MARTIAN_RESOURCES_H
#define ACCESS_MARTIAN_RESOURCES_H
#include "common/scummsys.h"
#include "access/resources.h"
#include "access/font.h"
namespace Access {
namespace Martian {
extern const int SIDEOFFR[];
extern const int SIDEOFFL[];
extern const int SIDEOFFU[];
extern const int SIDEOFFD[];
extern const int SIDEOFFR[];
extern const int SIDEOFFL[];
extern const int SIDEOFFU[];
extern const int SIDEOFFD[];
extern const byte CREDIT_DATA[];
extern const byte ICON_PALETTE[];
extern byte HELP[];
extern const char *const ASK_TBL[];
extern const char *const TRAVDATA[];
extern const char *const SPEC7MESSAGE;
extern const byte CAN_TRAVEL_MATRIX[];
extern const int16 PICTURE_RANGE[][2];
extern const int16 DUCT_ARROW_BUTTON_RANGE[][2];
struct DuctMapPoint {
int16 ptType;
int16 shapeType;
int16 x;
int16 y;
};
extern const DuctMapPoint DUCT_MAP_DATA[];
struct Point3 {
int16 x;
int16 y;
int16 z;
};
struct DuctShape {
int16 numPts;
int16 array2Len;
const Point3 *points;
const uint16 *data;
};
extern const DuctShape *DUCT_SHAPE_DATA[];
class MartianResources : public Resources {
protected:
/**
* Load data from the access.dat file
*/
void load(Common::SeekableReadStream &s) override;
public:
MartianFont *_font1;
MartianFont *_font2;
MartianBitFont *_bitFont;
public:
MartianResources(AccessEngine *vm) : Resources(vm), _font1(nullptr), _font2(nullptr), _bitFont(nullptr) {}
~MartianResources() override;
const byte *getCursor(int num) const override;
const char *getEgoName() const override { return "TEX"; }
int getRMouse(int i, int j) const override;
int inButtonXRange(int x) const override;
};
#define MMRES (*((Martian::MartianResources *)_vm->_res))
} // End of namespace Martian
} // End of namespace Access
#endif /* ACCESS_MARTIAN_RESOURCES_H */

View File

@@ -0,0 +1,136 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/scummsys.h"
#include "access/access.h"
#include "access/resources.h"
#include "access/martian/martian_game.h"
#include "access/martian/martian_resources.h"
#include "access/martian/martian_room.h"
namespace Access {
namespace Martian {
MartianRoom::MartianRoom(AccessEngine *vm) : Room(vm) {
_game = (MartianEngine *)vm;
for (int i = 0; i < 30; i++)
_vm->_flags[200 + i] = 0;
for (int i = 0; i < 10; i++)
_vm->_flags[178 + i] = 0;
}
MartianRoom::~MartianRoom() {
}
void MartianRoom::loadRoom(int roomNumber) {
loadRoomData(&MMRES.ROOMTBL[roomNumber]._data[0]);
}
void MartianRoom::reloadRoom() {
// _vm->_currentMan = _roomFlag;
// _vm->_currentManOld = _roomFlag;
// _vm->_manScaleOff = 0;
_vm->_player->loadTexPalette();
_vm->_player->loadSprites("TEX.LZ");
loadRoom(_vm->_player->_roomNumber);
reloadRoom1();
}
void MartianRoom::reloadRoom1() {
_selectCommand = -1;
_vm->_boxSelect = false; //-1
_vm->_player->_playerOff = false;
_vm->_screen->forceFadeOut();
_vm->_events->hideCursor();
_vm->_screen->clearScreen();
_vm->_events->showCursor();
roomInit();
_vm->_player->load();
if (_vm->_player->_roomNumber != 47)
_vm->_player->calcManScale();
_vm->_events->hideCursor();
roomMenu();
_vm->_screen->setBufferScan();
setupRoom();
setWallCodes();
buildScreen();
_vm->copyBF2Vid();
_vm->_screen->setManPalette();
_vm->_events->showCursor();
_vm->_player->_frame = 0;
_vm->_oldRects.clear();
_vm->_newRects.clear();
_vm->_events->clearEvents();
}
void MartianRoom::roomInit() {
Room::roomInit();
for (int i = 0; i < 30; i++)
_vm->_flags[200 + i] = 0;
for (int i = 0; i < 10; i++)
_vm->_flags[178 + i] = 0;
}
void MartianRoom::roomMenu() {
const SpriteResource *icons = _vm->getIcons();
_vm->_screen->saveScreen();
_vm->_screen->setDisplayScan();
_vm->_destIn = _vm->_screen; // TODO: Redundant
_vm->_screen->plotImage(icons, 0, Common::Point(5, 184));
_vm->_screen->plotImage(icons, 1, Common::Point(155, 184));
_vm->_screen->restoreScreen();
}
void MartianRoom::mainAreaClick() {
Common::Point &mousePos = _vm->_events->_mousePos;
Common::Point pt = _vm->_events->calcRawMouse();
Screen &screen = *_vm->_screen;
Player &player = *_vm->_player;
if (_selectCommand == -1) {
player._moveTo = pt;
player._playerMove = true;
} else if (mousePos.x >= screen._windowXAdd &&
mousePos.x <= (screen._windowXAdd + screen._vWindowBytesWide) &&
mousePos.y >= screen._windowYAdd &&
mousePos.y <= (screen._windowYAdd + screen._vWindowLinesTall)) {
if (checkBoxes1(pt) >= 0) {
checkBoxes3();
}
}
}
} // End of namespace Martian
} // End of namespace Access

View File

@@ -0,0 +1,64 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ACCESS_MARTIAN_ROOM_H
#define ACCESS_MARTIAN_ROOM_H
#include "common/scummsys.h"
#include "access/room.h"
namespace Access {
class AccessEngine;
namespace Martian {
class MartianEngine;
class MartianRoom : public Room {
private:
MartianEngine *_game;
protected:
void loadRoom(int roomNumber) override;
void roomInit() override;
void reloadRoom() override;
void reloadRoom1() override;
void mainAreaClick() override;
public:
MartianRoom(AccessEngine *vm);
~MartianRoom() override;
void init4Quads() override { }
void roomMenu() override;
};
} // End of namespace Martian
} // End of namespace Access
#endif /* ACCESS_AMAZON_ROOM_H */

View File

@@ -0,0 +1,383 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/scummsys.h"
#include "access/access.h"
#include "access/martian/martian_game.h"
#include "access/martian/martian_resources.h"
#include "access/martian/martian_duct.h"
#include "access/martian/martian_scripts.h"
namespace Access {
namespace Martian {
MartianScripts::MartianScripts(AccessEngine *vm) : Scripts(vm) {
_game = (MartianEngine *)_vm;
_duct = new MartianDuct(_game);
}
MartianScripts::~MartianScripts() {
delete _duct;
}
void MartianScripts::cmdSpecial0() {
// Abduction scene
_vm->_sound->stopSound();
_vm->_midi->stopSong();
_vm->_midi->loadMusic(47, 1);
_vm->_midi->midiPlay();
_vm->_midi->setLoop(true);
_vm->_screen->forceFadeOut();
_vm->_files->loadScreen("HOUSE.SC");
_vm->_video->setVideo(_vm->_screen, Common::Point(46, 30), "HVID.VID", 20);
_vm->_events->hideCursor();
_vm->_events->_vbCount = 300;
while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0)
_vm->_events->pollEventsAndWait();
do {
_vm->_video->playVideo();
_vm->_events->pollEvents();
if (_vm->_video->_videoFrame == 4) {
_vm->_screen->flashPalette(16);
_vm->_sound->playSound(4);
do {
_vm->_events->pollEvents();
} while (!_vm->shouldQuit() && _vm->_sound->isSFXPlaying());
//
// TODO:
//
// The original sets these, probably to hold the video until the sound finishes?
// But, if we do that they never get past frame 4, because in the next iteration
// of the loop the timer is still "counting down", so we stay on frame 4 forever.
//
// Need to double-check the exact flow of the original here.
//
//_vm->_timers[31]._timer = _vm->_timers[31]._initTm = 40;
}
} while (!_vm->_video->_videoEnd && !_vm->shouldQuit());
if (_vm->shouldQuit())
return;
_vm->_screen->flashPalette(12);
_vm->_sound->playSound(4);
do {
_vm->_events->pollEvents();
} while (!_vm->shouldQuit() && _vm->_sound->isSFXPlaying());
_vm->_events->showCursor();
_vm->_midi->stopSong();
_vm->_midi->freeMusic();
}
void MartianScripts::cmdSpecial1(int param1, int param2) {
//
// Special 1 is a scene transition with some explanatory text
//
_vm->_events->hideCursor();
if ((byte)param1 != (byte)-1) {
_vm->_files->loadScreen(49, param1);
_vm->_buffer2.copyBuffer(_vm->_screen);
}
_vm->_screen->setIconPalette();
_vm->_screen->forceFadeIn();
_vm->_events->showCursor();
_vm->establish(0, param2);
}
void MartianScripts::cmdSpecial2() {
_duct->duct2();
}
void MartianScripts::cmdSpecial3() {
_vm->_screen->forceFadeOut();
_vm->_events->hideCursor();
_vm->_files->loadScreen(57, 3);
_vm->_buffer2.copyFrom(*_vm->_screen);
_vm->_screen->setIconPalette();
_vm->_events->showCursor();
_vm->_screen->forceFadeIn();
}
void MartianScripts::cmdSpecial4() {
_duct->duct4();
}
void MartianScripts::doIntro(int param1) {
_game->doSpecial5(param1);
}
void MartianScripts::cmdSpecial6() {
// A special transition screen after the jetpack in the outpost.
debug("cmdSpecial6: TODO: Store current music?");
_vm->_midi->stopSong();
_vm->_screen->setDisplayScan();
_vm->_events->clearEvents();
_vm->_screen->forceFadeOut();
_vm->_events->hideCursor();
_vm->_files->loadScreen(49, 9);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
_vm->_screen->forceFadeIn();
Resource *cellsRes = _vm->_files->loadFile("CELLS00.LZ");
_vm->_objectsTable[0] = new SpriteResource(_vm, cellsRes);
delete cellsRes;
_vm->_timers[20]._timer = _vm->_timers[20]._initTm = 30;
_vm->_fonts._charSet._lo = 1;
_vm->_fonts._charSet._hi = 10;
_vm->_fonts._charFor._lo = 1;
_vm->_fonts._charFor._hi = 255;
_vm->_screen->_maxChars = 50;
_vm->_screen->_printOrg = _vm->_screen->_printStart = Common::Point(24, 18);
Resource *notesRes = _vm->_files->loadFile("ETEXT.DAT");
notesRes->_stream->seek(72);
uint16 offset = notesRes->_stream->readUint16LE();
notesRes->_stream->seek(offset);
// Read the message
Common::String msg = notesRes->_stream->readString();
//display the message
_game->showExpositionText(msg);
delete notesRes;
delete _vm->_objectsTable[0];
_vm->_objectsTable[0] = nullptr;
_vm->_midi->stopSong();
// WORKAROUND: Reset Tex's scale flag after jetpack.
// (bug also present in original game)
_vm->_player->_flags &= ~IMGFLAG_UNSCALED;
// We always go straight to another scene so this seems
// redundant..
debug("cmdSpecial6: TODO: Restore original music?");
}
void MartianScripts::cmdSpecial7() {
_vm->_room->clearRoom();
_vm->_midi->loadMusic(47, 8);
_vm->_sound->freeSounds();
Resource *sound = _vm->_sound->loadSound(46, 14);
_vm->_sound->_soundTable.push_back(SoundEntry(sound, 1));
_vm->_screen->setDisplayScan();
_vm->_screen->forceFadeOut();
_vm->_events->hideCursor();
_vm->_files->loadScreen(40, 3);
_vm->_buffer1.copyBuffer(_vm->_screen);
_vm->_buffer2.copyBuffer(_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
_vm->_screen->forceFadeIn();
// Load objects specific to this special scene
Resource *data = _vm->_files->loadFile(40, 2);
_game->_objectsTable[40] = new SpriteResource(_vm, data);
delete data;
// Load animation data
_vm->_animation->freeAnimationData();
Resource *animResource = _vm->_files->loadFile(40, 1);
_vm->_animation->loadAnimations(animResource);
delete animResource;
// Load script
Resource *newScript = _vm->_files->loadFile(40, 0);
setScript(newScript);
_vm->_images.clear();
_vm->_oldRects.clear();
_sequence = 0;
searchForSequence();
executeScript();
_vm->_sound->playSound(0);
do {
charLoop();
_vm->_events->pollEvents();
} while (_vm->_flags[134] != 1);
do {
_vm->_events->pollEvents();
} while (!_vm->shouldQuit() && _vm->_sound->isSFXPlaying());
_vm->_animation->clearTimers();
_vm->_animation->freeAnimationData();
_vm->_scripts->freeScriptData();
_vm->_sound->freeSounds();
_vm->_screen->forceFadeOut();
_vm->_midi->midiPlay();
_vm->_midi->setLoop(true);
_vm->_events->hideCursor();
_vm->_files->loadScreen(40, 4);
_vm->_buffer1.copyBuffer(_vm->_screen);
_vm->_buffer2.copyBuffer(_vm->_screen);
_vm->_events->showCursor();
_vm->_screen->setIconPalette();
_vm->_screen->forceFadeIn();
// Setup fonts
_vm->_fonts._charSet._hi = 10;
_vm->_fonts._charSet._lo = 1;
_vm->_fonts._charFor._lo = 247;
_vm->_fonts._charFor._hi = 255;
_vm->_screen->_maxChars = 50;
_vm->_screen->_printOrg = Common::Point(24, 18);
_vm->_screen->_printStart = Common::Point(24, 18);
_game->showExpositionText(Common::String(SPEC7MESSAGE));
_vm->_events->showCursor();
_vm->_screen->copyBuffer(&_vm->_buffer1);
_vm->_events->hideCursor();
_vm->_video->setVideo(_vm->_screen, Common::Point(120, 16), FileIdent(40, 5), 10);
while (!_vm->shouldQuit() && !_vm->_video->_videoEnd) {
_vm->_video->playVideo();
_vm->_events->pollEventsAndWait();
}
_vm->_sound->freeSounds();
sound = _vm->_sound->loadSound(40, 8);
_vm->_sound->_soundTable.push_back(SoundEntry(sound, 1));
sound = _vm->_sound->loadSound(40, 9);
_vm->_sound->_soundTable.push_back(SoundEntry(sound, 1));
sound = _vm->_sound->loadSound(40, 10);
_vm->_sound->_soundTable.push_back(SoundEntry(sound, 1));
_vm->_screen->forceFadeOut();
_vm->_files->loadScreen(40, 7);
_vm->_destIn = _vm->_screen;
_vm->_screen->plotImage(_game->_objectsTable[40], 8, Common::Point(176, 104));
_vm->_screen->plotImage(_game->_objectsTable[40], 7, Common::Point(160, 102));
_vm->_events->showCursor();
_vm->_screen->forceFadeIn();
_vm->_events->_vbCount = 100;
while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0)
_vm->_events->pollEventsAndWait();
_vm->_sound->playSound(0);
do {
_vm->_events->pollEvents();
} while (!_vm->shouldQuit() && _vm->_sound->isSFXPlaying());
_vm->_events->_vbCount = 80;
while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0)
_vm->_events->pollEventsAndWait();
_vm->_sound->playSound(1);
do {
_vm->_events->pollEvents();
} while (!_vm->shouldQuit() && _vm->_sound->isSFXPlaying());
_vm->_events->_vbCount = 80;
while (!_vm->shouldQuit() && _vm->_events->_vbCount > 0)
_vm->_events->pollEventsAndWait();
_vm->_sound->playSound(2);
do {
_vm->_events->pollEvents();
} while (!_vm->shouldQuit() && _vm->_sound->isSFXPlaying());
_vm->_sound->freeSounds();
delete _game->_objectsTable[40];
_game->_objectsTable[40] = nullptr;
_vm->_events->hideCursor();
_vm->_screen->forceFadeOut();
_vm->_files->loadScreen(40, 6);
_vm->_events->showCursor();
_vm->_screen->forceFadeIn();
_vm->_events->waitKeyActionMouse();
_vm->_midi->stopSong();
_vm->_midi->freeMusic();
// The original was jumping to the restart label in main
_vm->_restartFl = true;
_vm->_events->pollEvents();
}
void MartianScripts::executeSpecial(int commandIndex, int param1, int param2) {
switch (commandIndex) {
case 0:
cmdSpecial0();
break;
case 1:
cmdSpecial1(param1, param2);
break;
case 2:
cmdSpecial2();
break;
case 3:
cmdSpecial3();
break;
case 4:
cmdSpecial4();
break;
case 5:
doIntro(param1);
break;
case 6:
cmdSpecial6();
break;
case 7:
cmdSpecial7();
break;
default:
warning("Unexpected Special code %d - Skipped", commandIndex);
}
}
typedef void(MartianScripts::*MartianScriptMethodPtr)();
void MartianScripts::executeCommand(int commandIndex) {
Scripts::executeCommand(commandIndex);
}
} // End of namespace Martian
} // End of namespace Access

View File

@@ -0,0 +1,62 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ACCESS_MARTIAN_SCRIPTS_H
#define ACCESS_MARTIAN_SCRIPTS_H
#include "common/scummsys.h"
#include "access/scripts.h"
namespace Access {
namespace Martian {
class MartianEngine;
class MartianDuct;
class MartianScripts : public Scripts {
private:
MartianEngine *_game;
MartianDuct *_duct;
void cmdSpecial0();
void cmdSpecial1(int param1, int param2);
void cmdSpecial2();
void cmdSpecial3();
void cmdSpecial4();
void doIntro(int param1);
void cmdSpecial6();
void cmdSpecial7();
protected:
void executeSpecial(int commandIndex, int param1, int param2) override;
void executeCommand(int commandIndex) override;
public:
MartianScripts(AccessEngine *vm);
~MartianScripts();
};
} // End of namespace Martian
} // End of namespace Access
#endif /* ACCESS_MARTIAN_SCRIPTS_H */

View File

@@ -0,0 +1,207 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "access/martian/midiparser_bemd.h"
#include "audio/mididrv.h"
#include "audio/midiparser.h"
#include "common/textconsole.h"
#include "common/util.h"
#include "common/file.h"
namespace Access {
MidiParser_BEmd::MidiParser_BEmd(): _tickData(nullptr), _tickDataEnd(nullptr), _trackDataEnd(nullptr) {
}
bool MidiParser_BEmd::loadMusic(const byte *data, uint32 size) {
unloadMusic();
const byte *pos = data;
//
// 'BEmd' MIDI format from Martian Memorandum.
//
// A simple single-track format that splits note and timing data.
//
// Header is:
// 'BEmd' (magic number)
// 0xC0 0x00 (unknown, always 0xC0?
// 16-bit offset to timing data block
// 16-bit size of timing data block
// 6 bytes unk (normally 0)
// Header is followed by the track data block, then timing delta data
// block.
//
// Track data mostly follows other MIDI formats with a few differences:
// * Fixed length arguments
// * 0xFF 0x51 (tempo meta event) is followed by a uint16 which is fed
// directly to the PIT as a delay
// * Deltas are assumed to be 0. On 0xF8, a 16 bit int is read from
// the timing block and sent to the PIT as a timing delay.
//
if (!memcmp(pos, "BEmd", 4)) {
pos += 4;
if (size <= 16)
error("Wrong BEmd music resource size");
/*uint16 unk1 = */ READ_LE_UINT16(pos); // Normally 0xC0?
uint16 secondBlockOffset = READ_LE_UINT16(pos + 2);
if (secondBlockOffset < 16 || secondBlockOffset >= size)
error("Bad second block offset in BEmd file");
uint16 secondBlockSize = READ_LE_UINT16(pos + 4);
if (static_cast<uint32>(secondBlockOffset + secondBlockSize) != size)
error("Bad second block offset+size in BEmd file");
_trackDataEnd = data + secondBlockOffset;
_tickData = _trackDataEnd;
_tickDataEnd = data + size;
// Only one track
_numTracks = 1;
_numSubtracks[0] = 1;
_autoLoop = false;
_ppqn = 1;
_tracks[0][0] = data + 16;
resetTracking();
setTempo(16667);
setTrack(0);
return true;
} else {
warning("Expected BEmd header but found '%c%c%c%c' instead", pos[0], pos[1], pos[2], pos[3]);
return false;
}
return false;
}
void MidiParser_BEmd::parseNextEvent(EventInfo &info) {
uint8 subtrack = info.subtrack;
const byte *playPos = _position._subtracks[subtrack]._playPos;
info.start = playPos;
info.delta = 0;
// Process the next info.
if ((playPos[0] & 0xF0) >= 0x80)
info.event = *(playPos++);
else
info.event = _position._subtracks[subtrack]._runningStatus;
if (info.event < 0x80) {
_position._subtracks[subtrack]._playPos = playPos;
return;
}
_position._subtracks[subtrack]._runningStatus = info.event;
switch (info.command()) {
case 0x9: // Note On
info.basic.param1 = *(playPos++);
info.basic.param2 = *(playPos++);
if (info.basic.param2 == 0)
info.event = info.channel() | 0x80;
info.length = 0;
break;
case 0xC:
case 0xD:
info.basic.param1 = *(playPos++);
info.basic.param2 = 0;
break;
case 0x8:
case 0xA:
case 0xB:
case 0xE:
info.basic.param1 = *(playPos++);
info.basic.param2 = *(playPos++);
info.length = 0;
break;
case 0xF:
switch (info.event & 0x0F) {
case 0x2: // Song Position Pointer
info.basic.param1 = *(playPos++);
info.basic.param2 = *(playPos++);
break;
case 0x3: // Song Select
info.basic.param1 = *(playPos++);
info.basic.param2 = 0;
break;
case 0x8: // Timing data
// Tick data is stored separately.
info.delta = READ_LE_UINT16(_tickData);
_tickData += 2;
// FALL THROUGH
case 0x6:
case 0xA:
case 0xB:
case 0xC:
case 0xE:
info.basic.param1 = info.basic.param2 = 0;
break;
case 0x0: // SysEx
error("MidiParser_BEmd::parseNextEvent: Unexpected SysEx event");
break;
case 0xF: // META event
info.ext.type = *(playPos++);
if (info.ext.type == 0x51) {
// Set Tempo - 2 bytes and interpreted as direct input for the PIT
// as ticks to next note (0.8381uS/tick)
setTempo(READ_LE_UINT16(playPos) * 0.8381);
}
info.length = (info.ext.type == 0x2f ? 0 : 2);
info.ext.data = playPos;
playPos += info.length;
break;
default:
error("MidiParser_BEmd::parseNextEvent: Unsupported event code %x", info.event);
break;
}
default:
break;
}
_position._subtracks[subtrack]._playPos = playPos;
assert(playPos < _trackDataEnd);
assert(_tickData < _tickDataEnd);
}
bool MidiParser_BEmd::processEvent(const EventInfo &info, bool fireEvents) {
// Ignore timer events we handled already.
if ((info.event == 0xF8) || (info.event == 0xFF && info.ext.type == 0x51))
return true;
return MidiParser::processEvent(info, fireEvents);
}
void MidiParser_BEmd::resetTracking() {
_tickData = _trackDataEnd;
MidiParser::resetTracking();
}
} // end namespace Access

View File

@@ -0,0 +1,49 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ACCESS_MARTIAN_MIDI_PARSER_BEMD_H
#define ACCESS_MARTIAN_MIDI_PARSER_BEMD_H
#include "audio/midiparser.h"
namespace Access {
class MidiParser_BEmd : public MidiParser {
public:
MidiParser_BEmd();
bool loadMusic(const byte *data, uint32 size) override;
protected:
void parseNextEvent(EventInfo &info) override;
bool processEvent(const EventInfo &info, bool fireEvents) override;
void resetTracking() override;
private:
const byte *_trackDataEnd;
const byte *_tickData;
const byte *_tickDataEnd;
};
} // end namespace Access
#endif // ACCESS_MARTIAN_MIDI_PARSER_BEMD_H