2011-06-05 09:38:05 +00:00
|
|
|
/* 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 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: https://svn.scummvm.org:4444/svn/dreamweb/dreamweb.cpp $
|
|
|
|
* $Id: dreamweb.cpp 79 2011-06-05 08:26:54Z eriktorbjorn $
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "common/config-manager.h"
|
|
|
|
#include "common/debug-channels.h"
|
|
|
|
#include "common/events.h"
|
|
|
|
#include "common/EventRecorder.h"
|
|
|
|
#include "common/file.h"
|
|
|
|
#include "common/func.h"
|
|
|
|
#include "common/iff_container.h"
|
|
|
|
#include "common/system.h"
|
|
|
|
#include "common/timer.h"
|
2011-06-08 07:26:46 +00:00
|
|
|
#include "common/util.h"
|
2011-06-05 09:38:05 +00:00
|
|
|
|
|
|
|
#include "engines/util.h"
|
|
|
|
|
|
|
|
#include "audio/mixer.h"
|
|
|
|
|
|
|
|
#include "graphics/palette.h"
|
2011-06-08 07:26:46 +00:00
|
|
|
#include "graphics/surface.h"
|
2011-06-05 09:38:05 +00:00
|
|
|
|
|
|
|
#include "dreamweb/dreamweb.h"
|
2011-06-05 10:49:56 +00:00
|
|
|
#include "dreamweb/dreamgen.h"
|
2011-06-05 09:38:05 +00:00
|
|
|
|
|
|
|
namespace DreamWeb {
|
|
|
|
|
2011-06-06 23:00:53 +00:00
|
|
|
DreamWebEngine *DreamWebEngine::_instance;
|
|
|
|
|
|
|
|
DreamWebEngine::DreamWebEngine(OSystem *syst, const DreamWebGameDescription *gameDesc) :
|
|
|
|
Engine(syst), _gameDescription(gameDesc), _rnd("dreamweb") {
|
2011-06-05 09:38:05 +00:00
|
|
|
// Setup mixer
|
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
|
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
|
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
|
|
|
|
|
|
|
|
_vSyncInterrupt = false;
|
|
|
|
|
|
|
|
_console = 0;
|
|
|
|
DebugMan.addDebugChannel(kDebugAnimation, "Animation", "Animation Debug Flag");
|
|
|
|
DebugMan.addDebugChannel(kDebugSaveLoad, "SaveLoad", "Track Save/Load Function");
|
2011-06-06 23:00:53 +00:00
|
|
|
_instance = this;
|
2011-06-05 09:38:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DreamWebEngine::~DreamWebEngine() {
|
|
|
|
DebugMan.clearAllDebugChannels();
|
|
|
|
delete _console;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Let's see if it's a good idea to emulate VSYNC interrupts with a timer like
|
|
|
|
// this. There's a chance we'll miss interrupts, which could be countered by
|
|
|
|
// counting them instead of just flagging them, but we'll see...
|
|
|
|
|
|
|
|
static void vSyncInterrupt(void *refCon) {
|
|
|
|
DreamWebEngine *vm = (DreamWebEngine *)refCon;
|
|
|
|
|
|
|
|
if (!vm->isPaused()) {
|
|
|
|
vm->setVSyncInterrupt(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DreamWebEngine::setVSyncInterrupt(bool flag) {
|
|
|
|
_vSyncInterrupt = flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DreamWebEngine::waitForVSync() {
|
2011-06-08 07:14:12 +00:00
|
|
|
processEvents();
|
2011-06-11 12:52:05 +00:00
|
|
|
|
2011-06-05 09:38:05 +00:00
|
|
|
while (!_vSyncInterrupt) {
|
|
|
|
_system->delayMillis(10);
|
|
|
|
}
|
|
|
|
setVSyncInterrupt(false);
|
2011-06-11 12:52:05 +00:00
|
|
|
|
2011-06-05 09:38:05 +00:00
|
|
|
// doshake
|
|
|
|
// dofade
|
|
|
|
}
|
|
|
|
|
2011-06-08 07:14:12 +00:00
|
|
|
void DreamWebEngine::processEvents() {
|
2011-06-05 09:38:05 +00:00
|
|
|
Common::EventManager *event_manager = _system->getEventManager();
|
2011-06-08 07:14:12 +00:00
|
|
|
Common::Event event;
|
|
|
|
while (event_manager->pollEvent(event)) {
|
|
|
|
switch(event.type) {
|
|
|
|
case Common::EVENT_RTL:
|
|
|
|
warning("quit requested");
|
|
|
|
return;
|
|
|
|
case Common::EVENT_LBUTTONDOWN:
|
|
|
|
_mouseState |= 1;
|
|
|
|
break;
|
|
|
|
case Common::EVENT_LBUTTONUP:
|
|
|
|
_mouseState &= ~1;
|
|
|
|
break;
|
|
|
|
case Common::EVENT_RBUTTONDOWN:
|
|
|
|
_mouseState |= 2;
|
|
|
|
break;
|
|
|
|
case Common::EVENT_RBUTTONUP:
|
|
|
|
_mouseState &= ~2;
|
|
|
|
break;
|
|
|
|
case Common::EVENT_MOUSEMOVE:
|
|
|
|
_mouse = event.mouse;
|
|
|
|
break;
|
|
|
|
case Common::EVENT_KEYDOWN:
|
|
|
|
switch (event.kbd.keycode) {
|
|
|
|
case Common::KEYCODE_d:
|
|
|
|
if (event.kbd.flags & Common::KBD_CTRL) {
|
|
|
|
_console->attach();
|
|
|
|
_console->onFrame();
|
2011-06-05 09:38:05 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2011-06-10 07:46:54 +00:00
|
|
|
if (event.kbd.ascii)
|
|
|
|
keyPressed(event.kbd.ascii);
|
2011-06-08 07:14:12 +00:00
|
|
|
break;
|
2011-06-05 09:38:05 +00:00
|
|
|
}
|
2011-06-08 07:14:12 +00:00
|
|
|
break;
|
|
|
|
default:
|
2011-06-08 07:26:46 +00:00
|
|
|
break;
|
2011-06-05 09:38:05 +00:00
|
|
|
}
|
2011-06-08 07:14:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Common::Error DreamWebEngine::run() {
|
|
|
|
_mouseState = 0;
|
|
|
|
_console = new DreamWebConsole(this);
|
2011-06-05 09:38:05 +00:00
|
|
|
|
2011-06-11 12:52:05 +00:00
|
|
|
getTimerManager()->installTimerProc(vSyncInterrupt, 1000000 / 70, this);
|
|
|
|
//http://martin.hinner.info/vga/timing.html
|
2011-06-08 07:14:12 +00:00
|
|
|
|
|
|
|
dreamgen::__start(_context);
|
|
|
|
|
2011-06-05 09:38:05 +00:00
|
|
|
getTimerManager()->removeTimerProc(vSyncInterrupt);
|
|
|
|
|
|
|
|
return Common::kNoError;
|
|
|
|
}
|
|
|
|
|
2011-06-07 21:25:26 +00:00
|
|
|
void DreamWebEngine::openFile(const Common::String &name) {
|
2011-06-08 07:14:12 +00:00
|
|
|
processEvents();
|
2011-06-07 21:25:26 +00:00
|
|
|
if (_file.isOpen()) {
|
|
|
|
_file.close();
|
|
|
|
}
|
2011-06-07 22:46:54 +00:00
|
|
|
if (!_file.open(name)) {
|
2011-06-07 21:25:26 +00:00
|
|
|
error("cannot open file %s", name.c_str());
|
2011-06-07 22:46:54 +00:00
|
|
|
}
|
2011-06-07 21:25:26 +00:00
|
|
|
}
|
|
|
|
|
2011-06-08 22:00:41 +00:00
|
|
|
uint32 DreamWebEngine::readFromFile(uint8 *dst, unsigned size) {
|
2011-06-08 07:14:12 +00:00
|
|
|
processEvents();
|
2011-06-07 22:49:05 +00:00
|
|
|
if (!_file.isOpen())
|
|
|
|
error("file was not opened (read before open)");
|
2011-06-08 22:00:41 +00:00
|
|
|
return _file.read(dst, size);
|
2011-06-07 21:38:12 +00:00
|
|
|
}
|
|
|
|
|
2011-06-07 21:51:01 +00:00
|
|
|
void DreamWebEngine::closeFile() {
|
2011-06-08 07:14:12 +00:00
|
|
|
processEvents();
|
2011-06-07 21:51:01 +00:00
|
|
|
_file.close();
|
|
|
|
}
|
|
|
|
|
2011-06-10 07:30:11 +00:00
|
|
|
void DreamWebEngine::keyPressed(uint16 ascii) {
|
|
|
|
debug(1, "key pressed = %04x", ascii);
|
|
|
|
uint8* keybuf = _context.data.ptr(5715, 16); //fixme: some hardcoded offsets are not added as consts
|
|
|
|
uint16 in = (_context.data.word(dreamgen::kBufferin) + 1) % 0x0f;
|
|
|
|
uint16 out = _context.data.word(dreamgen::kBufferout);
|
|
|
|
if (in == out) {
|
|
|
|
warning("keyboard buffer is full");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_context.data.word(dreamgen::kBufferin) = in;
|
|
|
|
keybuf[in] = ascii;
|
|
|
|
}
|
|
|
|
|
2011-06-08 07:14:12 +00:00
|
|
|
void DreamWebEngine::mouseCall() {
|
|
|
|
processEvents();
|
|
|
|
Common::Point pos = _mouse;
|
|
|
|
if (pos.x > 298)
|
|
|
|
pos.x = 298;
|
|
|
|
if (pos.x < 15)
|
|
|
|
pos.x = 15;
|
|
|
|
if (pos.y < 15)
|
|
|
|
pos.y = 15;
|
|
|
|
if (pos.y > 184)
|
|
|
|
pos.y = 184;
|
|
|
|
_context.cx = pos.x;
|
|
|
|
_context.dx = pos.y;
|
|
|
|
_context.bx = _mouseState;
|
|
|
|
}
|
|
|
|
|
2011-06-08 07:26:46 +00:00
|
|
|
void DreamWebEngine::setGraphicsMode() {
|
2011-06-10 06:47:23 +00:00
|
|
|
processEvents();
|
2011-06-08 07:26:46 +00:00
|
|
|
initGraphics(320, 200, false);
|
|
|
|
}
|
|
|
|
|
2011-06-09 22:18:57 +00:00
|
|
|
void DreamWebEngine::fadeDos() {
|
2011-06-11 12:08:30 +00:00
|
|
|
waitForVSync();
|
2011-06-10 06:47:23 +00:00
|
|
|
//processEvents will be called from vsync
|
2011-06-09 22:18:57 +00:00
|
|
|
_context.ds = _context.es = _context.data.word(dreamgen::kBuffers);
|
2011-06-09 22:48:11 +00:00
|
|
|
uint8 *dst = _context.es.ptr(dreamgen::kStartpal, 768);
|
2011-06-11 13:20:00 +00:00
|
|
|
getPalette(dst, 0, 64);
|
2011-06-09 22:18:57 +00:00
|
|
|
for(int fade = 0; fade < 64; ++fade) {
|
|
|
|
for(int c = 0; c < 768; ++c) { //original sources decrement 768 values -> 256 colors
|
|
|
|
if (dst[c]) {
|
|
|
|
--dst[c];
|
|
|
|
}
|
|
|
|
}
|
2011-06-11 13:20:00 +00:00
|
|
|
setPalette(dst, 0, 64);
|
2011-06-11 12:08:30 +00:00
|
|
|
waitForVSync();
|
2011-06-09 22:18:57 +00:00
|
|
|
}
|
|
|
|
}
|
2011-06-11 12:52:05 +00:00
|
|
|
|
2011-06-10 06:43:13 +00:00
|
|
|
void DreamWebEngine::setPalette() {
|
2011-06-10 06:47:23 +00:00
|
|
|
processEvents();
|
2011-06-10 06:43:13 +00:00
|
|
|
unsigned n = (uint16)_context.cx;
|
2011-06-10 07:46:54 +00:00
|
|
|
uint8 *src = _context.ds.ptr(_context.si, n * 3);
|
2011-06-11 13:20:00 +00:00
|
|
|
setPalette(src, _context.al, n);
|
2011-06-10 06:43:13 +00:00
|
|
|
_context.si += n * 3;
|
|
|
|
_context.cx = 0;
|
|
|
|
}
|
2011-06-07 21:25:26 +00:00
|
|
|
|
2011-06-11 13:20:00 +00:00
|
|
|
void DreamWebEngine::getPalette(uint8 *data, uint start, uint count) {
|
|
|
|
_system->getPaletteManager()->grabPalette(data, start, count);
|
|
|
|
while(count--)
|
|
|
|
*data++ >>= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DreamWebEngine::setPalette(const uint8 *data, uint start, uint count) {
|
|
|
|
assert(start + count <= 256);
|
|
|
|
uint8 fixed[768];
|
|
|
|
for(uint i = 0; i < count * 3; ++i) {
|
|
|
|
fixed[i] = data[i] << 2;
|
|
|
|
}
|
|
|
|
_system->getPaletteManager()->setPalette(fixed, start, count);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DreamWebEngine::blit(const uint8 *src, int pitch, int x, int y, int w, int h) {
|
2011-06-11 12:08:30 +00:00
|
|
|
_system->copyRectToScreen(src, pitch, x, y, w, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DreamWebEngine::cls() {
|
|
|
|
_system->fillScreen(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-05 09:38:05 +00:00
|
|
|
} // End of namespace DreamWeb
|
2011-06-05 11:01:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace dreamgen {
|
2011-06-06 23:00:53 +00:00
|
|
|
|
|
|
|
static inline DreamWeb::DreamWebEngine *engine() {
|
|
|
|
return DreamWeb::DreamWebEngine::instance();
|
|
|
|
}
|
|
|
|
|
2011-06-10 05:53:35 +00:00
|
|
|
void multiget(Context &context) {
|
2011-06-10 06:24:02 +00:00
|
|
|
unsigned w = (uint8)context.cl, h = (uint8)context.ch;
|
2011-06-11 12:27:36 +00:00
|
|
|
unsigned src = (uint16)context.di + (uint16)context.bx * kScreenwidth;
|
2011-06-10 06:24:02 +00:00
|
|
|
unsigned dst = (uint16)context.si;
|
|
|
|
context.es = context.ds;
|
|
|
|
context.ds = context.data.word(kWorkspace);
|
|
|
|
//debug(1, "multiget %ux%u -> segment: %04x->%04x", w, h, (uint16)context.ds, (uint16)context.es);
|
|
|
|
for(unsigned y = 0; y < h; ++y) {
|
2011-06-11 12:27:36 +00:00
|
|
|
uint8 *src_p = context.ds.ptr(src + kScreenwidth * y, w);
|
2011-06-10 06:24:02 +00:00
|
|
|
uint8 *dst_p = context.es.ptr(dst + w * y, w);
|
2011-06-10 07:46:54 +00:00
|
|
|
memcpy(dst_p, src_p, w);
|
2011-06-10 06:24:02 +00:00
|
|
|
}
|
2011-06-10 05:53:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void multiput(Context &context) {
|
2011-06-10 06:24:02 +00:00
|
|
|
unsigned w = (uint8)context.cl, h = (uint8)context.ch;
|
|
|
|
unsigned src = (uint16)context.si;
|
2011-06-11 12:27:36 +00:00
|
|
|
unsigned dst = (uint16)context.di + (uint16)context.bx * kScreenwidth;
|
2011-06-10 06:24:02 +00:00
|
|
|
context.es = context.data.word(kWorkspace);
|
|
|
|
//debug(1, "multiput %ux%u -> segment: %04x->%04x", w, h, (uint16)context.ds, (uint16)context.es);
|
|
|
|
for(unsigned y = 0; y < h; ++y) {
|
|
|
|
uint8 *src_p = context.ds.ptr(src + w * y, w);
|
2011-06-11 12:27:36 +00:00
|
|
|
uint8 *dst_p = context.es.ptr(dst + kScreenwidth * y, w);
|
2011-06-10 07:46:54 +00:00
|
|
|
memcpy(dst_p, src_p, w);
|
2011-06-10 06:24:02 +00:00
|
|
|
}
|
2011-06-10 05:53:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void multidump(Context &context) {
|
2011-06-11 12:52:05 +00:00
|
|
|
context.ds = context.data.word(kWorkspace);
|
2011-06-11 12:08:30 +00:00
|
|
|
int w = (uint8)context.cl, h = (uint8)context.ch;
|
2011-06-11 12:52:05 +00:00
|
|
|
if (w == 0 || h == 0)
|
|
|
|
return;
|
2011-06-11 12:08:30 +00:00
|
|
|
int x = (int16)context.di, y = (int16)context.bx;
|
2011-06-11 12:27:36 +00:00
|
|
|
unsigned offset = x + y * kScreenwidth;
|
|
|
|
debug(1, "multidump %ux%u(segment: %04x) -> %d,%d(address: %d)", w, h, (uint16)context.ds, x, y, offset);
|
|
|
|
engine()->blit(context.ds.ptr(offset, w * h), kScreenwidth, x, y, w, h);
|
2011-06-11 12:08:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void worktoscreen(Context &context) {
|
|
|
|
context.ds = context.data.word(kWorkspace);
|
|
|
|
engine()->blit(context.ds.ptr(0, 320 * 200), 320, 0, 0, 320, 200);
|
|
|
|
}
|
|
|
|
|
|
|
|
void printundermon(Context &context) {
|
|
|
|
warning("printundermon: STUB");
|
|
|
|
}
|
|
|
|
|
|
|
|
void cls(Context &context) {
|
|
|
|
engine()->cls();
|
2011-06-10 05:53:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void frameoutnm(Context &context) {
|
2011-06-10 06:43:13 +00:00
|
|
|
unsigned w = (uint8)context.cl, h = (uint8)context.ch;
|
|
|
|
unsigned pitch = (uint16)context.dx;
|
|
|
|
unsigned src = (uint16)context.si;
|
|
|
|
unsigned dst = (uint16)context.di + (uint16)context.bx * pitch;
|
|
|
|
//debug(1, "framenm %ux%u[pitch: %u] -> segment: %04x->%04x", w, h, pitch, (uint16)context.ds, (uint16)context.es);
|
|
|
|
for(unsigned y = 0; y < h; ++y) {
|
|
|
|
uint8 *src_p = context.ds.ptr(src + w * y, w);
|
|
|
|
uint8 *dst_p = context.es.ptr(dst + pitch * y, w);
|
2011-06-10 07:46:54 +00:00
|
|
|
memcpy(dst_p, src_p, w);
|
2011-06-10 06:43:13 +00:00
|
|
|
}
|
2011-06-10 05:53:35 +00:00
|
|
|
}
|
|
|
|
|
2011-06-06 22:45:48 +00:00
|
|
|
void seecommandtail(Context &context) {
|
2011-06-08 07:26:46 +00:00
|
|
|
context.data.word(kSoundbaseadd) = 0x220;
|
|
|
|
context.data.byte(kSoundint) = 5;
|
|
|
|
context.data.byte(kSounddmachannel) = 1;
|
|
|
|
context.data.byte(kBrightness) = 1;
|
|
|
|
context.data.word(kHowmuchalloc) = 0x9360;
|
2011-06-06 22:45:48 +00:00
|
|
|
}
|
|
|
|
|
2011-06-05 11:01:01 +00:00
|
|
|
void randomnumber(Context &context) {
|
2011-06-06 23:00:53 +00:00
|
|
|
context.al = engine()->randomNumber();
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void quickquit(Context &context) {
|
2011-06-06 22:45:48 +00:00
|
|
|
assert(0);
|
2011-06-05 11:01:01 +00:00
|
|
|
::error("quickquit");
|
|
|
|
}
|
|
|
|
|
|
|
|
void quickquit2(Context &context) {
|
2011-06-06 22:45:48 +00:00
|
|
|
assert(0);
|
2011-06-05 11:01:01 +00:00
|
|
|
::error("quickquit2");
|
|
|
|
}
|
|
|
|
|
|
|
|
void keyboardread(Context &context) {
|
2011-06-10 07:30:11 +00:00
|
|
|
::error("keyboardread"); //this keyboard int handler, must never be called
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void resetkeyboard(Context &context) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void setkeyboardint(Context &context) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void readfromfile(Context &context) {
|
2011-06-07 21:38:12 +00:00
|
|
|
uint16 dst_offset = context.dx;
|
2011-06-07 22:53:35 +00:00
|
|
|
uint16 size = context.cx;
|
|
|
|
debug(1, "readfromfile(%04x:%u, %u)", (uint16)context.ds, dst_offset, size);
|
2011-06-08 22:00:41 +00:00
|
|
|
context.ax = engine()->readFromFile(context.ds.ptr(dst_offset, size), size);
|
2011-06-08 22:08:09 +00:00
|
|
|
context.flags._c = false;
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void closefile(Context &context) {
|
2011-06-07 21:51:01 +00:00
|
|
|
engine()->closeFile();
|
2011-06-07 22:49:05 +00:00
|
|
|
context.data.byte(kHandle) = 0;
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void openforsave(Context &context) {
|
|
|
|
::error("openforsave");
|
|
|
|
}
|
|
|
|
|
|
|
|
void openfilenocheck(Context &context) {
|
|
|
|
::error("openfilenocheck");
|
|
|
|
}
|
|
|
|
|
|
|
|
void openfile(Context &context) {
|
2011-06-07 21:19:39 +00:00
|
|
|
uint16 name_ptr = context.dx;
|
|
|
|
Common::String name;
|
|
|
|
uint8 c;
|
2011-06-07 21:25:26 +00:00
|
|
|
while((c = context.cs.byte(name_ptr++)) != 0)
|
2011-06-07 21:19:39 +00:00
|
|
|
name += (char)c;
|
|
|
|
debug(1, "opening file: %s", name.c_str());
|
2011-06-07 21:38:12 +00:00
|
|
|
engine()->openFile(name);
|
2011-06-07 21:25:26 +00:00
|
|
|
context.cs.word(kHandle) = 1; //only one handle
|
|
|
|
context.flags._c = false;
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void createfile(Context &context) {
|
|
|
|
::error("createfile");
|
|
|
|
}
|
|
|
|
|
|
|
|
void dontloadseg(Context &context) {
|
|
|
|
::error("dontloadseg");
|
|
|
|
}
|
|
|
|
|
|
|
|
void mousecall(Context &context) {
|
2011-06-08 07:14:12 +00:00
|
|
|
engine()->mouseCall();
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void setmouse(Context &context) {
|
2011-06-08 07:26:46 +00:00
|
|
|
context.data.word(kOldpointerx) = 0xffff;
|
|
|
|
//warning("setmouse: fixme: add range setting");
|
2011-06-06 23:00:53 +00:00
|
|
|
//set vertical range to 15-184
|
|
|
|
//set horizontal range to 15-298*2
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void gettime(Context &context) {
|
2011-06-07 17:12:09 +00:00
|
|
|
TimeDate t;
|
|
|
|
g_system->getTimeAndDate(t);
|
|
|
|
debug(1, "\tgettime: %02d:%02d:%02d", t.tm_hour, t.tm_min, t.tm_sec);
|
|
|
|
context.ch = t.tm_hour;
|
|
|
|
context.cl = t.tm_min;
|
|
|
|
context.dh = t.tm_sec;
|
2011-06-09 06:25:36 +00:00
|
|
|
context.data.byte(kSecondcount) = context.dh;
|
|
|
|
context.data.byte(kMinutecount) = context.cl;
|
|
|
|
context.data.byte(kHourcount) = context.ch;
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void allocatemem(Context &context) {
|
2011-06-06 22:26:37 +00:00
|
|
|
uint size = (context.bx + 2) * 16;
|
|
|
|
debug(1, "allocate mem, %u bytes", size);
|
|
|
|
context.flags._c = false;
|
|
|
|
SegmentRef seg = context.allocateSegment(size);
|
|
|
|
context.ax = (uint16)seg;
|
|
|
|
debug(1, "\tsegment address -> %04x", (uint16)context.ax);
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void deallocatemem(Context &context) {
|
2011-06-09 21:48:46 +00:00
|
|
|
debug(1, "deallocating segment %04x", (uint16)context.es);
|
|
|
|
context.deallocateSegment(context.es);
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void removeemm(Context &context) {
|
|
|
|
::error("removeemm");
|
|
|
|
}
|
|
|
|
|
|
|
|
void setupemm(Context &context) {
|
2011-06-06 22:26:37 +00:00
|
|
|
//fixme: double check this, but it seems that emm pages used only for sound
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void pitinterupt(Context &context) {
|
|
|
|
::error("pitinterupt");
|
|
|
|
}
|
|
|
|
|
|
|
|
void getridofpit(Context &context) {
|
|
|
|
::error("getridofpit");
|
|
|
|
}
|
|
|
|
|
|
|
|
void setuppit(Context &context) {
|
|
|
|
::error("setuppit");
|
|
|
|
}
|
|
|
|
|
|
|
|
void startdmablock(Context &context) {
|
|
|
|
::error("startdmablock");
|
|
|
|
}
|
|
|
|
|
|
|
|
void dmaend(Context &context) {
|
|
|
|
::error("dmaend");
|
|
|
|
}
|
|
|
|
|
|
|
|
void restoreems(Context &context) {
|
|
|
|
::error("restoreems");
|
|
|
|
}
|
|
|
|
|
|
|
|
void saveems(Context &context) {
|
|
|
|
::error("saveems");
|
|
|
|
}
|
|
|
|
|
|
|
|
void bothchannels(Context &context) {
|
|
|
|
::error("bothchannels");
|
|
|
|
}
|
|
|
|
|
|
|
|
void channel1only(Context &context) {
|
|
|
|
::error("channel1only");
|
|
|
|
}
|
|
|
|
|
|
|
|
void channel0only(Context &context) {
|
|
|
|
::error("channel0only");
|
|
|
|
}
|
|
|
|
|
|
|
|
void out22c(Context &context) {
|
|
|
|
::error("out22c");
|
|
|
|
}
|
|
|
|
|
2011-06-06 21:02:09 +00:00
|
|
|
void soundstartup(Context &context) {
|
|
|
|
}
|
|
|
|
|
2011-06-05 11:01:01 +00:00
|
|
|
void soundend(Context &context) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void interupttest(Context &context) {
|
|
|
|
::error("interupttest");
|
|
|
|
}
|
|
|
|
|
|
|
|
void disablesoundint(Context &context) {
|
2011-06-07 22:17:28 +00:00
|
|
|
warning("disablesoundint: STUB");
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void enablesoundint(Context &context) {
|
2011-06-07 22:17:28 +00:00
|
|
|
warning("enablesoundint: STUB");
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void checksoundint(Context &context) {
|
2011-06-07 22:17:28 +00:00
|
|
|
context.data.byte(kTestresult) = 1;
|
|
|
|
warning("checksoundint: STUB");
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void setsoundoff(Context &context) {
|
2011-06-07 22:17:28 +00:00
|
|
|
warning("setsoundoff: STUB");
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
2011-06-09 21:48:46 +00:00
|
|
|
void readheader(Context &context);
|
2011-06-05 11:01:01 +00:00
|
|
|
|
|
|
|
void loadsample(Context &context) {
|
2011-06-07 22:17:28 +00:00
|
|
|
warning("loadsample: STUB");
|
|
|
|
openfile(context);
|
|
|
|
closefile(context);
|
2011-06-09 21:48:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void loadsecondsample(Context &context) {
|
|
|
|
warning("loadsecondsample: STUB");
|
|
|
|
openfile(context);
|
|
|
|
closefile(context);
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void loadspeech(Context &context) {
|
|
|
|
::error("loadspeech");
|
|
|
|
}
|
|
|
|
|
|
|
|
void scanfornames(Context &context) {
|
2011-06-07 22:17:28 +00:00
|
|
|
warning("scanfornames: STUB");
|
|
|
|
context.ch = 0;
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void saveseg(Context &context) {
|
|
|
|
::error("saveseg");
|
|
|
|
}
|
|
|
|
|
|
|
|
void loadseg(Context &context) {
|
2011-06-08 22:08:09 +00:00
|
|
|
context.ax = context.es.word(context.di);
|
|
|
|
context.di += 2;
|
|
|
|
|
2011-06-09 21:02:22 +00:00
|
|
|
uint16 dst_offset = context.dx;
|
|
|
|
uint16 size = context.ax;
|
|
|
|
|
2011-06-08 22:09:19 +00:00
|
|
|
debug(1, "loadseg(%04x:%u, %u)", (uint16)context.ds, dst_offset, size);
|
2011-06-08 22:08:09 +00:00
|
|
|
context.ax = engine()->readFromFile(context.ds.ptr(dst_offset, size), size);
|
|
|
|
context.flags._c = false;
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void loadposition(Context &context) {
|
|
|
|
::error("loadposition");
|
|
|
|
}
|
|
|
|
|
|
|
|
void saveposition(Context &context) {
|
|
|
|
::error("saveposition");
|
|
|
|
}
|
|
|
|
|
|
|
|
void error(Context &context) {
|
|
|
|
::error("error");
|
|
|
|
}
|
|
|
|
|
|
|
|
void generalerror(Context &context) {
|
|
|
|
::error("generalerror");
|
|
|
|
}
|
|
|
|
|
|
|
|
void dosreturn(Context &context) {
|
|
|
|
::error("dosreturn");
|
|
|
|
}
|
|
|
|
|
|
|
|
void set16colpalette(Context &context) {
|
2011-06-07 21:19:39 +00:00
|
|
|
warning("set16colpalette: STUB");
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void mode640x480(Context &context) {
|
2011-06-07 17:21:22 +00:00
|
|
|
// Video mode 12h: 640x480 pixels, 16 colors, I believe
|
2011-06-09 04:03:01 +00:00
|
|
|
context.al = 0x12 + 128;
|
|
|
|
context.ah = 0;
|
2011-06-07 17:21:22 +00:00
|
|
|
initGraphics(640, 480, true);
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void showgroup(Context &context) {
|
2011-06-10 06:43:13 +00:00
|
|
|
engine()->setPalette();
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void fadedos(Context &context) {
|
2011-06-09 22:18:57 +00:00
|
|
|
engine()->fadeDos();
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void doshake(Context &context) {
|
2011-06-11 12:08:30 +00:00
|
|
|
warning("doshake: STUB");
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void vsync(Context &context) {
|
2011-06-08 07:14:12 +00:00
|
|
|
engine()->waitForVSync();
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void setmode(Context &context) {
|
2011-06-08 07:26:46 +00:00
|
|
|
engine()->setGraphicsMode();
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void readoneblock(Context &context) {
|
2011-06-09 19:35:13 +00:00
|
|
|
context.ds = context.data.word(kWorkspace);
|
|
|
|
context.cx = 30000;
|
|
|
|
context.dx = 0;
|
|
|
|
readfromfile(context);
|
|
|
|
}
|
|
|
|
|
2011-06-09 19:49:12 +00:00
|
|
|
void readabyte(Context & context);
|
2011-06-05 11:01:01 +00:00
|
|
|
|
|
|
|
void showpcx(Context &context) {
|
2011-06-11 09:29:02 +00:00
|
|
|
Graphics::Surface *s = g_system->lockScreen();
|
|
|
|
|
2011-06-09 19:35:13 +00:00
|
|
|
openfile(context);
|
|
|
|
context.ds = context.data.word(kWorkspace);
|
|
|
|
context.cx = 128;
|
|
|
|
context.dx = 0;
|
|
|
|
readfromfile(context);
|
|
|
|
|
|
|
|
context.ds = context.data.word(kWorkspace);
|
|
|
|
context.si = 16;
|
|
|
|
context.cx = 48;
|
|
|
|
context.es = context.data.word(kBuffers);
|
|
|
|
context.di = 0+(228*13)+32+60+(32*32)+(11*10*3)+768+768;
|
2011-06-11 09:29:02 +00:00
|
|
|
uint8 *pal = context.es.ptr(context.di, 768);
|
2011-06-09 19:35:13 +00:00
|
|
|
pcxpal:
|
|
|
|
context.push(context.cx);
|
|
|
|
readabyte(context);
|
|
|
|
context._shr(context.al, 1);
|
|
|
|
context._shr(context.al, 1);
|
|
|
|
context._stosb();
|
|
|
|
context.cx = context.pop();
|
|
|
|
if (--context.cx) goto pcxpal;
|
|
|
|
context.cx = 768 - 48;
|
|
|
|
context.ax = 0x0ffff;
|
2011-06-11 09:29:02 +00:00
|
|
|
while (context.cx--) context._stosw();
|
|
|
|
|
|
|
|
// TODO: I think this is wrong. I mean, it's the right palette but I
|
|
|
|
// don't think this is the place to set it in the backend.
|
|
|
|
|
|
|
|
byte pal16[48];
|
|
|
|
for (int i = 0; i < 48; i++) {
|
|
|
|
pal16[i] = 4 * pal[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
PaletteManager *palette = g_system->getPaletteManager();
|
|
|
|
palette->setPalette(pal16, 0, 256);
|
2011-06-09 19:35:13 +00:00
|
|
|
|
|
|
|
readoneblock(context);
|
|
|
|
context.si = 0;
|
|
|
|
context.di = 0;
|
|
|
|
context.cx = 480;
|
|
|
|
convertpcx:
|
|
|
|
context.push(context.cx);
|
|
|
|
context.push(context.di);
|
|
|
|
context.ds = context.data.word(kWorkspace);
|
|
|
|
context.es = context.data.word(kBuffers);
|
|
|
|
context.di = 0+(228*13)+32+60;
|
|
|
|
context.bx = 0;
|
2011-06-11 09:29:02 +00:00
|
|
|
|
|
|
|
uint8 *src = context.es.ptr(context.di, 320);
|
|
|
|
|
2011-06-09 19:35:13 +00:00
|
|
|
sameline:
|
|
|
|
readabyte(context);
|
|
|
|
context.ah = context.al;
|
|
|
|
context._and(context.ah, 0xc0);
|
|
|
|
context._cmp(context.ah, 0xc0);
|
|
|
|
if (!context.flags.z()) goto normal;
|
|
|
|
context.cl = context.al;
|
|
|
|
context._and(context.cl, 0x3f);
|
|
|
|
context.ch = 0;
|
|
|
|
context.push(context.cx);
|
|
|
|
readabyte(context);
|
|
|
|
context.cx = context.pop();
|
|
|
|
context._add(context.bx, context.cx);
|
2011-06-11 09:29:02 +00:00
|
|
|
while (context.cx--) context._stosb();
|
2011-06-09 19:35:13 +00:00
|
|
|
context._cmp(context.bx, 4 * 80);
|
|
|
|
if (!context.flags.z()) goto sameline;
|
|
|
|
goto endline;
|
|
|
|
normal:
|
|
|
|
context._stosb();
|
|
|
|
context._add(context.bx, 1);
|
|
|
|
context._cmp(context.bx, 4 * 80);
|
|
|
|
if (!context.flags.z()) goto sameline;
|
|
|
|
|
|
|
|
endline:
|
|
|
|
context.di = context.pop();
|
2011-06-11 12:02:01 +00:00
|
|
|
context.cx = context.pop();
|
2011-06-09 19:35:13 +00:00
|
|
|
|
2011-06-11 12:15:06 +00:00
|
|
|
assert((uint16)context.cx <= 480);
|
2011-06-11 12:02:01 +00:00
|
|
|
uint8 *dst = (uint8 *)s->getBasePtr(0, 480 - (uint16)context.cx);
|
2011-06-11 09:29:02 +00:00
|
|
|
memset(dst, 0, 640);
|
|
|
|
|
|
|
|
for (int i = 0; i < 320; i++) {
|
|
|
|
int plane = i / 80;
|
|
|
|
int pos = i % 80;
|
|
|
|
|
|
|
|
for (int j = 0; j < 8; j++) {
|
|
|
|
byte bit = (src[i] >> (7 - j)) & 1;
|
|
|
|
dst[8 * pos + j] |= (bit << plane);
|
|
|
|
}
|
|
|
|
}
|
2011-06-09 19:35:13 +00:00
|
|
|
|
|
|
|
if (--context.cx) goto convertpcx;
|
|
|
|
|
|
|
|
closefile(context);
|
2011-06-11 09:29:02 +00:00
|
|
|
|
|
|
|
g_system->unlockScreen();
|
2011-06-11 12:02:01 +00:00
|
|
|
|
|
|
|
// TODO: This is probably not the right place to do this
|
2011-06-11 09:29:02 +00:00
|
|
|
g_system->updateScreen();
|
2011-06-05 11:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} /*namespace dreamgen */
|