Initial commit
This commit is contained in:
1
engines/chamber/POTFILES
Normal file
1
engines/chamber/POTFILES
Normal file
@@ -0,0 +1 @@
|
||||
engines/chamber/metaengine.cpp
|
||||
329
engines/chamber/anim.cpp
Normal file
329
engines/chamber/anim.cpp
Normal file
@@ -0,0 +1,329 @@
|
||||
/* 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/system.h"
|
||||
|
||||
#include "chamber/chamber.h"
|
||||
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/resdata.h"
|
||||
#include "chamber/cga.h"
|
||||
#include "chamber/room.h"
|
||||
#include "chamber/sound.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
|
||||
byte *anima_end_ofs;
|
||||
|
||||
byte last_anim_y = 0;
|
||||
byte last_anim_x = 0;
|
||||
byte anim_shift_y = 0;
|
||||
byte anim_shift_x = 0;
|
||||
byte last_anim_height;
|
||||
byte last_anim_width;
|
||||
byte anim_cycle;
|
||||
byte anim_flags;
|
||||
byte anim_use_dot_effect;
|
||||
uint16 anim_draw_delay;
|
||||
byte dot_effect_step;
|
||||
uint16 dot_effect_delay;
|
||||
|
||||
extern uint16 cpu_speed_delay;
|
||||
|
||||
extern void loadLutinSprite(uint16 lutidx);
|
||||
|
||||
void getScratchBuffer(byte mode) {
|
||||
byte *buffer = scratch_mem2;
|
||||
uint16 offs = 0;
|
||||
if (mode & 0x80)
|
||||
offs += 3200;
|
||||
if (mode & 0x40)
|
||||
offs += 1600;
|
||||
lutin_mem = buffer + offs;
|
||||
}
|
||||
|
||||
void animLoadSprite(byte **panim) {
|
||||
byte mode;
|
||||
byte index;
|
||||
mode = *((*panim)++);
|
||||
index = *((*panim)++);
|
||||
getScratchBuffer(mode);
|
||||
loadLutinSprite(index);
|
||||
}
|
||||
|
||||
void clipSprite(byte *x, byte *y, byte *sprw, byte *sprh, byte **sprite, int8 dx, int8 dy) {
|
||||
if (anim_flags == 7)
|
||||
return;
|
||||
if (anim_flags & 4) {
|
||||
if (anim_cycle == 0)
|
||||
return;
|
||||
if (anim_flags & 2) {
|
||||
*sprh = anim_cycle;
|
||||
if (anim_cycle >= dy)
|
||||
anim_cycle -= dy;
|
||||
else
|
||||
anim_cycle = 0;
|
||||
} else if (anim_flags & 1) {
|
||||
*sprw = anim_cycle;
|
||||
anim_cycle--;
|
||||
} else {
|
||||
*x -= dx;
|
||||
*sprite += (*sprw - anim_cycle) * 2;
|
||||
*sprw = anim_cycle;
|
||||
anim_cycle--;
|
||||
}
|
||||
} else if (anim_flags & 2) {
|
||||
if (*sprw == anim_cycle) {
|
||||
anim_cycle = 0;
|
||||
} else if (anim_flags & 1) {
|
||||
*sprw = anim_cycle;
|
||||
anim_cycle++;
|
||||
} else {
|
||||
*x -= dx;
|
||||
*sprite += (*sprw - anim_cycle) * 2;
|
||||
*sprw = anim_cycle;
|
||||
anim_cycle++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void copyScreenBlockWithDotEffect(byte *source, byte x, byte y, byte width, byte height, byte *target) {
|
||||
uint16 offs;
|
||||
uint16 xx = x * 4;
|
||||
uint16 ww = width * 4;
|
||||
uint16 cur_image_end = ww * height;
|
||||
|
||||
for (offs = 0; offs != cur_image_end;) {
|
||||
byte mask = 0xC0 >> (((xx + offs % ww) % 4) * 2);
|
||||
uint16 ofs = cga_CalcXY(xx + offs % ww, y + offs / ww);
|
||||
|
||||
target[ofs] = (target[ofs] & ~mask) | (source[ofs] & mask);
|
||||
|
||||
if (dot_effect_delay / 4 != 0) {
|
||||
uint16 i;
|
||||
for (i = 0; i < dot_effect_delay / 4; i++) ; /*TODO: weak delay*/
|
||||
}
|
||||
|
||||
offs += dot_effect_step;
|
||||
if (offs > cur_image_end)
|
||||
offs -= cur_image_end;
|
||||
}
|
||||
}
|
||||
|
||||
void animDrawSprite(byte x, byte y, byte sprw, byte sprh, byte *pixels, uint16 pitch) {
|
||||
uint16 delay;
|
||||
byte ex, ey, updx, updy, updw, updh;
|
||||
uint16 ofs = CalcXY_p(x, y);
|
||||
cga_BackupImage(backbuffer, ofs, sprw, sprh, sprit_load_buffer);
|
||||
cga_BlitSprite(pixels, pitch, sprw, sprh, backbuffer, ofs);
|
||||
ex = x + sprw;
|
||||
ey = y + sprh;
|
||||
if (last_anim_height != 0) {
|
||||
if (last_anim_x + last_anim_width > ex)
|
||||
ex = last_anim_x + last_anim_width;
|
||||
|
||||
if (last_anim_y + last_anim_height > ey)
|
||||
ey = last_anim_y + last_anim_height;
|
||||
|
||||
updx = (x > last_anim_x) ? last_anim_x : x;
|
||||
updy = (y > last_anim_y) ? last_anim_y : y;
|
||||
} else {
|
||||
updx = x;
|
||||
updy = y;
|
||||
}
|
||||
updw = ex - updx;
|
||||
updh = ey - updy;
|
||||
ofs = CalcXY_p(updx, updy);
|
||||
/*TODO looks like here was some code before*/
|
||||
for (delay = 0; delay < anim_draw_delay; delay++) {
|
||||
g_system->delayMillis(1000 / 16 / 25);
|
||||
}
|
||||
waitVBlank();
|
||||
|
||||
if (anim_use_dot_effect)
|
||||
copyScreenBlockWithDotEffect(backbuffer, updx, updy, updw, updh, frontbuffer);
|
||||
else {
|
||||
cga_CopyScreenBlock(backbuffer, updw, updh, frontbuffer, ofs);
|
||||
}
|
||||
cga_RestoreImage(sprit_load_buffer, backbuffer);
|
||||
|
||||
last_anim_x = x;
|
||||
last_anim_y = y;
|
||||
last_anim_width = sprw;
|
||||
last_anim_height = sprh;
|
||||
|
||||
anim_shift_x = anim_shift_y = 0;
|
||||
}
|
||||
|
||||
void animUndrawSprite(void) {
|
||||
cga_CopyScreenBlock(backbuffer, last_anim_width, last_anim_height, CGA_SCREENBUFFER, CalcXY_p(last_anim_x, last_anim_y));
|
||||
last_anim_height = 0;
|
||||
}
|
||||
|
||||
void playAnimCore(byte **panim) {
|
||||
byte mode;
|
||||
uint16 count, count2;
|
||||
byte *pframe;
|
||||
mode = *((*panim)++);
|
||||
anim_flags = mode & 7;
|
||||
count = mode >> 3;
|
||||
|
||||
while (count--) {
|
||||
pframe = *panim;
|
||||
mode = *pframe++;
|
||||
anim_draw_delay = ((mode & ~7) >> 3) << 1;
|
||||
dot_effect_step = (mode & ~7) >> 3;
|
||||
dot_effect_delay = 500;
|
||||
count2 = mode & 7;
|
||||
while (count2--) {
|
||||
byte *sprite;
|
||||
byte sprw, sprh;
|
||||
byte x, y;
|
||||
int8 dx, dy;
|
||||
uint16 pitch;
|
||||
mode = *pframe++;
|
||||
getScratchBuffer(mode);
|
||||
dy = mode & 7;
|
||||
dx = (mode >> 3) & 7;
|
||||
|
||||
dx = (dx & 1) ? -(dx & ~1) : dx;
|
||||
dx /= 2;
|
||||
dy = (dy & 1) ? -(dy & ~1) : dy;
|
||||
|
||||
x = last_anim_x + dx + anim_shift_x;
|
||||
y = last_anim_y + dy + anim_shift_y;
|
||||
|
||||
sprite = lutin_mem;
|
||||
sprw = *sprite++;
|
||||
sprh = *sprite++;
|
||||
|
||||
pitch = sprw * 2;
|
||||
clipSprite(&x, &y, &sprw, &sprh, &sprite, dx, dy);
|
||||
animDrawSprite(x, y, sprw, sprh, sprite, pitch);
|
||||
|
||||
if (anim_flags & 4) {
|
||||
if (anim_cycle == 0) {
|
||||
animUndrawSprite();
|
||||
goto end;
|
||||
}
|
||||
} else if (anim_flags & 2) {
|
||||
if (anim_cycle == 0) {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
;
|
||||
mode = *((*panim)++);
|
||||
*panim += mode & 7;
|
||||
}
|
||||
|
||||
void anim1(byte **panim) {
|
||||
anim_cycle = 0xFF;
|
||||
anim_use_dot_effect = 0;
|
||||
playAnimCore(panim);
|
||||
}
|
||||
|
||||
void anim2(byte **panim) {
|
||||
anim_cycle = 1;
|
||||
anim_use_dot_effect = 0;
|
||||
playAnimCore(panim);
|
||||
}
|
||||
|
||||
void anim3(byte **panim) {
|
||||
anim_cycle = 1;
|
||||
anim_use_dot_effect = 0;
|
||||
playAnimCore(panim);
|
||||
}
|
||||
|
||||
void anim4(byte **panim) {
|
||||
anim_cycle = last_anim_width - 1;
|
||||
anim_use_dot_effect = 0;
|
||||
playAnimCore(panim);
|
||||
}
|
||||
|
||||
void anim5(byte **panim) {
|
||||
anim_cycle = last_anim_width - 1;
|
||||
anim_use_dot_effect = 0;
|
||||
playAnimCore(panim);
|
||||
}
|
||||
|
||||
void anim6(byte **panim) {
|
||||
anim_cycle = last_anim_height;
|
||||
anim_use_dot_effect = 0;
|
||||
playAnimCore(panim);
|
||||
}
|
||||
|
||||
void anim7(byte **panim) {
|
||||
anim_cycle = 0xFF;
|
||||
anim_use_dot_effect = 1;
|
||||
playAnimCore(panim);
|
||||
}
|
||||
|
||||
typedef void (*animhandler_t)(byte **panim);
|
||||
|
||||
animhandler_t anim_handlers[] = {
|
||||
animLoadSprite,
|
||||
anim1,
|
||||
anim2,
|
||||
anim3,
|
||||
anim4,
|
||||
anim5,
|
||||
anim6,
|
||||
anim7
|
||||
};
|
||||
|
||||
void playAnim(byte index, byte x, byte y) {
|
||||
byte sound;
|
||||
byte *panim;
|
||||
|
||||
last_anim_width = 0;
|
||||
last_anim_height = 0;
|
||||
last_anim_x = x;
|
||||
last_anim_y = y;
|
||||
|
||||
panim = seekToEntry(anima_data, index - 1, &anima_end_ofs);
|
||||
while (panim != anima_end_ofs) {
|
||||
byte mode = *panim;
|
||||
switch (mode) {
|
||||
case 0xFE: /*set shift*/
|
||||
panim++;
|
||||
anim_shift_x = *panim++;
|
||||
anim_shift_y = *panim++;
|
||||
break;
|
||||
case 0xFD: /*play sfx*/
|
||||
panim++;
|
||||
sound = *panim++;
|
||||
panim++; /*unused*/
|
||||
playSound(sound);
|
||||
break;
|
||||
case 0xFC: /*nothing*/
|
||||
panim++;
|
||||
break;
|
||||
default:
|
||||
anim_handlers[mode & 7](&panim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
35
engines/chamber/anim.h
Normal file
35
engines/chamber/anim.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/* 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 CHAMBER_ANIM_H
|
||||
#define CHAMBER_ANIM_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
void playAnim(byte index, byte x, byte y);
|
||||
void copyScreenBlockWithDotEffect(byte *source, byte x, byte y, byte width, byte height, byte *target);
|
||||
|
||||
extern byte dot_effect_step;
|
||||
extern uint16 dot_effect_delay;
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
30
engines/chamber/bkbuff.cpp
Normal file
30
engines/chamber/bkbuff.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
|
||||
byte backbuffer[0xB800]; ///< CGA: 0x4000, HGS: 0xB800
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
1640
engines/chamber/cga.cpp
Normal file
1640
engines/chamber/cga.cpp
Normal file
File diff suppressed because it is too large
Load Diff
166
engines/chamber/cga.h
Normal file
166
engines/chamber/cga.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/* 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 CHAMBER_cga_H
|
||||
#define CHAMBER_cga_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
// HGA Constants
|
||||
#define HGA_WIDTH 720
|
||||
#define HGA_HEIGHT 348
|
||||
#define HGA_BASE_SEG 0xB000
|
||||
#define HGA_PAGE2_SEG 0xB800
|
||||
#define HGA_NEXT_LINES_OFS 0x2000
|
||||
#define HGA_BITS_PER_PIXEL 1
|
||||
#define HGA_PIXELS_PER_BYTE (8 / HGA_BITS_PER_PIXEL)
|
||||
#define HGA_BYTES_PER_LINE (HGA_WIDTH / HGA_PIXELS_PER_BYTE)
|
||||
#define HGA_CALCXY_RAW(x, y) ( ((y) % 4) * HGA_NEXT_LINES_OFS + ((y) / 4) * HGA_BYTES_PER_LINE + (x) / HGA_PIXELS_PER_BYTE )
|
||||
#define HGA_CENTERED_BASE_OFS HGA_CALCXY_RAW(-76, 8)
|
||||
#ifdef __386__
|
||||
#define HGA_SCREENBUFFER ((byte*)(HGA_BASE_SEG * 16))
|
||||
#define HGA_BACKBUFFER ((byte*)(HGA_PAGE2_SEG * 16))
|
||||
#else
|
||||
#if 0
|
||||
#define HGA_SCREENBUFFER ((byte*)MK_FP(HGA_BASE_SEG, 0))
|
||||
#define HGA_BACKBUFFER ((byte*)MK_FP(HGA_PAGE2_SEG, 0))
|
||||
|
||||
|
||||
#define HGA_FONT_HEIGHT 6
|
||||
#define frontbuffer HGA_SCREENBUFFER
|
||||
#define backbuffer HGA_BACKBUFFER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// CGA Constants
|
||||
#define CGA_WIDTH 320
|
||||
#define CGA_HEIGHT 200
|
||||
#define CGA_BASE_SEG 0xB800
|
||||
#define CGA_ODD_LINES_OFS 0x2000
|
||||
#define CGA_BITS_PER_PIXEL 2
|
||||
#define CGA_PIXELS_PER_BYTE (8 / CGA_BITS_PER_PIXEL)
|
||||
#define CGA_BYTES_PER_LINE (CGA_WIDTH / CGA_PIXELS_PER_BYTE)
|
||||
|
||||
extern byte CGA_SCREENBUFFER[0xB800];
|
||||
|
||||
#define CGA_FONT_HEIGHT 6
|
||||
|
||||
#define CGA_NEXT_LINE(offs) ((CGA_ODD_LINES_OFS ^ (offs)) + (((offs) & CGA_ODD_LINES_OFS) ? 0 : CGA_BYTES_PER_LINE))
|
||||
#define CGA_PREV_LINE(offs) ((CGA_ODD_LINES_OFS ^ (offs)) - (((offs) & CGA_ODD_LINES_OFS) ? CGA_BYTES_PER_LINE : 0))
|
||||
|
||||
#define frontbuffer CGA_SCREENBUFFER
|
||||
extern byte backbuffer[0xB800]; ///< CGA: 0x4000, HGS: 0xB800
|
||||
|
||||
extern byte sprit_load_buffer[1290];
|
||||
|
||||
extern byte cga_pixel_flip[256];
|
||||
|
||||
extern byte char_draw_coords_x;
|
||||
extern byte char_draw_coords_y;
|
||||
extern byte *char_xlat_table;
|
||||
extern byte string_ended;
|
||||
extern byte char_draw_max_width;
|
||||
extern byte char_draw_max_height;
|
||||
|
||||
void switchToGraphicsMode(void);
|
||||
void switchToTextMode(void);
|
||||
|
||||
void waitVBlank(void);
|
||||
void cga_blitToScreen(int16 dx, int16 dy, int16 w, int16 h);
|
||||
void cga_blitToScreen(int16 ofs, int16 w, int16 h);
|
||||
|
||||
void cga_ColorSelect(byte csel);
|
||||
void cga_BackBufferToRealFull(void);
|
||||
void cga_RealBufferToBackFull(void);
|
||||
void cga_SwapRealBackBuffer(void);
|
||||
|
||||
void cga_SwapScreenRect(byte *pixels, uint16 w, uint16 h, byte *screen, uint16 ofs);
|
||||
|
||||
uint16 CalcXY(uint16 x, uint16 y);
|
||||
uint16 CalcXY_p(uint16 x, uint16 y);
|
||||
|
||||
uint16 HGA_CalcXY(uint16 x, uint16 y);
|
||||
uint16 HGA_CalcXY_p(uint16 x, uint16 y);
|
||||
uint16 cga_CalcXY(uint16 x, uint16 y);
|
||||
uint16 cga_CalcXY_p(uint16 x, uint16 y);
|
||||
|
||||
void cga_CopyScreenBlock(byte *source, uint16 w, uint16 h, byte *target, uint16 ofs);
|
||||
|
||||
byte *cga_BackupImage(byte *source, uint16 ofs, uint16 w, uint16 h, byte *buffer);
|
||||
byte *cga_BackupImageReal(uint16 ofs, uint16 w, uint16 h);
|
||||
|
||||
void cga_RestoreImage(byte *buffer, byte *target);
|
||||
void cga_RefreshImageData(byte *buffer);
|
||||
void cga_RestoreBackupImage(byte *target);
|
||||
|
||||
void cga_Blit(byte *pixels, uint16 pw, uint16 w, uint16 h, byte *screen, uint16 ofs);
|
||||
void cga_BlitAndWait(byte *pixels, uint16 pw, uint16 w, uint16 h, byte *screen, uint16 ofs);
|
||||
void cga_FillAndWait(byte pixel, uint16 w, uint16 h, byte *screen, uint16 ofs);
|
||||
|
||||
void cga_DrawVLine(uint16 x, uint16 y, uint16 l, byte color, byte *target);
|
||||
void cga_DrawHLine(uint16 x, uint16 y, uint16 l, byte color, byte *target);
|
||||
uint16 cga_DrawHLineWithEnds(uint16 bmask, uint16 bpix, byte color, uint16 l, byte *target, uint16 ofs);
|
||||
|
||||
void cga_PrintChar(byte c, byte *target);
|
||||
|
||||
void cga_BlitScratchBackSprite(uint16 sprofs, uint16 w, uint16 h, byte *screen, uint16 ofs);
|
||||
void cga_BlitFromBackBuffer(byte w, byte h, byte *screen, uint16 ofs);
|
||||
|
||||
void cga_BlitSprite(byte *pixels, int16 pw, uint16 w, uint16 h, byte *screen, uint16 ofs);
|
||||
void cga_BlitSpriteFlip(byte *pixels, int16 pw, uint16 w, uint16 h, byte *screen, uint16 ofs);
|
||||
|
||||
void cga_BlitSpriteBak(byte *pixels, int16 pw, uint16 w, uint16 h, byte *screen, uint16 ofs, byte *backup, byte mask);
|
||||
|
||||
void drawSprite(byte *sprite, byte *screen, uint16 ofs);
|
||||
void drawSpriteFlip(byte *sprite, byte *screen, uint16 ofs);
|
||||
|
||||
void drawSpriteN(byte index, uint16 x, uint16 y, byte *target);
|
||||
void drawSpriteNFlip(byte index, uint16 x, uint16 y, byte *target);
|
||||
|
||||
void backupAndShowSprite(byte index, byte x, byte y);
|
||||
|
||||
byte *loadSprite(byte index, byte *bank, byte *buffer, byte header_only);
|
||||
|
||||
byte *loadSprit(byte index);
|
||||
byte *loadPersSprit(byte index);
|
||||
|
||||
void cga_AnimLiftToUp(byte *pixels, uint16 pw, uint16 w, uint16 h, byte *screen, uint16 x, uint16 y);
|
||||
void cga_AnimLiftToDown(byte *pixels, uint16 pw, uint16 w, uint16 h, byte *screen, uint16 ofs);
|
||||
void cga_AnimLiftToLeft(uint16 n, byte *pixels, uint16 pw, uint16 w, uint16 h, byte *screen, uint16 ofs);
|
||||
void cga_AnimLiftToRight(uint16 n, byte *pixels, uint16 pw, uint16 w, uint16 h, byte *screen, uint16 ofs);
|
||||
|
||||
void cga_HideScreenBlockLiftToUp(uint16 n, byte *screen, byte *source, uint16 w, uint16 h, byte *target, uint16 ofs);
|
||||
void cga_HideScreenBlockLiftToDown(uint16 n, byte *screen, byte *source, uint16 w, uint16 h, byte *target, uint16 ofs);
|
||||
void cga_HideScreenBlockLiftToLeft(uint16 n, byte *screen, byte *source, uint16 w, uint16 h, byte *target, uint16 ofs);
|
||||
void cga_HideScreenBlockLiftToRight(uint16 n, byte *screen, byte *source, uint16 w, uint16 h, byte *target, uint16 ofs);
|
||||
|
||||
void cga_HideShatterFall(byte *screen, byte *source, uint16 w, uint16 h, byte *target, uint16 ofs);
|
||||
|
||||
void cga_TraceLine(uint16 sx, uint16 ex, uint16 sy, uint16 ey, byte *source, byte *target);
|
||||
|
||||
void cga_ZoomImage(byte *pixels, byte w, byte h, byte nw, byte nh, byte *target, uint16 ofs);
|
||||
void cga_AnimZoomIn(byte *pixels, byte w, byte h, byte *target, uint16 ofs);
|
||||
|
||||
void cga_ZoomInplaceXY(byte *pixels, byte w, byte h, byte nw, byte nh, uint16 x, uint16 y, byte *target);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
93
engines/chamber/chamber.cpp
Normal file
93
engines/chamber/chamber.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/* 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 "common/config-manager.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/error.h"
|
||||
#include "common/events.h"
|
||||
#include "common/file.h"
|
||||
#include "common/fs.h"
|
||||
#include "common/system.h"
|
||||
|
||||
#include "engines/util.h"
|
||||
|
||||
#include "chamber/chamber.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
ChamberEngine *g_vm;
|
||||
|
||||
ChamberEngine::ChamberEngine(OSystem *syst, const ADGameDescription *desc)
|
||||
: Engine(syst) {
|
||||
g_vm = this;
|
||||
_gameDescription = desc;
|
||||
|
||||
const Common::FSNode gameDataDir(ConfMan.getPath("path"));
|
||||
|
||||
// Don't forget to register your random source
|
||||
_rnd = new Common::RandomSource("chamber");
|
||||
|
||||
_shouldQuit = false;
|
||||
_shouldRestart = false;
|
||||
_prioritycommand_1 = false;
|
||||
_prioritycommand_2 = false;
|
||||
_pxiData = NULL;
|
||||
_videoMode = Common::kRenderCGA;
|
||||
_screenH = _screenW = _screenBits = _screenBPL = _screenPPB = 0;
|
||||
_line_offset = _line_offset2 = _fontHeight = _fontWidth = 0;
|
||||
}
|
||||
|
||||
ChamberEngine::~ChamberEngine() {
|
||||
// Dispose your resources here
|
||||
delete _rnd;
|
||||
delete[] _pxiData;
|
||||
|
||||
deinitSound();
|
||||
}
|
||||
|
||||
bool ChamberEngine::hasFeature(EngineFeature f) const {
|
||||
return
|
||||
(f == kSupportsReturnToLauncher) ||
|
||||
(f == kSupportsLoadingDuringRuntime) ||
|
||||
(f == kSupportsSavingDuringRuntime);
|
||||
}
|
||||
|
||||
Common::Error ChamberEngine::loadGameStream(Common::SeekableReadStream *stream) {
|
||||
Common::Serializer s(stream, nullptr);
|
||||
syncGameStream(s);
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
Common::Error ChamberEngine::saveGameStream(Common::WriteStream *stream, bool isAutosave) {
|
||||
Common::Serializer s(nullptr, stream);
|
||||
syncGameStream(s);
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
void ChamberEngine::syncGameStream(Common::Serializer &s) {
|
||||
// Use methods of Serializer to save/load fields
|
||||
int16 dummy = 0;
|
||||
s.syncAsUint16LE(dummy);
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
108
engines/chamber/chamber.h
Normal file
108
engines/chamber/chamber.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/* 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 CHAMBER_H
|
||||
#define CHAMBER_H
|
||||
#define RUNCOMMAND_RESTART 1337
|
||||
|
||||
#include "common/random.h"
|
||||
#include "common/serializer.h"
|
||||
#include "common/rendermode.h"
|
||||
#include "engines/engine.h"
|
||||
#include "gui/debugger.h"
|
||||
|
||||
namespace Audio {
|
||||
class SoundHandle;
|
||||
class PCSpeaker;
|
||||
}
|
||||
|
||||
struct ADGameDescription;
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
enum CHAMBERActions {
|
||||
kActionNone,
|
||||
kActionInteract,
|
||||
kActionQuit,
|
||||
kActionYes,
|
||||
kActionNo,
|
||||
};
|
||||
|
||||
class ChamberEngine : public Engine {
|
||||
private:
|
||||
// We need random numbers
|
||||
Common::RandomSource *_rnd;
|
||||
|
||||
public:
|
||||
ChamberEngine(OSystem *syst, const ADGameDescription *desc);
|
||||
~ChamberEngine();
|
||||
|
||||
Common::Language getLanguage() const;
|
||||
|
||||
Common::Error run() override;
|
||||
Common::Error init();
|
||||
Common::Error execute();
|
||||
bool hasFeature(EngineFeature f) const override;
|
||||
bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override { return true; }
|
||||
bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override { return true; }
|
||||
Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
|
||||
Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
|
||||
void syncGameStream(Common::Serializer &s);
|
||||
|
||||
byte readKeyboardChar();
|
||||
|
||||
void initSound();
|
||||
void deinitSound();
|
||||
|
||||
public:
|
||||
bool _shouldQuit;
|
||||
bool _shouldRestart;
|
||||
bool _prioritycommand_1;
|
||||
bool _prioritycommand_2;
|
||||
|
||||
Common::RenderMode _videoMode;
|
||||
|
||||
byte *_pxiData;
|
||||
|
||||
uint16 _screenW; ///< Screen Width
|
||||
uint16 _screenH; ///< Screen Height
|
||||
uint8 _screenBits; ///< Bits per pixel
|
||||
uint16 _line_offset; ///< Memory offset of blanks
|
||||
uint16 _line_offset2; ///< Memory offset of blanks
|
||||
uint8 _screenPPB; ///< Pixels per byte
|
||||
uint16 _screenBPL; ///< Bytes per line
|
||||
uint8 _fontHeight; ///< Font height
|
||||
uint8 _fontWidth; ///< Font height
|
||||
|
||||
|
||||
Audio::PCSpeaker *_speaker;
|
||||
|
||||
private:
|
||||
const ADGameDescription *_gameDescription;
|
||||
};
|
||||
|
||||
void init(void);
|
||||
|
||||
extern ChamberEngine *g_vm;
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
97
engines/chamber/common.h
Normal file
97
engines/chamber/common.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/* 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 CHAMBER_COMMON_H
|
||||
#define CHAMBER_COMMON_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
#define BE(x) ((((x) >> 8) | ((x) << 8)) & 0xffff)
|
||||
#define LE16(x) (x)
|
||||
|
||||
#define TODO(s) \
|
||||
{ \
|
||||
warning("%s", s); \
|
||||
promptWait(); \
|
||||
for(;;) ; \
|
||||
}
|
||||
|
||||
#include "common/pack-start.h"
|
||||
typedef struct rect_t {
|
||||
byte sx;
|
||||
byte ex;
|
||||
byte sy;
|
||||
byte ey;
|
||||
} rect_t;
|
||||
#include "common/pack-end.h"
|
||||
|
||||
#if 0
|
||||
#define DEBUG_ENDING
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define DEBUG
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*0 - play intro*/
|
||||
/*0xFF - skip intro, quest item and teleport*/
|
||||
/*other - skip intro, play quest item seq, teleport to room*/
|
||||
#define DEBUG_SKIP_INTRO 0xFF
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#define DEBUG_ZONE
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*Rope -> De Profundis*/
|
||||
#define DEBUG_QUEST 0x00
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*Knife -> The Wall*/
|
||||
#define DEBUG_QUEST 0x40
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*Goblet -> The Twins*/
|
||||
#define DEBUG_QUEST 0x80
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*Fly -> Scorpion's*/
|
||||
#define DEBUG_QUEST 0xC0
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*win in fights*/
|
||||
#define CHEAT
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*never lose to the Skull Trader*/
|
||||
#define CHEAT_TRADER
|
||||
#endif
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
3
engines/chamber/configure.engine
Normal file
3
engines/chamber/configure.engine
Normal file
@@ -0,0 +1,3 @@
|
||||
# This file is included from the main "configure" script
|
||||
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] [components]
|
||||
add_engine chamber "Chamber" no
|
||||
4
engines/chamber/credits.pl
Normal file
4
engines/chamber/credits.pl
Normal file
@@ -0,0 +1,4 @@
|
||||
begin_section("Chamber");
|
||||
add_person("Retro-Junk;", "bambarbee", "");
|
||||
add_person("Eugene Sandulenko", "sev", "");
|
||||
end_section();
|
||||
125
engines/chamber/cursor.cpp
Normal file
125
engines/chamber/cursor.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/* 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/system.h"
|
||||
|
||||
#include "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/cursor.h"
|
||||
#include "chamber/resdata.h"
|
||||
#include "chamber/cga.h"
|
||||
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
|
||||
byte cursor_color = 0;
|
||||
|
||||
byte *cursor_shape = NULL;
|
||||
byte cursor_anim_ticks;
|
||||
byte cursor_anim_phase;
|
||||
|
||||
/*cursors hotspot offsets*/
|
||||
uint16 cursor_shifts[CURSOR_MAX][2] = {
|
||||
{ 0, 0 },
|
||||
{ 7, 7 },
|
||||
{ 7, 7 },
|
||||
{ 0, 0 },
|
||||
{ 7, 7 },
|
||||
{ 0, 15 },
|
||||
{ 7, 7 },
|
||||
{ 7, 7 },
|
||||
{ 7, 7 }
|
||||
};
|
||||
|
||||
uint16 cursor_x_shift;
|
||||
byte cursor_y_shift;
|
||||
|
||||
uint16 cursor_x;
|
||||
byte cursor_y;
|
||||
byte cursor_backup[CURSOR_WIDTH_SPR * CURSOR_HEIGHT / CGA_BITS_PER_PIXEL];
|
||||
uint16 last_cursor_draw_ofs = 0;
|
||||
uint16 cursor_draw_ofs;
|
||||
byte cursorImage[CURSOR_WIDTH * CURSOR_HEIGHT];
|
||||
|
||||
/*
|
||||
Select cursor shape and its hotspot
|
||||
*/
|
||||
void selectCursor(uint16 num) {
|
||||
cursor_x_shift = cursor_shifts[num][0];
|
||||
cursor_y_shift = cursor_shifts[num][1];
|
||||
cursor_shape = souri_data + num * CURSOR_WIDTH * CURSOR_HEIGHT * 2 / g_vm->_screenPPB;
|
||||
|
||||
byte *src = cursor_shape;
|
||||
byte *dst = cursorImage;
|
||||
for (int16 y = 0; y < CURSOR_HEIGHT; y++) {
|
||||
for (int16 x = 0; x < CURSOR_HEIGHT / 4; x++) {
|
||||
byte colors = *src;
|
||||
byte masks = *(src++ + CURSOR_HEIGHT * CURSOR_WIDTH / 4);
|
||||
|
||||
for (int16 c = 0; c < 4; c++) {
|
||||
byte color = (colors & 0xC0) >> 6;
|
||||
byte mask = (masks & 0xC0) >> 6;
|
||||
colors <<= 2;
|
||||
masks <<= 2;
|
||||
|
||||
if (!mask)
|
||||
*dst++ = color;
|
||||
else {
|
||||
*dst++ = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_system->setMouseCursor(cursorImage, CURSOR_WIDTH, CURSOR_HEIGHT, cursor_x_shift, cursor_y_shift, 255);
|
||||
g_system->showMouse(true);
|
||||
}
|
||||
|
||||
/*
|
||||
Build cursor sprite for its current pixel-grained position
|
||||
*/
|
||||
void updateCursor(void) {
|
||||
}
|
||||
|
||||
/*
|
||||
Draw cursor sprite and backup background pixels
|
||||
*/
|
||||
void drawCursor(byte *target) {
|
||||
g_system->updateScreen();
|
||||
}
|
||||
|
||||
/*
|
||||
Restore background pixels under cursor
|
||||
*/
|
||||
void undrawCursor(byte *target) {
|
||||
}
|
||||
|
||||
/*
|
||||
Restore pixels under cursor and update cursor sprite
|
||||
*/
|
||||
void updateUndrawCursor(byte *target) {
|
||||
/*TODO: does this call order makes any sense?*/
|
||||
updateCursor();
|
||||
undrawCursor(target);
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
59
engines/chamber/cursor.h
Normal file
59
engines/chamber/cursor.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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 CHAMBER_CURSOR_H
|
||||
#define CHAMBER_CURSOR_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
#define CURSOR_WIDTH 16
|
||||
#define CURSOR_HEIGHT 16
|
||||
#define CURSOR_WIDTH_SPR 20
|
||||
|
||||
enum Cursors {
|
||||
CURSOR_FINGER,
|
||||
CURSOR_TARGET,
|
||||
CURSOR_FLY,
|
||||
CURSOR_SNAKE,
|
||||
CURSOR_GRAB,
|
||||
CURSOR_POUR,
|
||||
CURSOR_BODY,
|
||||
CURSOR_ARROWS,
|
||||
CURSOR_CROSSHAIR,
|
||||
CURSOR_MAX
|
||||
};
|
||||
|
||||
extern uint16 cursor_x;
|
||||
extern byte cursor_y;
|
||||
extern byte cursor_color;
|
||||
extern byte *cursor_shape;
|
||||
extern byte cursor_anim_ticks;
|
||||
extern byte cursor_anim_phase;
|
||||
|
||||
void selectCursor(uint16 num);
|
||||
void updateCursor(void);
|
||||
void drawCursor(byte *target);
|
||||
void undrawCursor(byte *target);
|
||||
void updateUndrawCursor(byte *target);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
119
engines/chamber/decompr.cpp
Normal file
119
engines/chamber/decompr.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
|
||||
static struct {
|
||||
byte codes[256];
|
||||
byte prefix[256];
|
||||
byte suffix[256];
|
||||
byte coddict[256];
|
||||
byte codlink[256];
|
||||
byte stackpos;
|
||||
} DecompCtx;
|
||||
|
||||
byte decode_string(byte code, byte prev_n, byte *stack) {
|
||||
byte n;
|
||||
while ((n = DecompCtx.coddict[code]) != 0) {
|
||||
while (n >= prev_n) {
|
||||
n = DecompCtx.codlink[n];
|
||||
if (n == 0)
|
||||
return code;
|
||||
}
|
||||
/*if(DecompCtx.stackpos == 255) exit("stack exploded");*/
|
||||
stack[DecompCtx.stackpos++] = prev_n = n;
|
||||
code = DecompCtx.prefix[n];
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
uint32 decompress(byte *data, byte *result) {
|
||||
byte dict_size, more;
|
||||
uint16 compsize;
|
||||
uint16 i;
|
||||
byte code, n, suffix;
|
||||
byte stack[256];
|
||||
uint32 decompsize = 0;
|
||||
|
||||
do {
|
||||
dict_size = *data++;
|
||||
more = *data++;
|
||||
compsize = *data++;
|
||||
compsize |= (*data++) << 8;
|
||||
|
||||
if (dict_size == 0) {
|
||||
/* uncompressed block */
|
||||
decompsize += compsize;
|
||||
while (compsize--)
|
||||
*result++ = *data++;
|
||||
} else {
|
||||
/* compressed block */
|
||||
/*
|
||||
memcpy(DecompCtx.codes + 1, data, dict_size); data += dict_size;
|
||||
memcpy(DecompCtx.prefix + 1, data, dict_size); data += dict_size;
|
||||
memcpy(DecompCtx.suffix + 1, data, dict_size); data += dict_size;
|
||||
*/
|
||||
for (n = 1, i = 0; i < dict_size; n++, i++) DecompCtx.codes[n] = *data++;
|
||||
for (n = 1, i = 0; i < dict_size; n++, i++) DecompCtx.prefix[n] = *data++;
|
||||
for (n = 1, i = 0; i < dict_size; n++, i++) DecompCtx.suffix[n] = *data++;
|
||||
|
||||
memset(DecompCtx.coddict, 0, 256);
|
||||
for (n = 1, i = 0; i < dict_size; n++, i++) {
|
||||
code = DecompCtx.codes[n];
|
||||
DecompCtx.codlink[n] = DecompCtx.coddict[code];
|
||||
DecompCtx.coddict[code] = n;
|
||||
}
|
||||
|
||||
while (compsize-- > 0) {
|
||||
code = *data++;
|
||||
|
||||
if (DecompCtx.coddict[code] == 0) {
|
||||
/* literal */
|
||||
*result++ = code;
|
||||
decompsize += 1;
|
||||
} else {
|
||||
/* string */
|
||||
DecompCtx.stackpos = 0;
|
||||
|
||||
n = DecompCtx.coddict[code];
|
||||
|
||||
stack[DecompCtx.stackpos++] = n;
|
||||
|
||||
for (code = DecompCtx.prefix[n];; code = DecompCtx.suffix[n]) {
|
||||
suffix = decode_string(code, n, stack);
|
||||
*result++ = suffix;
|
||||
decompsize += 1;
|
||||
if (DecompCtx.stackpos == 0)
|
||||
break;
|
||||
n = stack[--DecompCtx.stackpos];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (more != 0);
|
||||
|
||||
return decompsize;
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
30
engines/chamber/decompr.h
Normal file
30
engines/chamber/decompr.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* 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 CHAMBER_DECOMPR_H
|
||||
#define CHAMBER_DECOMPR_H
|
||||
|
||||
namespace Chamber {
|
||||
uint32 decompress(byte *data, byte *result);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
75
engines/chamber/detection.cpp
Normal file
75
engines/chamber/detection.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/* 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 "base/plugins.h"
|
||||
#include "engines/advancedDetector.h"
|
||||
|
||||
namespace Chamber {
|
||||
static const PlainGameDescriptor ChamberGames[] = {
|
||||
{"chamber", "Chamber of the Sci-Mutant Priestess"},
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static const ADGameDescription gameDescriptions[] = {
|
||||
{
|
||||
"chamber",
|
||||
"",
|
||||
AD_ENTRY1s("ere.pxi", "5aa5bd2d79eefde70675b0b6734944f2", 134358),
|
||||
Common::UNK_LANG, // EN/FR/DE
|
||||
Common::kPlatformDOS,
|
||||
ADGF_UNSTABLE,
|
||||
GUIO0()
|
||||
},
|
||||
|
||||
{
|
||||
"chamber",
|
||||
"",
|
||||
AD_ENTRY1s("kult1.pxi", "fc0bd31a3c380338f76ff53e421e47b6", 140537),
|
||||
Common::EN_USA,
|
||||
Common::kPlatformDOS,
|
||||
ADGF_UNSTABLE,
|
||||
GUIO0()
|
||||
},
|
||||
|
||||
AD_TABLE_END_MARKER
|
||||
};
|
||||
} // End of namespace Chamber
|
||||
|
||||
class ChamberMetaEngineDetection : public AdvancedMetaEngineDetection<ADGameDescription> {
|
||||
public:
|
||||
ChamberMetaEngineDetection() : AdvancedMetaEngineDetection(Chamber::gameDescriptions, Chamber::ChamberGames) {
|
||||
}
|
||||
|
||||
const char *getName() const override {
|
||||
return "chamber";
|
||||
}
|
||||
|
||||
const char *getEngineName() const override {
|
||||
return "chamber";
|
||||
}
|
||||
|
||||
const char *getOriginalCopyright() const override {
|
||||
return "Chamber (C) 1989 ERE Informatique";
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_PLUGIN_STATIC(CHAMBER_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, ChamberMetaEngineDetection);
|
||||
252
engines/chamber/dialog.cpp
Normal file
252
engines/chamber/dialog.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
/* 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/system.h"
|
||||
|
||||
#include "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/dialog.h"
|
||||
#include "chamber/print.h"
|
||||
#include "chamber/cga.h"
|
||||
#include "chamber/script.h"
|
||||
#include "chamber/cursor.h"
|
||||
#include "chamber/input.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
uint16 cur_str_index;
|
||||
uint16 cur_dlg_index;
|
||||
|
||||
dirty_rect_t dirty_rects[MAX_DIRTY_RECT];
|
||||
dirty_rect_t *last_dirty_rect = dirty_rects;
|
||||
|
||||
void addDirtyRect(byte kind, byte x, byte y, byte w, byte h, uint16 offs) {
|
||||
int16 i;
|
||||
dirty_rect_t *r = dirty_rects;
|
||||
for (i = 0; i < MAX_DIRTY_RECT; i++, r++) /*TODO: may go oob*/
|
||||
if (r->kind == DirtyRectFree)
|
||||
break;
|
||||
r->kind = kind;
|
||||
r->offs = offs;
|
||||
r->width = w;
|
||||
r->height = h;
|
||||
r->y = y;
|
||||
r->x = x;
|
||||
script_byte_vars.dirty_rect_kind = dirty_rects[0].kind;
|
||||
last_dirty_rect = r;
|
||||
}
|
||||
|
||||
void getDirtyRect(int16 index, byte *kind, byte *x, byte *y, byte *w, byte *h, uint16 *offs, byte newkind) {
|
||||
*kind = dirty_rects[index].kind;
|
||||
*offs = dirty_rects[index].offs;
|
||||
*w = dirty_rects[index].width;
|
||||
*h = dirty_rects[index].height;
|
||||
*y = dirty_rects[index].y;
|
||||
*x = dirty_rects[index].x;
|
||||
|
||||
dirty_rects[index].kind = newkind;
|
||||
script_byte_vars.dirty_rect_kind = dirty_rects[0].kind;
|
||||
}
|
||||
|
||||
void getDirtyRectAndFree(int16 index, byte *kind, byte *x, byte *y, byte *w, byte *h, uint16 *offs) {
|
||||
getDirtyRect(index - 1, kind, x, y, w, h, offs, DirtyRectFree);
|
||||
}
|
||||
|
||||
void getDirtyRectAndSetSprite(int16 index, byte *kind, byte *x, byte *y, byte *w, byte *h, uint16 *offs) {
|
||||
getDirtyRect(index - 1, kind, x, y, w, h, offs, DirtyRectSprite);
|
||||
}
|
||||
|
||||
int16 findDirtyRectAndFree(byte kind, byte *x, byte *y, byte *w, byte *h, uint16 *offs) {
|
||||
int16 i;
|
||||
for (i = 0; i < MAX_DIRTY_RECT; i++) {
|
||||
if (dirty_rects[i].kind == kind) {
|
||||
getDirtyRect(i, &kind, x, y, w, h, offs, DirtyRectFree);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*Restore screen data from back buffer as specified by dirty rects of kind*/
|
||||
void popDirtyRects(byte kind) {
|
||||
byte x, y;
|
||||
byte width, height;
|
||||
uint16 offs;
|
||||
while (findDirtyRectAndFree(kind, &x, &y, &width, &height, &offs)) {
|
||||
cga_CopyScreenBlock(backbuffer, width, height, frontbuffer, offs);
|
||||
if (kind == DirtyRectBubble) {
|
||||
/*pop bubble's spike*/
|
||||
cga_CopyScreenBlock(backbuffer, 2, 21, frontbuffer, offs = (x << 8) | y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void desciTextBox(uint16 x, uint16 y, uint16 width, byte *msg) {
|
||||
draw_x = x;
|
||||
draw_y = y;
|
||||
char_draw_max_width = width;
|
||||
cga_DrawTextBox(msg, frontbuffer);
|
||||
addDirtyRect(DirtyRectText, draw_x, draw_y, char_draw_max_width + 2, char_draw_coords_y - draw_y + 8, CalcXY_p(draw_x, draw_y));
|
||||
}
|
||||
|
||||
/*Draw dialog bubble with text and spike*/
|
||||
void drawPersonBubble(byte x, byte y, byte flags, byte *msg) {
|
||||
uint16 ofs;
|
||||
byte w, h;
|
||||
uint16 ww, nw;
|
||||
|
||||
char_draw_max_width = flags & 0x1F;
|
||||
char_xlat_table = chars_color_bonw;
|
||||
|
||||
if (g_vm->getLanguage() == Common::EN_USA) {
|
||||
calcStringSize(msg, &ww, &nw);
|
||||
if (ww >= char_draw_max_width)
|
||||
char_draw_max_width = ww;
|
||||
}
|
||||
|
||||
/*upper border*/
|
||||
ofs = CalcXY_p(x, y);
|
||||
ofs = cga_DrawHLineWithEnds(0xF00F, 0, 0, char_draw_max_width, CGA_SCREENBUFFER, ofs);
|
||||
ofs = cga_DrawHLineWithEnds(0xC003, 0x0FF0, 0xFF, char_draw_max_width, CGA_SCREENBUFFER, ofs);
|
||||
ofs = cga_DrawHLineWithEnds(0, 0x3FFC, 0xFF, char_draw_max_width, CGA_SCREENBUFFER, ofs);
|
||||
ofs = cga_DrawHLineWithEnds(0, 0x3FFC, 0xFF, char_draw_max_width, CGA_SCREENBUFFER, ofs);
|
||||
|
||||
/*body*/
|
||||
char_draw_coords_x = x;
|
||||
char_draw_coords_y = y + 4;
|
||||
|
||||
for (string_ended = 0; !string_ended; char_draw_coords_y += 6) {
|
||||
cga_PrintChar(0x3B, CGA_SCREENBUFFER);
|
||||
msg = printStringPadded(msg, CGA_SCREENBUFFER);
|
||||
cga_PrintChar(0x3C, CGA_SCREENBUFFER);
|
||||
char_draw_coords_x = x;
|
||||
}
|
||||
|
||||
ofs = CalcXY_p(x, char_draw_coords_y);
|
||||
ofs = cga_DrawHLineWithEnds(0xC003, 0x0FF0, 0xFF, char_draw_max_width, CGA_SCREENBUFFER, ofs);
|
||||
ofs = cga_DrawHLineWithEnds(0xF00F, 0, 0, char_draw_max_width, CGA_SCREENBUFFER, ofs);
|
||||
|
||||
w = char_draw_max_width + 2;
|
||||
h = char_draw_coords_y - y + 2;
|
||||
|
||||
/*draw spike*/
|
||||
switch (flags & SPIKE_MASK) {
|
||||
case SPIKE_UPLEFT: /*upper-left spike*/
|
||||
ofs = CalcXY_p(x + 1, y - 7);
|
||||
drawSpriteN(18, x + 1, y - 7, CGA_SCREENBUFFER);
|
||||
break;
|
||||
case SPIKE_UPRIGHT: /*upper-right spike*/
|
||||
ofs = CalcXY_p(x + char_draw_max_width, y - 7) - 1;
|
||||
drawSpriteNFlip(18, x + char_draw_max_width, y - 7, CGA_SCREENBUFFER);
|
||||
break;
|
||||
case SPIKE_DNRIGHT: /*lower-right spike*/
|
||||
ofs = CalcXY_p(x + char_draw_max_width, char_draw_coords_y + 1) - 1;
|
||||
drawSpriteNFlip(21, x + char_draw_max_width, char_draw_coords_y + 1, CGA_SCREENBUFFER);
|
||||
break;
|
||||
case SPIKE_DNLEFT: /*lower-left spike*/
|
||||
ofs = CalcXY_p(x + 1, char_draw_coords_y + 1);
|
||||
drawSpriteN(21, x + 1, char_draw_coords_y + 1, CGA_SCREENBUFFER);
|
||||
break;
|
||||
case SPIKE_BUBRIGHT: /*lower-right bubbles*/
|
||||
ofs = CalcXY_p(x + char_draw_max_width, char_draw_coords_y + 4);
|
||||
drawSpriteN(20, x + char_draw_max_width, char_draw_coords_y + 4, CGA_SCREENBUFFER);
|
||||
break;
|
||||
case SPIKE_BUBLEFT: /*lower-left bubbles*/
|
||||
ofs = CalcXY_p(x + 1, char_draw_coords_y + 4);
|
||||
drawSpriteN(19, x + 1, char_draw_coords_y + 4, CGA_SCREENBUFFER);
|
||||
break;
|
||||
}
|
||||
|
||||
addDirtyRect(DirtyRectBubble, ofs >> 8, ofs & 255, w, h, CalcXY_p(x, y));
|
||||
}
|
||||
|
||||
void showPromptAnim(void) {
|
||||
if (script_byte_vars.zone_index == 135)
|
||||
return;
|
||||
waitVBlank();
|
||||
drawSpriteN(cursor_anim_phase ? 23 : 22, 300 / 4, 155, frontbuffer);
|
||||
cursor_anim_phase = ~cursor_anim_phase;
|
||||
}
|
||||
|
||||
void promptWait(void) {
|
||||
cursor_anim_phase = 0;
|
||||
|
||||
do {
|
||||
byte ticks = script_byte_vars.timer_ticks;
|
||||
if ((ticks % 8) == 0 && ticks != cursor_anim_ticks) {
|
||||
cursor_anim_ticks = ticks;
|
||||
showPromptAnim();
|
||||
}
|
||||
pollInputButtonsOnly();
|
||||
|
||||
if (g_vm->_shouldQuit)
|
||||
break;
|
||||
|
||||
g_system->updateScreen();
|
||||
g_system->delayMillis(10);
|
||||
} while (!buttons);
|
||||
|
||||
if (cursor_anim_phase)
|
||||
showPromptAnim();
|
||||
}
|
||||
|
||||
/*
|
||||
Get string with index num from strings bank
|
||||
*/
|
||||
byte *seekToString(byte *bank, uint16 num) {
|
||||
byte len;
|
||||
byte *p = bank;
|
||||
|
||||
cur_str_index = num;
|
||||
|
||||
num -= 4;
|
||||
while (num--) {
|
||||
len = *p;
|
||||
p += len;
|
||||
}
|
||||
len = *p;
|
||||
cur_str_end = p + len;
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Get string with index num from strings bank, with large string index support for scripts
|
||||
*/
|
||||
byte *seekToStringScr(byte *bank, uint16 num, byte **ptr) {
|
||||
byte len;
|
||||
byte *p = bank;
|
||||
|
||||
if (num < 4) {
|
||||
num = (num << 8) | *(++(*ptr));
|
||||
}
|
||||
cur_str_index = num;
|
||||
|
||||
num -= 4;
|
||||
while (num--) {
|
||||
len = *p;
|
||||
p += len;
|
||||
}
|
||||
len = *p;
|
||||
cur_str_end = p + len;
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
74
engines/chamber/dialog.h
Normal file
74
engines/chamber/dialog.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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 CHAMBER_DIALOG_H
|
||||
#define CHAMBER_DIALOG_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
extern uint16 cur_str_index;
|
||||
extern uint16 cur_dlg_index;
|
||||
|
||||
enum DirtyRectKind {
|
||||
DirtyRectFree = 0,
|
||||
DirtyRectBubble = 1, /*bubble with spike*/
|
||||
DirtyRectSprite = 2, /*portrait*/
|
||||
DirtyRectText = 3 /*text bubble w/o spike*/
|
||||
};
|
||||
|
||||
typedef struct dirty_rect_t {
|
||||
byte kind;
|
||||
uint16 offs;
|
||||
byte height;
|
||||
byte width;
|
||||
byte y; /*for DirtyRectBubble this is spike offs*/
|
||||
byte x;
|
||||
} dirty_rect_t;
|
||||
|
||||
#define MAX_DIRTY_RECT 10
|
||||
extern dirty_rect_t dirty_rects[];
|
||||
extern dirty_rect_t *last_dirty_rect;
|
||||
|
||||
#define SPIKE_MASK 0xE0
|
||||
#define SPIKE_UPLEFT 0
|
||||
#define SPIKE_UPRIGHT 0x20
|
||||
#define SPIKE_DNRIGHT 0x80
|
||||
#define SPIKE_DNLEFT 0xA0
|
||||
#define SPIKE_BUBBLES 0x40
|
||||
#define SPIKE_BUBRIGHT 0xC0
|
||||
#define SPIKE_BUBLEFT 0xE0
|
||||
|
||||
void addDirtyRect(byte kind, byte x, byte y, byte w, byte h, uint16 offs);
|
||||
void getDirtyRectAndFree(int16 index, byte *kind, byte *x, byte *y, byte *w, byte *h, uint16 *offs);
|
||||
void getDirtyRectAndSetSprite(int16 index, byte *kind, byte *x, byte *y, byte *w, byte *h, uint16 *offs);
|
||||
|
||||
void popDirtyRects(byte kind);
|
||||
void drawPersonBubble(byte x, byte y, byte flags, byte *msg);
|
||||
void desciTextBox(uint16 x, uint16 y, uint16 width, byte *msg);
|
||||
|
||||
void promptWait(void);
|
||||
|
||||
byte *seekToString(byte *bank, uint16 num);
|
||||
byte *seekToStringScr(byte *bank, uint16 num, byte **ptr);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
240
engines/chamber/enums.h
Normal file
240
engines/chamber/enums.h
Normal file
@@ -0,0 +1,240 @@
|
||||
/* 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 CHAMBER_ENUMS_H
|
||||
#define CHAMBER_ENUMS_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
/*game items, mirrors inventory_items (except kItemNone)*/
|
||||
enum Items {
|
||||
kItemNone = 0,
|
||||
|
||||
kItemSkull1 = 1,
|
||||
kItemSkull2 = 2,
|
||||
kItemSkull3 = 3,
|
||||
kItemSkull4 = 4,
|
||||
kItemSkull5 = 5,
|
||||
|
||||
kItemRope1 = 6,
|
||||
kItemRope2 = 7,
|
||||
kItemRope3 = 8,
|
||||
kItemRope4 = 9,
|
||||
kItemRope5 = 10,
|
||||
|
||||
kItemFly1 = 11,
|
||||
kItemFly2 = 12,
|
||||
kItemFly3 = 13,
|
||||
kItemFly4 = 14,
|
||||
|
||||
kItemGoblet1 = 15,
|
||||
kItemGoblet2 = 16,
|
||||
kItemGoblet3 = 17,
|
||||
kItemGoblet4 = 18,
|
||||
|
||||
kItemDagger1 = 19,
|
||||
kItemDagger2 = 20,
|
||||
kItemDagger3 = 21,
|
||||
kItemDagger4 = 22,
|
||||
|
||||
kItemLantern1 = 23,
|
||||
kItemLantern2 = 24,
|
||||
kItemLantern3 = 25,
|
||||
kItemLantern4 = 26,
|
||||
|
||||
kItemBlueSpider1 = 27,
|
||||
kItemBlueSpider2 = 28,
|
||||
kItemBlueSpider3 = 29,
|
||||
kItemBlueSpider4 = 30,
|
||||
|
||||
kItemRedSpider1 = 31,
|
||||
kItemRedSpider2 = 32,
|
||||
kItemRedSpider3 = 33,
|
||||
kItemRedSpider4 = 34,
|
||||
|
||||
kItemDie1 = 35,
|
||||
kItemDie2 = 36,
|
||||
kItemDie3 = 37,
|
||||
kItemDie4 = 38,
|
||||
|
||||
kItemZapstik1 = 39,
|
||||
kItemZapstik2 = 40,
|
||||
kItemZapstik3 = 41,
|
||||
kItemZapstik4 = 42,
|
||||
kItemZapstik5 = 43,
|
||||
kItemZapstik6 = 44,
|
||||
kItemZapstik7 = 45,
|
||||
kItemZapstik8 = 46,
|
||||
kItemZapstik9 = 47,
|
||||
kItemZapstik10 = 48,
|
||||
kItemZapstik11 = 49,
|
||||
kItemZapstik12 = 50,
|
||||
kItemZapstik13 = 51,
|
||||
kItemZapstik14 = 52,
|
||||
|
||||
kItemMask = 53,
|
||||
kItemWhistle = 54,
|
||||
kItemEgg1 = 55,
|
||||
kItemBlade = 56,
|
||||
kItemChopper = 57,
|
||||
kItemZorq = 58,
|
||||
kItemSaura = 59,
|
||||
kItemFlask = 60,
|
||||
kItemBean = 61,
|
||||
kItemEgg2 = 62,
|
||||
kItemEgg3 = 63
|
||||
};
|
||||
|
||||
/*game persons, mirrors pers_list*/
|
||||
enum Persons {
|
||||
kPersVort = 0,
|
||||
|
||||
kPersAspirant1 = 1,
|
||||
kPersAspirant2 = 2,
|
||||
kPersAspirant3 = 3,
|
||||
kPersAspirant4 = 4,
|
||||
|
||||
kPersTurkey = 5,
|
||||
|
||||
kPersPriestess1 = 6,
|
||||
kPersPriestess2 = 7,
|
||||
|
||||
kPersMaster = 8,
|
||||
|
||||
kPersProtozorq1 = 9,
|
||||
kPersProtozorq2 = 10,
|
||||
kPersProtozorq3 = 11,
|
||||
kPersProtozorq4 = 12,
|
||||
kPersProtozorq5 = 13,
|
||||
kPersProtozorq6 = 14,
|
||||
kPersProtozorq7 = 15,
|
||||
kPersProtozorq8 = 16,
|
||||
kPersProtozorq9 = 17,
|
||||
kPersProtozorq10 = 18,
|
||||
kPersProtozorq11 = 19,
|
||||
kPersProtozorq12 = 20,
|
||||
kPersProtozorq13 = 21,
|
||||
kPersProtozorq14 = 22,
|
||||
|
||||
kPersPoormouth = 23,
|
||||
kPersKhele = 24,
|
||||
kPersMistress = 25,
|
||||
kPersDeilos = 26,
|
||||
kPersScifi = 27,
|
||||
kPersNormajeen = 28,
|
||||
kPersAsh = 29,
|
||||
kPersMonkey = 30,
|
||||
kPersHarssk = 31,
|
||||
kPersZorq = 32,
|
||||
kPersQriich = 33,
|
||||
|
||||
kPersVort2 = 34,
|
||||
kPersVort3 = 35,
|
||||
|
||||
kPersPriestess3 = 36,
|
||||
kPersPriestess4 = 37,
|
||||
|
||||
kPersCadaver = 38,
|
||||
|
||||
kPersTurkey1 = 39,
|
||||
kPersTurkey2 = 40
|
||||
};
|
||||
|
||||
#define PersonOffset(p) ((p) * 5)
|
||||
|
||||
enum Areas {
|
||||
kAreaNone = 0,
|
||||
kAreaTheMastersEye = 1,
|
||||
kAreaTheMastersOrbit1 = 2,
|
||||
kAreaTheMastersOrbit2 = 3,
|
||||
kAreaTheMastersOrbit3 = 5,
|
||||
kAreaTheReturn = 8,
|
||||
kAreaTheRing1 = 10,
|
||||
kAreaTheRing2 = 12,
|
||||
kAreaTheRing3 = 14,
|
||||
kAreaTheRing4 = 16,
|
||||
kAreaTheRing5 = 18,
|
||||
kAreaTheRing6 = 20,
|
||||
kAreaDeProfundis = 22,
|
||||
kAreaTheWall = 24,
|
||||
kAreaTheInfidelsTomb1 = 25,
|
||||
kAreaTheInfidelsTomb2 = 26,
|
||||
kAreaVictoryOfTheFaith1 = 25,
|
||||
kAreaVictoryOfTheFaith2 = 26,
|
||||
kAreaDeadEnd = 29,
|
||||
kAreaTheWall2 = 30,
|
||||
kAreaTheInfidelsTomb3 = 31,
|
||||
kAreaTheInfidelsTomb4 = 32,
|
||||
kAreaVictoryOfTheFaith3 = 31,
|
||||
kAreaVictoryOfTheFaith4 = 32,
|
||||
kAreaDeadEnd2 = 35,
|
||||
kAreaTheNoose = 36,
|
||||
kAreaTheSource = 37,
|
||||
kAreaTheTwins = 38,
|
||||
kAreaWhoWillBeSaved = 39,
|
||||
kAreaInTheScorpionsPresence = 40,
|
||||
kAreaTheWeb = 41,
|
||||
kAreaPassage1 = 44,
|
||||
kAreaPassage2 = 46,
|
||||
kAreaPassage3 = 48,
|
||||
kAreaThePowersOfTheAbyss = 50,
|
||||
kAreaTheConcourse = 51,
|
||||
kAreaPassage4 = 52,
|
||||
kAreaPassage5 = 54,
|
||||
kAreaDreamsOfSlime = 55,
|
||||
kAreaGuardRoom = 56,
|
||||
kAreaAHiddenPlace = 57,
|
||||
kAreaAnteChamber = 58,
|
||||
kAreaPlacatingThePowers = 59,
|
||||
kAreaInThePresenceOfGod = 60,
|
||||
kAreaBirthOfADivineRace = 61,
|
||||
kAreaSaurasRepose = 62,
|
||||
kAreaTheThresholdOfTruth = 63,
|
||||
kAreaTheScriptures = 63,
|
||||
kAreaRefectory = 65,
|
||||
kAreaPassage6 = 66,
|
||||
kAreaPassage7 = 68,
|
||||
kAreaAblutions = 70,
|
||||
kAreaCell1 = 71,
|
||||
kAreaCell2 = 72,
|
||||
kAreaCell3 = 73,
|
||||
kAreaCell4 = 74,
|
||||
kAreaUpwardGallery = 75,
|
||||
kAreaGallery1 = 75,
|
||||
kAreaCavern = 77,
|
||||
kAreaGallery2 = 78,
|
||||
kAreaGallery3 = 79,
|
||||
kAreaGallery4 = 82,
|
||||
kAreaDownwardGallery = 83,
|
||||
kAreaGallery5 = 83,
|
||||
kAreaGallery6 = 85,
|
||||
kAreaPinkGallery1 = 87,
|
||||
kAreaGallery7 = 88,
|
||||
kAreaPinkGallery2 = 90,
|
||||
kAreaPinkGallery3 = 91,
|
||||
kAreaTube = 93,
|
||||
kAreaUnderwater = 94,
|
||||
kAreaObscurity = 101
|
||||
};
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
93
engines/chamber/ifgm.cpp
Normal file
93
engines/chamber/ifgm.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/ifgm.h"
|
||||
#include "chamber/dialog.h"
|
||||
#include "chamber/sound.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
byte ifgm_loaded = 0;
|
||||
byte ifgm_flag2;
|
||||
|
||||
void IFGM_Init(void) {
|
||||
if (g_vm->getLanguage() == Common::EN_USA) {
|
||||
/*TODO*/
|
||||
} else {
|
||||
ifgm_loaded = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void IFGM_Shutdown(void) {
|
||||
|
||||
}
|
||||
|
||||
void IFGM_Poll(void) {
|
||||
if(!ifgm_loaded)
|
||||
return;
|
||||
/*
|
||||
xor ax, ax
|
||||
int 0F0h
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Load and play a sound sample.
|
||||
Return 0 if playback is unavailable
|
||||
*/
|
||||
int16 IFGM_PlaySound(byte index) {
|
||||
if (!ifgm_loaded)
|
||||
return 0;
|
||||
|
||||
/*TODO*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void IFGM_PlaySample(byte index) {
|
||||
if (!ifgm_loaded)
|
||||
return;
|
||||
IFGM_PlaySound(index);
|
||||
}
|
||||
|
||||
void IFGM_StopSample(void) {
|
||||
if (!ifgm_loaded)
|
||||
return;
|
||||
}
|
||||
|
||||
static byte sfx_sounds[] = {
|
||||
0, 5, 10, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
void IFGM_PlaySfx(byte index) {
|
||||
if (!ifgm_loaded)
|
||||
return;
|
||||
if (cur_dlg_index == 0)
|
||||
return;
|
||||
playSound(sfx_sounds[index % 16]);
|
||||
}
|
||||
|
||||
} // end of namespace Chamber
|
||||
46
engines/chamber/ifgm.h
Normal file
46
engines/chamber/ifgm.h
Normal 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 CHAMBER_IFGM_H
|
||||
#define CHAMBER_IFGM_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
extern byte ifgm_loaded;
|
||||
|
||||
extern uint16 ifgm_flag1;
|
||||
extern byte ifgm_flag2;
|
||||
|
||||
void IFGM_Init(void);
|
||||
|
||||
void IFGM_Shutdown(void);
|
||||
|
||||
void IFGM_Poll(void);
|
||||
|
||||
void IFGM_PlaySample(byte index);
|
||||
void IFGM_StopSample(void);
|
||||
|
||||
int16 IFGM_PlaySound(byte index);
|
||||
void IFGM_PlaySfx(byte index);
|
||||
|
||||
} // end of namespace Chamber
|
||||
|
||||
#endif
|
||||
317
engines/chamber/input.cpp
Normal file
317
engines/chamber/input.cpp
Normal file
@@ -0,0 +1,317 @@
|
||||
/* 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/events.h"
|
||||
#include "common/system.h"
|
||||
|
||||
#include "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/dialog.h"
|
||||
#include "chamber/input.h"
|
||||
#include "chamber/cursor.h"
|
||||
#include "chamber/print.h"
|
||||
#include "chamber/resdata.h"
|
||||
#include "chamber/cga.h"
|
||||
#include "chamber/timer.h"
|
||||
#include "chamber/ifgm.h"
|
||||
|
||||
#include "backends/keymapper/keymapper.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
byte have_mouse = 0;
|
||||
byte have_joystick = 0;
|
||||
byte key_held;
|
||||
volatile byte key_direction;
|
||||
volatile byte key_code;
|
||||
|
||||
volatile byte keyboard_scan;
|
||||
volatile byte keyboard_specials;
|
||||
volatile byte keyboard_arrows;
|
||||
volatile byte keyboard_buttons;
|
||||
|
||||
byte buttons_repeat = 0;
|
||||
byte buttons;
|
||||
byte right_button;
|
||||
byte key_direction_old;
|
||||
byte accel_countdown;
|
||||
uint16 acceleration = 1;
|
||||
byte mouseButtons = 0;
|
||||
|
||||
void pollDiscrete(void);
|
||||
|
||||
byte ChamberEngine::readKeyboardChar() {
|
||||
Common::Event event;
|
||||
|
||||
Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper();
|
||||
keymapper->disableAllGameKeymaps();
|
||||
g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
|
||||
|
||||
while (true) {
|
||||
while (g_system->getEventManager()->pollEvent(event)) {
|
||||
switch (event.type) {
|
||||
case Common::EVENT_KEYDOWN:
|
||||
g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
|
||||
keymapper->getKeymap("chamber-default")->setEnabled(true);
|
||||
keymapper->getKeymap("game-shortcuts")->setEnabled(true);
|
||||
return event.kbd.ascii;
|
||||
|
||||
case Common::EVENT_RETURN_TO_LAUNCHER:
|
||||
case Common::EVENT_QUIT:
|
||||
_shouldQuit = true;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_system->updateScreen();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clearKeyboard(void) {
|
||||
}
|
||||
|
||||
void setInputButtons(byte keys) {
|
||||
if (keys & 2)
|
||||
right_button = 0xff;
|
||||
if (keys & 1)
|
||||
right_button = 0;
|
||||
buttons = keys;
|
||||
buttons_repeat = keys;
|
||||
}
|
||||
|
||||
byte pollMouse(void) {
|
||||
pollInput();
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
byte pollKeyboard(void) {
|
||||
byte direction = key_direction;
|
||||
if (direction && direction == key_direction_old) {
|
||||
if (++accel_countdown == 10) {
|
||||
acceleration++;
|
||||
accel_countdown = 0;
|
||||
}
|
||||
} else {
|
||||
acceleration = 1;
|
||||
accel_countdown = 0;
|
||||
}
|
||||
key_direction_old = direction;
|
||||
|
||||
if (direction & 0x0F) {
|
||||
if (direction == 1) {
|
||||
cursor_x += acceleration;
|
||||
if (cursor_x >= 304) /*TODO: >*/
|
||||
cursor_x = 304;
|
||||
} else {
|
||||
cursor_x -= acceleration;
|
||||
if ((int16)cursor_x < 0)
|
||||
cursor_x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (direction & 0xF0) {
|
||||
if (direction == 0x10) {
|
||||
cursor_y += acceleration;
|
||||
if (cursor_y >= 184) /*TODO: >*/
|
||||
cursor_y = 184;
|
||||
} else {
|
||||
cursor_y -= acceleration;
|
||||
if ((int8)cursor_y < 0)
|
||||
cursor_y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return key_code;
|
||||
}
|
||||
|
||||
/*
|
||||
Show game exit confirmation dialog and get user's input
|
||||
*/
|
||||
int16 askQuitGame(void) {
|
||||
/*EU version comes without requited text string*/
|
||||
if (g_vm->getLanguage() != Common::EN_USA)
|
||||
return 0;
|
||||
|
||||
int16 quit = -1;
|
||||
|
||||
byte *msg = seekToString(desci_data, 411); /*DO YOU WANT TO QUIT ? (Y OR N).*/
|
||||
char_draw_max_width = 32;
|
||||
draw_x = 1;
|
||||
draw_y = 188;
|
||||
cga_DrawTextBox(msg, frontbuffer);
|
||||
|
||||
Common::Event event;
|
||||
|
||||
Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper();
|
||||
keymapper->getKeymap("chamber-default")->setEnabled(false);
|
||||
keymapper->getKeymap("game-shortcuts")->setEnabled(false);
|
||||
keymapper->getKeymap("quit-dialog")->setEnabled(true);
|
||||
|
||||
while (quit == -1) {
|
||||
while (g_system->getEventManager()->pollEvent(event)) {
|
||||
switch (event.type) {
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
|
||||
if (event.customType == kActionYes)
|
||||
quit = 1;
|
||||
else if (event.customType == kActionNo)
|
||||
quit = 0;
|
||||
break;
|
||||
|
||||
case Common::EVENT_RETURN_TO_LAUNCHER:
|
||||
case Common::EVENT_QUIT:
|
||||
quit = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cga_CopyScreenBlock(backbuffer, char_draw_max_width + 2, char_draw_coords_y - draw_y + 8, frontbuffer, CalcXY_p(draw_x, draw_y));
|
||||
|
||||
keymapper->getKeymap("quit-dialog")->setEnabled(false);
|
||||
keymapper->getKeymap("chamber-default")->setEnabled(true);
|
||||
keymapper->getKeymap("game-shortcuts")->setEnabled(true);
|
||||
|
||||
return quit;
|
||||
}
|
||||
|
||||
void pollInputButtonsOnly() {
|
||||
pollInput();
|
||||
}
|
||||
|
||||
void pollInput(void) {
|
||||
Common::Event event;
|
||||
while (g_system->getEventManager()->pollEvent(event)) {
|
||||
switch (event.type) {
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
|
||||
if (event.customType == kActionInteract)
|
||||
mouseButtons |= 1;
|
||||
else if (event.customType == kActionQuit) {
|
||||
if (g_vm->getLanguage() == Common::EN_USA) {
|
||||
if (askQuitGame() != 0)
|
||||
g_vm->_shouldQuit = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
|
||||
if (event.customType == kActionInteract)
|
||||
mouseButtons &= ~1;
|
||||
break;
|
||||
|
||||
case Common::EVENT_RETURN_TO_LAUNCHER:
|
||||
case Common::EVENT_QUIT:
|
||||
g_vm->_shouldQuit = true;
|
||||
break;
|
||||
|
||||
case Common::EVENT_MOUSEMOVE:
|
||||
cursor_x = event.mouse.x;
|
||||
cursor_y = event.mouse.y;
|
||||
break;
|
||||
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
mouseButtons |= 1;
|
||||
break;
|
||||
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
mouseButtons &= ~1;
|
||||
break;
|
||||
|
||||
case Common::EVENT_RBUTTONDOWN:
|
||||
mouseButtons |= 2;
|
||||
break;
|
||||
|
||||
case Common::EVENT_RBUTTONUP:
|
||||
mouseButtons &= ~2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
setInputButtons(mouseButtons);
|
||||
}
|
||||
|
||||
void processInput(void) {
|
||||
pollInput();
|
||||
updateCursor();
|
||||
drawCursor(frontbuffer);
|
||||
}
|
||||
|
||||
void keyboardIsr() {
|
||||
warning("STUB: KeyboardIsr()");
|
||||
#if 0
|
||||
byte scan, strobe;
|
||||
scan = inportb(0x60);
|
||||
/*consume scan from kbd. controller*/
|
||||
strobe = inportb(0x61);
|
||||
outportb(0x61, strobe | 0x80);
|
||||
outportb(0x61, strobe);
|
||||
|
||||
if (scan == 1) { /*esc*/
|
||||
esc_pressed = ~0;
|
||||
} else {
|
||||
if (scan & 0x80) { /*key release?*/
|
||||
key_code = 0;
|
||||
key_direction = 0;
|
||||
} else {
|
||||
switch (scan) {
|
||||
case 0x39: /*space*/
|
||||
key_code = scan;
|
||||
key_direction = 0;
|
||||
break;
|
||||
case 0x48: /*up*/
|
||||
key_code = 0;
|
||||
key_direction = 0xF0;
|
||||
break;
|
||||
case 0x50: /*down*/
|
||||
key_code = 0;
|
||||
key_direction = 0x10;
|
||||
break;
|
||||
case 0x4B: /*left*/
|
||||
key_code = 0;
|
||||
key_direction = 0x0F;
|
||||
break;
|
||||
case 0x4D: /*right*/
|
||||
key_code = 0;
|
||||
key_direction = 0x01;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
outportb(0x20, 0x20);
|
||||
#endif
|
||||
}
|
||||
|
||||
void initInput(void) {
|
||||
have_mouse = 1;
|
||||
}
|
||||
|
||||
void uninitInput(void) {
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
54
engines/chamber/input.h
Normal file
54
engines/chamber/input.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* 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 CHAMBER_INPUT_H
|
||||
#define CHAMBER_INPUT_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
extern byte buttons;
|
||||
extern byte right_button;
|
||||
|
||||
extern byte have_mouse;
|
||||
|
||||
extern volatile byte key_direction;
|
||||
extern volatile byte key_code;
|
||||
extern byte key_held;
|
||||
|
||||
byte readKeyboardChar(void);
|
||||
void clearKeyboard(void);
|
||||
byte getKeyScan(void);
|
||||
|
||||
byte pollMouse(uint16 *curs_x, uint8 *curs_y);
|
||||
byte pollKeyboard(void);
|
||||
void setInputButtons(byte keys);
|
||||
|
||||
void pollInput(void);
|
||||
void processInput(void);
|
||||
void pollInputButtonsOnly(void);
|
||||
void resetInput(void);
|
||||
|
||||
void initInput(void);
|
||||
void uninitInput(void);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
141
engines/chamber/invent.cpp
Normal file
141
engines/chamber/invent.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/invent.h"
|
||||
#include "chamber/script.h"
|
||||
#include "chamber/cga.h"
|
||||
#include "chamber/cursor.h"
|
||||
#include "chamber/input.h"
|
||||
#include "chamber/sound.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
/*inventory box cells*/
|
||||
#define INVENTORY_SPOTS_MAX (4 * 4)
|
||||
|
||||
struct {
|
||||
byte sx;
|
||||
byte ex;
|
||||
byte sy;
|
||||
byte ey;
|
||||
byte name;
|
||||
byte unkn5;
|
||||
uint16 command;
|
||||
byte itemidx;
|
||||
byte unkn9;
|
||||
} inventory_spots[] = {
|
||||
{58, 62, 56, 72, 0, 0, 0, 0, 0},
|
||||
{62, 66, 56, 72, 0, 0, 0, 0, 0},
|
||||
{66, 70, 56, 72, 0, 0, 0, 0, 0},
|
||||
{70, 74, 56, 72, 0, 0, 0, 0, 0},
|
||||
{58, 62, 72, 88, 0, 0, 0, 0, 0},
|
||||
{62, 66, 72, 88, 0, 0, 0, 0, 0},
|
||||
{66, 70, 72, 88, 0, 0, 0, 0, 0},
|
||||
{70, 74, 72, 88, 0, 0, 0, 0, 0},
|
||||
{58, 62, 88, 104, 0, 0, 0, 0, 0},
|
||||
{62, 66, 88, 104, 0, 0, 0, 0, 0},
|
||||
{66, 70, 88, 104, 0, 0, 0, 0, 0},
|
||||
{70, 74, 88, 104, 0, 0, 0, 0, 0},
|
||||
{58, 62, 104, 120, 0, 0, 0, 0, 0},
|
||||
{62, 66, 104, 120, 0, 0, 0, 0, 0},
|
||||
{66, 70, 104, 120, 0, 0, 0, 0, 0},
|
||||
{70, 74, 104, 120, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
byte inv_count = 0; /*TODO: pass this as param?*/
|
||||
byte inv_bgcolor = 0; /*TODO: pass this as param?*/
|
||||
|
||||
/*
|
||||
Filter items and put them inventory box, then draw it if non-empty
|
||||
filtermask/filtervalue specify area (in high 8 bits) and flags (in lower 8 bits)
|
||||
*/
|
||||
void drawInventoryBox(uint16 filtermask, uint16 filtervalue) {
|
||||
int16 i;
|
||||
byte count = 0;
|
||||
for (i = 0; i < MAX_INV_ITEMS; i++) {
|
||||
uint16 flags = (inventory_items[i].area << 8) | inventory_items[i].flags;
|
||||
if ((flags & filtermask) != filtervalue)
|
||||
continue;
|
||||
if (count == 0) {
|
||||
/*once first valid item found, draw the box*/
|
||||
cga_FillAndWait(inv_bgcolor, 64 / 4, 64, CGA_SCREENBUFFER, CalcXY_p(232 / 4, 56));
|
||||
playSound(20);
|
||||
}
|
||||
inventory_spots[count].name = inventory_items[i].name;
|
||||
inventory_spots[count].command = inventory_items[i].command;
|
||||
inventory_spots[count].itemidx = i + 1;
|
||||
drawSpriteN(inventory_items[i].sprite, inventory_spots[count].sx, inventory_spots[count].sy, CGA_SCREENBUFFER);
|
||||
count++;
|
||||
}
|
||||
inv_count = count;
|
||||
}
|
||||
|
||||
void checkInventoryItemHover(byte count) {
|
||||
int16 i;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (isCursorInRect((rect_t *)&inventory_spots[i])) {
|
||||
the_command = inventory_spots[i].command;
|
||||
command_hint = inventory_spots[i].name;
|
||||
cursor_color = 0xAA;
|
||||
script_byte_vars.inv_item_index = inventory_spots[i].itemidx;
|
||||
script_vars[kScrPool3_CurrentItem] = &inventory_items[script_byte_vars.inv_item_index - 1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*nothing found*/
|
||||
command_hint = 100;
|
||||
cursor_color = 0xFF;
|
||||
the_command = 0;
|
||||
}
|
||||
|
||||
void openInventory(uint16 filtermask, uint16 filtervalue) {
|
||||
the_command = 0;
|
||||
cga_BackupImageReal(CalcXY_p(232 / 4, 56), 64 / 4, 64);
|
||||
drawInventoryBox(filtermask, filtervalue);
|
||||
if (inv_count != 0) {
|
||||
selectCursor(CURSOR_FINGER);
|
||||
processInput();
|
||||
do {
|
||||
pollInput();
|
||||
checkInventoryItemHover(inv_count);
|
||||
if (command_hint != last_command_hint)
|
||||
drawCommandHint();
|
||||
drawHintsAndCursor(frontbuffer);
|
||||
} while (buttons == 0);
|
||||
undrawCursor(frontbuffer);
|
||||
}
|
||||
cga_RestoreImage(scratch_mem2, frontbuffer);
|
||||
playSound(20);
|
||||
switch (((item_t *)script_vars[kScrPool3_CurrentItem])->name) {
|
||||
case 108: /*DAGGER*/
|
||||
case 115: /*SACRIFICIAL BLADE*/
|
||||
case 117: /*CHOPPER*/
|
||||
script_byte_vars.bvar_63 = 1;
|
||||
break;
|
||||
default:
|
||||
script_byte_vars.bvar_63 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
36
engines/chamber/invent.h
Normal file
36
engines/chamber/invent.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* 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 CHAMBER_INVENT_H
|
||||
#define CHAMBER_INVENT_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
extern byte inv_count;
|
||||
extern byte inv_bgcolor;
|
||||
|
||||
void drawInventoryBox(uint16 filtermask, uint16 filtervalue);
|
||||
|
||||
void openInventory(uint16 filtermask, uint16 filtervalue);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
411
engines/chamber/kult.cpp
Normal file
411
engines/chamber/kult.cpp
Normal file
@@ -0,0 +1,411 @@
|
||||
/* 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/error.h"
|
||||
#include "common/system.h"
|
||||
#include "engines/util.h"
|
||||
|
||||
#include "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/decompr.h"
|
||||
#include "chamber/cga.h"
|
||||
#include "chamber/anim.h"
|
||||
#include "chamber/cursor.h"
|
||||
#include "chamber/input.h"
|
||||
#include "chamber/timer.h"
|
||||
#include "chamber/portrait.h"
|
||||
#include "chamber/room.h"
|
||||
#include "chamber/savegame.h"
|
||||
#include "chamber/resdata.h"
|
||||
#include "chamber/script.h"
|
||||
#include "chamber/print.h"
|
||||
#include "chamber/dialog.h"
|
||||
#include "chamber/menu.h"
|
||||
#include "chamber/ifgm.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
uint16 cpu_speed_delay;
|
||||
|
||||
/*
|
||||
Prompt user to insert disk #2 to any drive
|
||||
*/
|
||||
void askDisk2(void) {
|
||||
drawMessage(seekToString(vepci_data, 179), frontbuffer);
|
||||
}
|
||||
|
||||
void saveToFile(char *filename, void *data, uint16 size) {
|
||||
warning("STUB: SaveToFile(%s, data, %d)", filename, size);
|
||||
#if 0
|
||||
FILE *f = fopen(filename, "wb");
|
||||
fwrite(data, 1, size, f);
|
||||
fclose(f);
|
||||
#endif
|
||||
}
|
||||
|
||||
int16 loadSplash(const char *filename) {
|
||||
if (!loadFile(filename, scratch_mem1))
|
||||
return 0;
|
||||
decompress(scratch_mem1 + 8, backbuffer); /* skip compressed/decompressed size fields */
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16 benchmarkCpu(void) {
|
||||
byte t;
|
||||
uint16 cycles = 0;
|
||||
for (t = script_byte_vars.timer_ticks; t == script_byte_vars.timer_ticks;) ;
|
||||
for (t = script_byte_vars.timer_ticks; t == script_byte_vars.timer_ticks;) cycles++;
|
||||
return cycles;
|
||||
}
|
||||
|
||||
void randomize(void) {
|
||||
warning("STUB: Randomize()");
|
||||
#if 0
|
||||
union REGS reg;
|
||||
|
||||
reg.h.ah = 0;
|
||||
int86(0x1A, ®, ®);
|
||||
rand_seed = reg.h.dl;
|
||||
Rand();
|
||||
#endif
|
||||
}
|
||||
|
||||
void TRAP() {
|
||||
promptWait();
|
||||
for (;;) ;
|
||||
}
|
||||
|
||||
/* Main Game Loop */
|
||||
void gameLoop(byte *target) {
|
||||
for (;;) {
|
||||
animateSpots(target);
|
||||
|
||||
/* Update/check live things */
|
||||
updateProtozorqs();
|
||||
checkGameTimeLimit();
|
||||
cleanupDroppedItems();
|
||||
|
||||
/* Get player input */
|
||||
pollInput();
|
||||
|
||||
if (g_vm->_shouldQuit)
|
||||
return;
|
||||
|
||||
the_command = 0;
|
||||
if (isCursorInRect(&room_bounds_rect)) {
|
||||
selectCursor(CURSOR_TARGET);
|
||||
command_hint = 100;
|
||||
selectSpotCursor();
|
||||
} else {
|
||||
selectCursor(CURSOR_FINGER);
|
||||
object_hint = 117;
|
||||
checkMenuCommandHover();
|
||||
}
|
||||
|
||||
if (object_hint != last_object_hint)
|
||||
drawObjectHint();
|
||||
|
||||
if (command_hint != last_command_hint)
|
||||
drawCommandHint();
|
||||
|
||||
drawHintsAndCursor(target);
|
||||
|
||||
if (!buttons || !the_command) {
|
||||
/*Pending / AI commands*/
|
||||
|
||||
if (script_byte_vars.check_used_commands < script_byte_vars.used_commands) {
|
||||
the_command = Swap16(script_word_vars.next_aspirant_cmd);
|
||||
if (the_command)
|
||||
goto process;
|
||||
}
|
||||
|
||||
if (script_byte_vars.bvar_45)
|
||||
continue;
|
||||
|
||||
the_command = Swap16(script_word_vars.next_protozorqs_cmd);
|
||||
if (the_command)
|
||||
goto process;
|
||||
|
||||
if (Swap16(next_vorts_ticks) < script_word_vars.timer_ticks2) { /*TODO: is this ok? ticks2 is BE, ticks3 is LE*/
|
||||
the_command = next_vorts_cmd;
|
||||
if (the_command)
|
||||
goto process;
|
||||
}
|
||||
|
||||
if (Swap16(next_turkey_ticks) < script_word_vars.timer_ticks2) { /*TODO: is this ok? ticks2 is BE, ticks4 is LE*/
|
||||
the_command = next_turkey_cmd;
|
||||
if (the_command)
|
||||
goto process;
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
process:
|
||||
;
|
||||
updateUndrawCursor(target);
|
||||
refreshSpritesData();
|
||||
runCommand();
|
||||
if (g_vm->_shouldRestart)
|
||||
return;
|
||||
blitSpritesToBackBuffer();
|
||||
processInput();
|
||||
drawSpots(target);
|
||||
} else {
|
||||
/*Player action*/
|
||||
|
||||
updateUndrawCursor(target);
|
||||
refreshSpritesData();
|
||||
uint16 restart = runCommandKeepSp();
|
||||
if (restart == RUNCOMMAND_RESTART && g_vm->_shouldRestart)
|
||||
return;
|
||||
script_byte_vars.used_commands++;
|
||||
if (script_byte_vars.dead_flag) {
|
||||
if (--script_byte_vars.tries_left == 0)
|
||||
resetAllPersons();
|
||||
}
|
||||
blitSpritesToBackBuffer();
|
||||
processInput();
|
||||
drawSpots(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void exitGame(void) {
|
||||
switchToTextMode();
|
||||
uninitTimer();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENDING
|
||||
extern theEnd(void);
|
||||
#endif
|
||||
|
||||
Common::Error ChamberEngine::init() {
|
||||
byte c;
|
||||
|
||||
// Initialize graphics using following:
|
||||
if (_videoMode == Common::RenderMode::kRenderCGA) {
|
||||
// 320x200x2
|
||||
_screenW = 320;
|
||||
_screenH = 200;
|
||||
_screenBits = 2;
|
||||
_screenPPB = 8 / _screenBits;
|
||||
_screenBPL = _screenW / _screenPPB;
|
||||
_line_offset = 0x2000;
|
||||
_fontHeight = 6;
|
||||
_fontWidth = 4;
|
||||
initGraphics(_screenW, _screenH);
|
||||
} else if (_videoMode == Common::RenderMode::kRenderHercG) {
|
||||
// 720x348x1
|
||||
_screenW = 720;
|
||||
_screenH = 348;
|
||||
_screenBits = 1;
|
||||
_screenPPB = 8 / _screenBits;
|
||||
_screenBPL = _screenW / _screenPPB;
|
||||
_line_offset = 0x2000;
|
||||
_line_offset2 = 0x2000;
|
||||
_fontHeight = 6;
|
||||
_fontWidth = 4;
|
||||
initGraphics(_screenW, _screenH);
|
||||
}
|
||||
initSound();
|
||||
|
||||
/*TODO: DetectCPU*/
|
||||
|
||||
IFGM_Init();
|
||||
|
||||
switchToGraphicsMode();
|
||||
|
||||
/* Install timer callback */
|
||||
initTimer();
|
||||
|
||||
if (g_vm->getLanguage() == Common::EN_USA) {
|
||||
/* Load title screen */
|
||||
if (!loadSplash("PRESCGA.BIN"))
|
||||
exitGame();
|
||||
|
||||
if (ifgm_loaded) {
|
||||
/*TODO*/
|
||||
}
|
||||
} else {
|
||||
/* Load title screen */
|
||||
if (!loadSplash("PRES.BIN"))
|
||||
exitGame();
|
||||
}
|
||||
|
||||
if (_videoMode == Common::RenderMode::kRenderCGA) {
|
||||
/* Select intense cyan-mageta palette */
|
||||
cga_ColorSelect(0x30);
|
||||
cga_BackBufferToRealFull();
|
||||
} else if (_videoMode == Common::RenderMode::kRenderHercG) {
|
||||
/* Select intense cyan-mageta palette */
|
||||
cga_ColorSelect(0x30);
|
||||
cga_BackBufferToRealFull();
|
||||
}
|
||||
|
||||
/* Wait for a keypress */
|
||||
clearKeyboard();
|
||||
readKeyboardChar();
|
||||
|
||||
|
||||
if (g_vm->getLanguage() == Common::EN_USA) {
|
||||
if (ifgm_loaded) {
|
||||
/*TODO*/
|
||||
}
|
||||
|
||||
/* Force English language */
|
||||
c = 'E';
|
||||
} else {
|
||||
/* Load language selection screen */
|
||||
if (!loadSplash("DRAP.BIN"))
|
||||
exitGame();
|
||||
|
||||
/* Wait for a keypress and show the language selection screen */
|
||||
clearKeyboard();
|
||||
readKeyboardChar();
|
||||
|
||||
if (_shouldQuit)
|
||||
return Common::kNoError;
|
||||
|
||||
cga_BackBufferToRealFull();
|
||||
clearKeyboard();
|
||||
|
||||
/* Wait for a valid language choice */
|
||||
do {
|
||||
c = readKeyboardChar();
|
||||
if (c > 'F')
|
||||
c -= ' ';
|
||||
} while (c < 'D' || c > 'F');
|
||||
}
|
||||
|
||||
if (_shouldQuit)
|
||||
return Common::kNoError;
|
||||
|
||||
/* Patch resource names for chosen language */
|
||||
res_texts[0].name[4] = c;
|
||||
res_texts[1].name[4] = c;
|
||||
res_desci[0].name[4] = c;
|
||||
res_diali[0].name[4] = c;
|
||||
|
||||
if (g_vm->getLanguage() != Common::EN_USA)
|
||||
cga_BackBufferToRealFull();
|
||||
|
||||
/* Load script and other static resources */
|
||||
/* Those are normally embedded in the executable, but here we load extracted ones*/
|
||||
if (!loadStaticData())
|
||||
exitGame();
|
||||
|
||||
/* Load text resources */
|
||||
if (!loadVepciData() || !loadDesciData() || !loadDialiData())
|
||||
exitGame();
|
||||
|
||||
/* Detect/Initialize input device */
|
||||
initInput();
|
||||
|
||||
/* Load graphics resources */
|
||||
while (!loadFond() || !loadSpritesData() || !loadPersData())
|
||||
askDisk2();
|
||||
|
||||
/*TODO: is this necessary?*/
|
||||
cga_BackBufferToRealFull();
|
||||
|
||||
/* Create clean game state snapshot */
|
||||
saveRestartGame();
|
||||
|
||||
/* Detect CPU speed for delay routines */
|
||||
cpu_speed_delay = benchmarkCpu() / 8;
|
||||
|
||||
if (g_vm->getLanguage() == Common::EN_USA) {
|
||||
if (ifgm_loaded) {
|
||||
/*TODO*/
|
||||
}
|
||||
}
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
Common::Error ChamberEngine::execute() {
|
||||
randomize();
|
||||
|
||||
/* Set start zone */
|
||||
script_byte_vars.zone_index = 7;
|
||||
|
||||
/* Begin the game */
|
||||
script_byte_vars.game_paused = 0;
|
||||
|
||||
#ifdef DEBUG_SCRIPT
|
||||
unlink(DEBUG_SCRIPT_LOG);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SKIP_INTRO
|
||||
/*bypass characters introduction*/
|
||||
script_byte_vars.load_flag = DEBUG_SKIP_INTRO;
|
||||
#endif
|
||||
|
||||
/* Discard all pending input */
|
||||
//ResetInput();
|
||||
|
||||
/* Play introduction sequence and initialize game */
|
||||
the_command = 0xC001;
|
||||
runCommand();
|
||||
|
||||
if (_shouldQuit)
|
||||
return Common::kNoError;
|
||||
|
||||
/* Sync graphics */
|
||||
blitSpritesToBackBuffer();
|
||||
|
||||
/* Initialize cursor backup */
|
||||
processInput();
|
||||
|
||||
#ifdef DEBUG_ENDING
|
||||
script_byte_vars.game_paused = 5;
|
||||
theEnd();
|
||||
for (;;) ;
|
||||
#endif
|
||||
|
||||
/* Main game loop */
|
||||
gameLoop(frontbuffer);
|
||||
if (g_vm->_shouldRestart)
|
||||
run();
|
||||
|
||||
/*TODO: the following code is never executed since gameLoop is infinite (or the whole game is restarted) */
|
||||
|
||||
/* Release hardware */
|
||||
uninitInput();
|
||||
|
||||
exitGame();
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
Common::Error ChamberEngine::run() {
|
||||
if (!g_vm->_shouldRestart)
|
||||
init();
|
||||
|
||||
do {
|
||||
g_vm->_shouldRestart = false;
|
||||
execute();
|
||||
} while (g_vm->_shouldRestart);
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
255
engines/chamber/menu.cpp
Normal file
255
engines/chamber/menu.cpp
Normal file
@@ -0,0 +1,255 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/menu.h"
|
||||
#include "chamber/cga.h"
|
||||
#include "chamber/input.h"
|
||||
#include "chamber/cursor.h"
|
||||
#include "chamber/room.h"
|
||||
#include "chamber/sound.h"
|
||||
#include "chamber/script.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
byte act_menu_x = 0;
|
||||
byte act_menu_y = 0;
|
||||
|
||||
rect_t *act_dot_rects_cur;
|
||||
rect_t *act_dot_rects_end;
|
||||
|
||||
/*choice dots placement on actions menu*/
|
||||
rect_t act_dot_rects[8 + 1];
|
||||
struct {
|
||||
byte x, y;
|
||||
} act_dot_coords[8] = {
|
||||
{ 2, 0},
|
||||
{ 8, 32},
|
||||
{ 2, 32},
|
||||
{10, 8},
|
||||
{ 0, 24},
|
||||
{ 8, 0},
|
||||
{ 0, 8},
|
||||
{10, 24}
|
||||
};
|
||||
|
||||
/*Handle keyboard keys in actions menu (to cycle through choices with directional keys)*/
|
||||
byte pollKeyboardInActionsMenu(void) {
|
||||
pollInput();
|
||||
if (!(key_direction & 0xF)) {
|
||||
key_held = 0;
|
||||
return key_code;
|
||||
}
|
||||
|
||||
if (key_held)
|
||||
return key_code;
|
||||
|
||||
key_held = 1;
|
||||
|
||||
/*cycle through menu choices*/
|
||||
|
||||
cursor_x = act_dot_rects_cur->sx * 4 + 1;
|
||||
cursor_y = act_dot_rects_cur->sy + 4;
|
||||
|
||||
if (++act_dot_rects_cur == act_dot_rects_end)
|
||||
act_dot_rects_cur = act_dot_rects;
|
||||
|
||||
return key_code;
|
||||
}
|
||||
|
||||
/*Handle player input in actions menu*/
|
||||
void pollInputInActionsMenu(void) {
|
||||
pollInput();
|
||||
}
|
||||
|
||||
/*Draw actions menu and process its choices*/
|
||||
void actionsMenu(byte **pinfo) {
|
||||
byte x, y;
|
||||
byte choices;
|
||||
int16 i, choice, numchoices;
|
||||
byte *menurecs;
|
||||
|
||||
last_object_hint = object_hint;
|
||||
|
||||
if (act_menu_x == 0xFF) {
|
||||
/*recalc menu pos*/
|
||||
x = cursor_x / 4;
|
||||
if ((int)(x + 48 / 4) >= 296 / 4)
|
||||
x -= x + 48 / 4 - 296 / 4;
|
||||
if (x < 32 / 4)
|
||||
x = 32 / 4;
|
||||
act_menu_x = x;
|
||||
|
||||
y = cursor_y;
|
||||
if ((int)(y + 45) >= 180)
|
||||
y -= y + 45 - 180;
|
||||
act_menu_y = y;
|
||||
}
|
||||
|
||||
x = act_menu_x;
|
||||
y = act_menu_y;
|
||||
|
||||
/*menu sprite*/
|
||||
backupAndShowSprite(0, x, y);
|
||||
playSound(18);
|
||||
|
||||
choices = *((*pinfo)++);
|
||||
menurecs = *pinfo;
|
||||
|
||||
numchoices = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (choices & (1 << i)) {
|
||||
act_dot_rects[numchoices].sx = x + act_dot_coords[i].x;
|
||||
act_dot_rects[numchoices].ex = act_dot_rects[numchoices].sx + 8 / 4;
|
||||
act_dot_rects[numchoices].sy = y + act_dot_coords[i].y;
|
||||
act_dot_rects[numchoices].ey = act_dot_rects[numchoices].sy + 8;
|
||||
numchoices++;
|
||||
}
|
||||
}
|
||||
act_dot_rects[numchoices].sx = x + 24 / 4;
|
||||
act_dot_rects[numchoices].sy = y + 22;
|
||||
/*TODO: no ex/ey?*/
|
||||
act_dot_rects_end = act_dot_rects + numchoices + 1;
|
||||
|
||||
for (i = 0; i < numchoices; i++)
|
||||
drawSpriteN(1, act_dot_rects[i].sx, act_dot_rects[i].sy, CGA_SCREENBUFFER);
|
||||
|
||||
selectCursor(CURSOR_FINGER);
|
||||
processInput();
|
||||
|
||||
choice = 0;
|
||||
act_dot_rects_cur = act_dot_rects;
|
||||
do {
|
||||
pollInputInActionsMenu();
|
||||
|
||||
for (choice = 0; choice < numchoices; choice++) {
|
||||
if (isCursorInRect(&act_dot_rects[choice]))
|
||||
break;
|
||||
}
|
||||
if (choice < numchoices) {
|
||||
cursor_color = 0xAA;
|
||||
command_hint = menurecs[choice * 3];
|
||||
the_command = (menurecs[choice * 3 + 1] << 8) | menurecs[choice * 3 + 2];
|
||||
} else {
|
||||
cursor_color = 0xFF;
|
||||
command_hint = 100;
|
||||
the_command = 0xFFFF;
|
||||
}
|
||||
|
||||
if (command_hint != last_command_hint)
|
||||
drawCommandHint(); /*to backbuffer*/
|
||||
drawHintsAndCursor(CGA_SCREENBUFFER);
|
||||
} while (buttons == 0);
|
||||
undrawCursor(CGA_SCREENBUFFER);
|
||||
|
||||
if (the_command != 0xFFFF) {
|
||||
playSound(19);
|
||||
waitVBlank();
|
||||
|
||||
/*draw dot explosion animation*/
|
||||
drawSpriteN(24, act_dot_rects[choice].sx, act_dot_rects[choice].sy, CGA_SCREENBUFFER);
|
||||
for (i = 0; i < 0xFFF; i++) ; /*TODO: weak delay*/
|
||||
drawSpriteN(2, act_dot_rects[choice].sx, act_dot_rects[choice].sy, CGA_SCREENBUFFER);
|
||||
for (i = 0; i < 0xFFF; i++) ; /*TODO: weak delay*/
|
||||
drawSpriteN(25, act_dot_rects[choice].sx, act_dot_rects[choice].sy, CGA_SCREENBUFFER);
|
||||
for (i = 0; i < 0xFFF; i++) ; /*TODO: weak delay*/
|
||||
}
|
||||
cga_RestoreBackupImage(CGA_SCREENBUFFER);
|
||||
|
||||
*pinfo += numchoices * 3;
|
||||
}
|
||||
|
||||
/*TODO: maybe rename to SpotsLoop*/
|
||||
void menuLoop(byte spotmask, byte spotvalue) {
|
||||
processInput();
|
||||
do {
|
||||
pollInput();
|
||||
checkHotspots(spotmask, spotvalue);
|
||||
if (object_hint != last_object_hint)
|
||||
drawObjectHint();
|
||||
drawHintsAndCursor(frontbuffer);
|
||||
} while (buttons == 0);
|
||||
undrawCursor(frontbuffer);
|
||||
}
|
||||
|
||||
void processMenu(void) {
|
||||
selectCursor(CURSOR_BODY);
|
||||
menuLoop(SPOTFLG_80 | SPOTFLG_20 | SPOTFLG_10 | SPOTFLG_8, SPOTFLG_80 | SPOTFLG_10);
|
||||
}
|
||||
|
||||
|
||||
rect_t menu_buttons_rects[] = {
|
||||
{296 / 4, 312 / 4, 15, 30}, /*Room's Objects*/
|
||||
{296 / 4, 312 / 4, 40, 56}, /*Psi Powers*/
|
||||
{296 / 4, 312 / 4, 56, 72}, /*Possessions*/
|
||||
{296 / 4, 312 / 4, 72, 88}, /*Energy Level*/
|
||||
{296 / 4, 312 / 4, 88, 104}, /*Wait*/
|
||||
{296 / 4, 312 / 4, 104, 120}, /*Load*/
|
||||
{296 / 4, 312 / 4, 120, 136}, /*Save*/
|
||||
{296 / 4, 312 / 4, 136, 152} /*Time*/
|
||||
};
|
||||
|
||||
void checkMenuCommandHover(void) {
|
||||
int16 i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (isCursorInRect(&menu_buttons_rects[i])) {
|
||||
the_command = 0xA001 + i;
|
||||
command_hint = i ? (i + 3) : 101;
|
||||
cursor_color = 0xAA;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*nothing found*/
|
||||
command_hint = 100;
|
||||
cursor_color = 0xFF;
|
||||
the_command = 0;
|
||||
}
|
||||
|
||||
rect_t psi_buttons_rects[] = {
|
||||
{280 / 4, 296 / 4, 40, 56}, /*Solar Eyes*/
|
||||
{280 / 4, 296 / 4, 56, 72}, /*Sticky Fingers*/
|
||||
{280 / 4, 296 / 4, 72, 88}, /*Know Mind*/
|
||||
{280 / 4, 296 / 4, 88, 104}, /*Brainwarp*/
|
||||
{280 / 4, 296 / 4, 104, 120}, /*Zone Scan*/
|
||||
{280 / 4, 296 / 4, 120, 136}, /*Psi Shift*/
|
||||
{280 / 4, 296 / 4, 136, 152}, /*Extreme Violence*/
|
||||
{280 / 4, 296 / 4, 152, 168} /*Tune In*/
|
||||
};
|
||||
|
||||
void checkPsiCommandHover(void) {
|
||||
/*TODO: maybe merge it with CheckMenuCommandHover()*/
|
||||
int16 i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (isCursorInRect(&psi_buttons_rects[i])) {
|
||||
the_command = 0xA00A + i;
|
||||
command_hint = i + 12;
|
||||
cursor_color = 0xAA;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*nothing found*/
|
||||
command_hint = 100;
|
||||
cursor_color = 0xFF;
|
||||
the_command = 0;
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
39
engines/chamber/menu.h
Normal file
39
engines/chamber/menu.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* 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 CHAMBER_MENU_H
|
||||
#define CHAMBER_MENU_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
extern byte act_menu_x;
|
||||
extern byte act_menu_y;
|
||||
|
||||
void actionsMenu(byte **pinfo);
|
||||
void menuLoop(byte spotmask, byte spotvalue);
|
||||
void processMenu(void);
|
||||
|
||||
void checkMenuCommandHover(void);
|
||||
void checkPsiCommandHover(void);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
118
engines/chamber/metaengine.cpp
Normal file
118
engines/chamber/metaengine.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
#include "engines/advancedDetector.h"
|
||||
|
||||
#include "common/translation.h"
|
||||
|
||||
#include "backends/keymapper/action.h"
|
||||
#include "backends/keymapper/keymapper.h"
|
||||
#include "backends/keymapper/standard-actions.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
Common::Language ChamberEngine::getLanguage() const {
|
||||
return _gameDescription->language;
|
||||
}
|
||||
|
||||
} // end of namespace Chamber
|
||||
|
||||
class ChamberMetaEngine : public AdvancedMetaEngine<ADGameDescription> {
|
||||
public:
|
||||
const char *getName() const override {
|
||||
return "chamber";
|
||||
}
|
||||
|
||||
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
|
||||
Common::KeymapArray initKeymaps(const char *target) const override;
|
||||
};
|
||||
|
||||
Common::Error ChamberMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
|
||||
*engine = new Chamber::ChamberEngine(syst, desc);
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
|
||||
Common::KeymapArray ChamberMetaEngine::initKeymaps(const char *target) const {
|
||||
using namespace Common;
|
||||
using namespace Chamber;
|
||||
|
||||
Keymap *engineKeymap = new Keymap(Keymap::kKeymapTypeGame, "chamber-default", _("Default keymappings"));
|
||||
Keymap *gameKeymap = new Keymap(Keymap::kKeymapTypeGame, "game-shortcuts", _("Game keymappings"));
|
||||
Keymap *quitDialogKeymap = new Keymap(Keymap::kKeymapTypeGame, "quit-dialog", _("Quit dialog keymappings"));
|
||||
|
||||
Action *act;
|
||||
|
||||
act = new Action(kStandardActionLeftClick, _("Select / Interact"));
|
||||
act->setLeftClickEvent();
|
||||
act->addDefaultInputMapping("MOUSE_LEFT");
|
||||
act->addDefaultInputMapping("JOY_A");
|
||||
engineKeymap->addAction(act);
|
||||
|
||||
act = new Action(kStandardActionRightClick, _("Select / Interact"));
|
||||
act->setRightClickEvent();
|
||||
act->addDefaultInputMapping("MOUSE_RIGHT");
|
||||
act->addDefaultInputMapping("JOY_B");
|
||||
engineKeymap->addAction(act);
|
||||
|
||||
act = new Action("INTERACT", _("Select / Interact"));
|
||||
act->setCustomEngineActionEvent(kActionInteract);
|
||||
act->addDefaultInputMapping("SPACE");
|
||||
gameKeymap->addAction(act);
|
||||
|
||||
// Only the EN_USA version has a quit dialog. Input handling does a similar check.
|
||||
if (parseLanguage(ConfMan.get("language")) == EN_USA) {
|
||||
act = new Action("QUIT", _("Quit"));
|
||||
act->setCustomEngineActionEvent(kActionQuit);
|
||||
act->addDefaultInputMapping("ESCAPE");
|
||||
act->addDefaultInputMapping("JOY_X");
|
||||
gameKeymap->addAction(act);
|
||||
}
|
||||
|
||||
act = new Action("YES", _("Yes"));
|
||||
act->setCustomEngineActionEvent(kActionYes);
|
||||
act->addDefaultInputMapping("y");
|
||||
act->addDefaultInputMapping("JOY_A");
|
||||
quitDialogKeymap->addAction(act);
|
||||
|
||||
act = new Action("NO", _("No"));
|
||||
act->setCustomEngineActionEvent(kActionNo);
|
||||
act->addDefaultInputMapping("n");
|
||||
act->addDefaultInputMapping("JOY_B");
|
||||
quitDialogKeymap->addAction(act);
|
||||
|
||||
Common::KeymapArray keymaps(3);
|
||||
|
||||
keymaps[0] = engineKeymap;
|
||||
keymaps[1] = gameKeymap;
|
||||
keymaps[2] = quitDialogKeymap;
|
||||
|
||||
quitDialogKeymap->setEnabled(false);
|
||||
|
||||
return keymaps;
|
||||
}
|
||||
|
||||
#if PLUGIN_ENABLED_DYNAMIC(CHAMBER)
|
||||
REGISTER_PLUGIN_DYNAMIC(CHAMBER, PLUGIN_TYPE_ENGINE, ChamberMetaEngine);
|
||||
#else
|
||||
REGISTER_PLUGIN_STATIC(CHAMBER, PLUGIN_TYPE_ENGINE, ChamberMetaEngine);
|
||||
#endif
|
||||
42
engines/chamber/module.mk
Normal file
42
engines/chamber/module.mk
Normal file
@@ -0,0 +1,42 @@
|
||||
MODULE := engines/chamber
|
||||
|
||||
MODULE_OBJS := \
|
||||
anim.o \
|
||||
bkbuff.o \
|
||||
cga.o \
|
||||
chamber.o \
|
||||
cursor.o \
|
||||
decompr.o \
|
||||
dialog.o \
|
||||
ifgm.o \
|
||||
input.o \
|
||||
invent.o \
|
||||
kult.o \
|
||||
menu.o \
|
||||
metaengine.o \
|
||||
portrait.o \
|
||||
print.o \
|
||||
r_pers.o \
|
||||
r_puzzl.o \
|
||||
r_sprit.o \
|
||||
r_texts.o \
|
||||
resdata.o \
|
||||
room.o \
|
||||
savegame.o \
|
||||
script.o \
|
||||
sound.o \
|
||||
timer.o
|
||||
|
||||
MODULE_DIRS += \
|
||||
engines/chamber
|
||||
|
||||
# This module can be built as a plugin
|
||||
ifeq ($(ENABLE_CHAMBER), DYNAMIC_PLUGIN)
|
||||
PLUGIN := 1
|
||||
endif
|
||||
|
||||
# Include common rules
|
||||
include $(srcdir)/rules.mk
|
||||
|
||||
# Detection objects
|
||||
DETECT_OBJS += $(MODULE)/detection.o
|
||||
376
engines/chamber/portrait.cpp
Normal file
376
engines/chamber/portrait.cpp
Normal file
@@ -0,0 +1,376 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/portrait.h"
|
||||
#include "chamber/resdata.h"
|
||||
#include "chamber/room.h"
|
||||
#include "chamber/cga.h"
|
||||
#include "chamber/script.h"
|
||||
#include "chamber/dialog.h"
|
||||
#include "chamber/input.h"
|
||||
#include "chamber/sound.h"
|
||||
#include "chamber/ifgm.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
|
||||
extern uint16 cpu_speed_delay;
|
||||
|
||||
byte *cur_image_pixels;
|
||||
byte cur_image_size_w;
|
||||
byte cur_image_size_h;
|
||||
byte cur_image_coords_x;
|
||||
byte cur_image_coords_y;
|
||||
uint16 cur_image_offs;
|
||||
uint16 cur_image_end;
|
||||
byte cur_image_idx;
|
||||
byte cur_image_anim1;
|
||||
byte cur_image_anim2;
|
||||
uint16 cur_frame_width;
|
||||
|
||||
typedef struct persframe_t {
|
||||
byte height;
|
||||
byte width;
|
||||
byte topbot; /*border and fill colors*/
|
||||
byte fill;
|
||||
byte left;
|
||||
byte right;
|
||||
} persframe_t;
|
||||
|
||||
persframe_t pers_frames[] = {
|
||||
{65, 16, 0xFF, 0xAA, 0xEA, 0xAB},
|
||||
{70, 16, 0xFF, 0xAA, 0xEA, 0xAB},
|
||||
{65, 17, 0xFF, 0xAA, 0xEA, 0xAB},
|
||||
{75, 17, 0xFF, 0xAA, 0xEA, 0xAB},
|
||||
{85, 16, 0xFF, 0xAA, 0xEA, 0xAB},
|
||||
{47, 13, 0xFF, 0, 0xC0, 3},
|
||||
{65, 18, 0xFF, 0xAA, 0xEA, 0xAB},
|
||||
{38, 11, 0xFF, 0, 0xC0, 3},
|
||||
{27, 34, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
void makePortraitFrame(byte index, byte *target) {
|
||||
uint16 i;
|
||||
persframe_t *pframe = &pers_frames[index];
|
||||
*target++ = pframe->height;
|
||||
*target++ = pframe->width;
|
||||
cur_frame_width = pframe->width;
|
||||
memset(target, pframe->topbot, pframe->width);
|
||||
target += pframe->width;
|
||||
for (i = 0; i < pframe->height - 2; i++) {
|
||||
*target++ = pframe->left;
|
||||
memset(target, pframe->fill, pframe->width - 2);
|
||||
target += pframe->width - 2;
|
||||
*target++ = pframe->right;
|
||||
}
|
||||
memset(target, pframe->topbot, pframe->width);
|
||||
}
|
||||
|
||||
/*TODO: move this to CGA ?*/
|
||||
/*
|
||||
Superimpose source sprite data over target image data
|
||||
*/
|
||||
void mergeImageAndSpriteData(byte *target, int16 pitch, byte *source, uint16 w, uint16 h) {
|
||||
uint16 x;
|
||||
while (h--) {
|
||||
for (x = 0; x < w; x++) {
|
||||
byte m = *source++;
|
||||
*target &= m;
|
||||
*target++ |= *source++;
|
||||
}
|
||||
target -= w;
|
||||
target += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Superimpose horizontally-flipped source sprite data over target image data
|
||||
*/
|
||||
void mergeImageAndSpriteDataFlip(byte *target, int16 pitch, byte *source, uint16 w, uint16 h) {
|
||||
uint16 x;
|
||||
target += w - 1;
|
||||
while (h--) {
|
||||
for (x = 0; x < w; x++) {
|
||||
byte m = cga_pixel_flip[*source++];
|
||||
*target &= m;
|
||||
*target |= cga_pixel_flip[*source++];
|
||||
target -= 1;
|
||||
}
|
||||
target += w;
|
||||
target += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Build portrait from multiple pers sprites
|
||||
*/
|
||||
byte *loadPortrait(byte **pinfo, byte *end) {
|
||||
while (*pinfo != end) {
|
||||
byte index;
|
||||
uint16 flags;
|
||||
int16 pitch;
|
||||
byte *buffer, *sprite;
|
||||
byte sprw, sprh;
|
||||
|
||||
index = *((*pinfo)++);
|
||||
flags = *((*pinfo)++);
|
||||
flags |= (*((*pinfo)++)) << 8;
|
||||
buffer = sprit_load_buffer + 2 + 2 + (flags & 0x3FFF);
|
||||
pitch = cur_frame_width;
|
||||
|
||||
sprite = loadPersSprit(index);
|
||||
sprw = *sprite++;
|
||||
sprh = *sprite++;
|
||||
|
||||
if (flags & 0x8000) { /*vertical flip*/
|
||||
buffer += pitch * (sprh - 1);
|
||||
pitch = -pitch;
|
||||
}
|
||||
if (flags & 0x4000) /*horizontal flip*/
|
||||
mergeImageAndSpriteDataFlip(buffer, pitch, sprite, sprw, sprh);
|
||||
else
|
||||
mergeImageAndSpriteData(buffer, pitch, sprite, sprw, sprh);
|
||||
}
|
||||
return sprit_load_buffer + 2;
|
||||
}
|
||||
|
||||
byte *loadPortraitWithFrame(byte index) {
|
||||
byte *pinfo, *end;
|
||||
pinfo = seekToEntry(icone_data, index, &end);
|
||||
makePortraitFrame(*pinfo++, sprit_load_buffer + 2);
|
||||
return loadPortrait(&pinfo, end);
|
||||
}
|
||||
|
||||
|
||||
#define STATIC_ANIMS_MAX 24
|
||||
|
||||
struct {
|
||||
byte index;
|
||||
byte image;
|
||||
byte x;
|
||||
byte y;
|
||||
byte anim1;
|
||||
byte anim2;
|
||||
} static_anims[] = {
|
||||
{ 24, 13, 35, 10, 4, 5},
|
||||
{ 88, 42, 35, 10, 11, 12},
|
||||
{152, 50, 35, 10, 13, 14},
|
||||
{216, 58, 35, 10, 15, 16},
|
||||
{ 40, 9, 30, 20, 3, 3},
|
||||
{ 48, 1, 35, 20, 1, 2},
|
||||
{ 32, 66, 35, 20, 17, 18},
|
||||
{128, 21, 20, 10, 6, 6},
|
||||
{192, 25, 2, 70, 7, 7},
|
||||
{ 56, 85, 25, 20, 26, 27},
|
||||
{ 64, 74, 56, 85, 23, 23},
|
||||
{ 72, 74, 56, 85, 23, 23},
|
||||
{ 80, 78, 27, 20, 24, 24},
|
||||
{144, 80, 27, 20, 25, 25},
|
||||
{ 96, 100, 27, 20, 29, 29},
|
||||
{104, 92, 27, 20, 28, 28},
|
||||
{112, 100, 27, 20, 29, 53},
|
||||
{224, 96, 27, 20, 48, 48},
|
||||
{232, 92, 27, 20, 47, 47},
|
||||
{184, 160, 27, 20, 50, 52},
|
||||
{200, 78, 27, 20, 24, 24},
|
||||
{160, 106, 33, 2, 49, 49},
|
||||
{168, 147, 16, 2, 32, 32},
|
||||
{248, 117, 16, 2, 33, 33}
|
||||
};
|
||||
|
||||
byte selectCurrentAnim(byte *x, byte *y, byte *index) {
|
||||
int16 i;
|
||||
byte aniidx = ((pers_t *)(script_vars[kScrPool8_CurrentPers]))->index & ~7;
|
||||
for (i = 0; i < STATIC_ANIMS_MAX; i++) {
|
||||
if (static_anims[i].index == aniidx) {
|
||||
*x = static_anims[i].x;
|
||||
*y = static_anims[i].y;
|
||||
*index = static_anims[i].image;
|
||||
cur_image_anim1 = static_anims[i].anim1;
|
||||
cur_image_anim2 = static_anims[i].anim2;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
warning("SelectCurrentAnim: not found for %d", aniidx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void drawBoxAroundSpot(void) {
|
||||
byte *buffer;
|
||||
uint16 w, h;
|
||||
uint16 ofs;
|
||||
uint16 x, y;
|
||||
|
||||
if (*spot_sprite == 0)
|
||||
return;
|
||||
zone_spots_cur = found_spot;
|
||||
zone_spr_index = script_byte_vars.cur_spot_idx - 1;
|
||||
|
||||
buffer = *spot_sprite;
|
||||
|
||||
h = *(byte *)(buffer + 0);
|
||||
w = *(byte *)(buffer + 1);
|
||||
ofs = *(uint16 *)(buffer + 2);
|
||||
|
||||
/*decode ofs back to x:y*/
|
||||
/*TODO: this is CGA-only!*/
|
||||
y = (ofs & g_vm->_line_offset) ? 1 : 0;
|
||||
ofs &= ~g_vm->_line_offset;
|
||||
x = (ofs % g_vm->_screenBPL) * g_vm->_screenPPB;
|
||||
y += (ofs / g_vm->_screenBPL) * 2;
|
||||
w *= g_vm->_screenPPB; /*TODO: this will overflow on large sprite*/
|
||||
|
||||
cga_DrawVLine(x, y, h - 1, 0, CGA_SCREENBUFFER);
|
||||
cga_DrawHLine(x, y, w - 1, 0, CGA_SCREENBUFFER);
|
||||
cga_DrawVLine(x + w - 1, y, h - 1, 0, CGA_SCREENBUFFER);
|
||||
cga_DrawHLine(x, y + h - 1, w - 1, 0, CGA_SCREENBUFFER);
|
||||
|
||||
cga_RefreshImageData(*spot_sprite);
|
||||
}
|
||||
|
||||
/*Get on-screen image as specified by script to temp buffer and register it with dirty rect of kind 2
|
||||
If rmb is pressed, draw it immediately and return 0
|
||||
*/
|
||||
int16 drawPortrait(byte **desc, byte *x, byte *y, byte *width, byte *height) {
|
||||
byte index;
|
||||
byte xx, yy;
|
||||
byte *image;
|
||||
|
||||
index = *((*desc)++);
|
||||
if (index == 0xFF) {
|
||||
if (script_byte_vars.dirty_rect_kind != 0)
|
||||
return 0;
|
||||
drawBoxAroundSpot();
|
||||
if (!selectCurrentAnim(&xx, &yy, &index))
|
||||
return 0;
|
||||
} else {
|
||||
xx = *((*desc)++);
|
||||
yy = *((*desc)++);
|
||||
}
|
||||
cur_image_coords_x = xx;
|
||||
cur_image_coords_y = yy;
|
||||
cur_image_idx = index;
|
||||
|
||||
image = loadPortraitWithFrame(index - 1);
|
||||
cur_image_size_h = *image++;
|
||||
cur_image_size_w = *image++;
|
||||
cur_image_pixels = image;
|
||||
cur_image_offs = CalcXY_p(cur_image_coords_x, cur_image_coords_y);
|
||||
addDirtyRect(DirtyRectSprite, cur_image_coords_x, cur_image_coords_y, cur_image_size_w, cur_image_size_h, cur_image_offs);
|
||||
|
||||
/*TODO: remove and use only globals?*/
|
||||
*x = cur_image_coords_x;
|
||||
*y = cur_image_coords_y;
|
||||
*width = cur_image_size_w;
|
||||
*height = cur_image_size_h;
|
||||
|
||||
if (right_button) {
|
||||
cga_BlitAndWait(cur_image_pixels, cur_image_size_w, cur_image_size_w, cur_image_size_h, CGA_SCREENBUFFER, cur_image_offs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void playHurtSound() {
|
||||
if (!ifgm_loaded)
|
||||
playSound(144);
|
||||
else
|
||||
playSound(144 + (getRand() / 4) % 4);
|
||||
}
|
||||
|
||||
void blinkWithSound(byte color) {
|
||||
cga_ColorSelect(color);
|
||||
playHurtSound();
|
||||
selectPalette();
|
||||
}
|
||||
|
||||
void blinkToRed(void) {
|
||||
blinkWithSound(0x3C);
|
||||
}
|
||||
|
||||
void blinkToWhite(void) {
|
||||
if (g_vm->getLanguage() == Common::EN_USA)
|
||||
playHurtSound(); /*TODO: play here and later? looks like a bug, original code will trash palette selection if pcspeaker is used*/
|
||||
|
||||
blinkWithSound(0x3F);
|
||||
}
|
||||
|
||||
volatile byte vblank_ticks;
|
||||
|
||||
void waitVBlankTimer(void) {
|
||||
if (g_vm->getLanguage() == Common::EN_USA) {
|
||||
/*A crude attempt to fix the animation speed...*/
|
||||
while (vblank_ticks < 3) ;
|
||||
vblank_ticks = 0;
|
||||
}
|
||||
waitVBlank();
|
||||
}
|
||||
|
||||
void animPortrait(byte layer, byte index, byte delay) {
|
||||
byte *ani, *ani_end;
|
||||
byte temp;
|
||||
|
||||
selectCurrentAnim(&temp, &temp, &temp);
|
||||
|
||||
if (index == 0xFF)
|
||||
index = cur_image_anim1;
|
||||
if (index == 0xFE)
|
||||
index = cur_image_anim2;
|
||||
|
||||
IFGM_PlaySfx(index);
|
||||
|
||||
ani = seekToEntry(anico_data, index - 1, &ani_end);
|
||||
cur_image_pixels = sprit_load_buffer + 2 + 2;
|
||||
|
||||
while (ani != ani_end) {
|
||||
byte kind;
|
||||
byte x, y;
|
||||
byte width, height;
|
||||
uint16 offs;
|
||||
|
||||
byte portrait = *ani++;
|
||||
loadPortraitWithFrame(portrait - 1);
|
||||
if (*ani == 0xFF) {
|
||||
ani++;
|
||||
loadPortrait(&ani, ani + 3);
|
||||
}
|
||||
getDirtyRectAndSetSprite(layer, &kind, &x, &y, &width, &height, &offs);
|
||||
waitVBlank();
|
||||
cga_BlitAndWait(cur_image_pixels, width, width, height, CGA_SCREENBUFFER, offs);
|
||||
waitVBlankTimer();
|
||||
if (delay) {
|
||||
if (ani[-1] == 37) { /*TODO: what is it?*/
|
||||
if (script_byte_vars.extreme_violence)
|
||||
blinkToRed();
|
||||
else
|
||||
blinkToWhite();
|
||||
} else {
|
||||
int16 i;
|
||||
while (delay--) for (i = 0; i < cpu_speed_delay; i++) ; /*TODO: FIXME weak delay*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
55
engines/chamber/portrait.h
Normal file
55
engines/chamber/portrait.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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 CHAMBER_PORTRAIT_H
|
||||
#define CHAMBER_PORTRAIT_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
extern byte *cur_image_pixels;
|
||||
extern byte cur_image_size_w;
|
||||
extern byte cur_image_size_h;
|
||||
extern byte cur_image_coords_x;
|
||||
extern byte cur_image_coords_y;
|
||||
extern uint16 cur_image_offs;
|
||||
extern uint16 cur_image_end;
|
||||
extern byte cur_image_idx;
|
||||
extern byte cur_image_anim1;
|
||||
extern byte cur_image_anim2;
|
||||
extern uint16 cur_frame_width;
|
||||
|
||||
extern volatile byte vblank_ticks;
|
||||
|
||||
int16 drawPortrait(byte **desc, byte *x, byte *y, byte *width, byte *height);
|
||||
void animPortrait(byte layer, byte index, byte delay);
|
||||
|
||||
void drawBoxAroundSpot(void);
|
||||
|
||||
void mergeImageAndSpriteData(byte *target, int16 pitch, byte *source, uint16 w, uint16 h);
|
||||
void mergeImageAndSpriteDataFlip(byte *target, int16 pitch, byte *source, uint16 w, uint16 h);
|
||||
|
||||
void blinkToRed(void);
|
||||
void blinkToWhite(void);
|
||||
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
300
engines/chamber/print.cpp
Normal file
300
engines/chamber/print.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/cga.h"
|
||||
#include "chamber/cursor.h"
|
||||
#include "chamber/dialog.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
|
||||
byte *cur_str_end;
|
||||
|
||||
byte draw_x;
|
||||
byte draw_y;
|
||||
|
||||
/*
|
||||
Calculate number of string's character until whitespace
|
||||
Return current word's characters count and the next word ptr
|
||||
*/
|
||||
byte *calcStringWordWidth(byte *str, uint16 *w) {
|
||||
uint16 ww = 0;
|
||||
byte c;
|
||||
|
||||
if ((*str & 0x3F) == 0) {
|
||||
str++;
|
||||
ww++;
|
||||
}
|
||||
|
||||
while (str != cur_str_end) {
|
||||
if ((*str & 0x3F) == 0)
|
||||
break;
|
||||
ww++;
|
||||
c = *str & 0xC0;
|
||||
if (c != 0) {
|
||||
if (c == 0x40) { /*space?*/
|
||||
str++;
|
||||
break;
|
||||
}
|
||||
ww++;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
|
||||
*w = ww;
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate number of text's words and max word width (in chars)
|
||||
*/
|
||||
void calcStringSize(byte *str, uint16 *w, uint16 *n) {
|
||||
uint16 ww = 0, nw = 0, lw;
|
||||
byte *s = str;
|
||||
do {
|
||||
s = calcStringWordWidth(s, &lw);
|
||||
if (lw > ww)
|
||||
ww = lw;
|
||||
nw += 1;
|
||||
} while (s != cur_str_end);
|
||||
*w = ww;
|
||||
*n = nw;
|
||||
}
|
||||
|
||||
/*
|
||||
Calculate number of text's lines with respect to set max width
|
||||
If a line is longer, wrap it to the next line
|
||||
*/
|
||||
uint16 calcTextLines(byte *str) {
|
||||
uint16 lines = 1;
|
||||
uint16 w, left = char_draw_max_width;
|
||||
while (str != cur_str_end) {
|
||||
str = calcStringWordWidth(str, &w);
|
||||
if (left > w) {
|
||||
left = left - w - 1;
|
||||
} else {
|
||||
lines++;
|
||||
left = char_draw_max_width - w - 1;
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
/*; translate 1-bit raster (4 columns per byte) to 4 2-bit color pixels*/
|
||||
byte chars_color_bonw[] = {0xFF, 0xFC, 0xF3, 0xF0, 0xCF, 0xCC, 0xC3, 0xC0, 0x3F, 0x3C, 0x33, 0x30, 0x0F, 0x0C, 3, 0}; /*black on white*/
|
||||
byte chars_color_bonc[] = {0x55, 0x54, 0x51, 0x50, 0x45, 0x44, 0x41, 0x40, 0x15, 0x14, 0x11, 0x10, 5, 4, 1, 0}; /*black on cyan*/
|
||||
byte chars_color_wonb[] = { 0, 3, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F, 0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF}; /*white on black*/
|
||||
byte chars_color_wonc[] = {0x55, 0x57, 0x5D, 0x5F, 0x75, 0xF7, 0x7D, 0x7F, 0xD5, 0xD7, 0xDD, 0xDF, 0xF5, 0xF7, 0xFD, 0xFF}; /*white on cyan*/
|
||||
|
||||
void printStringPad(uint16 w, byte *target) {
|
||||
while (w--)
|
||||
cga_PrintChar(0, target);
|
||||
}
|
||||
|
||||
byte *printWord(byte *str, byte *target) {
|
||||
byte c, f;
|
||||
if ((*str & 0x3F) == 0)
|
||||
goto skip_1st;
|
||||
while (str != cur_str_end) {
|
||||
f = *str;
|
||||
c = f & 0x3F;
|
||||
if (c == 0) {
|
||||
if ((f & 0xC0) == 0)
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
cga_PrintChar(c, target);
|
||||
|
||||
skip_1st:
|
||||
;
|
||||
f = *str & 0xC0;
|
||||
str++;
|
||||
if (f) {
|
||||
if (f == 0x80)
|
||||
cga_PrintChar(0x25, target);
|
||||
else if (f != 0x40)
|
||||
cga_PrintChar(0x21, target);
|
||||
else
|
||||
return str;
|
||||
}
|
||||
}
|
||||
string_ended = 1;
|
||||
return str;
|
||||
}
|
||||
|
||||
byte *printStringLine(byte *str, uint16 *left, byte *target) {
|
||||
uint16 mw = char_draw_max_width;
|
||||
for (;;) {
|
||||
uint16 w;
|
||||
calcStringWordWidth(str, &w);
|
||||
if (mw < w)
|
||||
break;
|
||||
mw -= w;
|
||||
str = printWord(str, target);
|
||||
if (string_ended || (mw == 0))
|
||||
break;
|
||||
mw--;
|
||||
cga_PrintChar(0, target);
|
||||
}
|
||||
*left = mw;
|
||||
return str;
|
||||
}
|
||||
|
||||
byte *printStringPadded(byte *str, byte *target) {
|
||||
uint16 w;
|
||||
|
||||
if (g_vm->getLanguage() != Common::EN_USA) {
|
||||
uint16 n;
|
||||
calcStringSize(str, &w, &n);
|
||||
if (w + 2 >= char_draw_max_width)
|
||||
char_draw_max_width = w + 2;
|
||||
}
|
||||
|
||||
str = printStringLine(str, &w, target);
|
||||
if (w != 0)
|
||||
printStringPad(w, target);
|
||||
return str;
|
||||
}
|
||||
|
||||
void printStringCentered(byte *str, byte *target) {
|
||||
byte pad = 0;
|
||||
uint16 ww = 0, lw;
|
||||
byte *s = str;
|
||||
do {
|
||||
s = calcStringWordWidth(s, &lw);
|
||||
ww += lw;
|
||||
} while (s != cur_str_end);
|
||||
|
||||
pad = (char_draw_max_width - ww) / 2;
|
||||
if (pad) {
|
||||
char_draw_max_width -= pad;
|
||||
printStringPad(pad, target);
|
||||
}
|
||||
string_ended = 0; /*TODO: move me elsewhere*/
|
||||
printStringPadded(str, target);
|
||||
}
|
||||
|
||||
void cga_DrawTextBox(byte *msg, byte *target) {
|
||||
uint16 x, y, w, i;
|
||||
uint16 ww, nw;
|
||||
|
||||
char_xlat_table = chars_color_bonc;
|
||||
|
||||
if (g_vm->getLanguage() == Common::EN_USA) {
|
||||
calcStringSize(msg, &ww, &nw);
|
||||
if (ww >= char_draw_max_width)
|
||||
char_draw_max_width = ww;
|
||||
}
|
||||
|
||||
x = draw_x * 4;
|
||||
y = draw_y;
|
||||
w = (char_draw_max_width + 2) * 4 - 2;
|
||||
|
||||
cga_DrawHLine(x + 2, y, w - 2, 0, target); /*box top*/
|
||||
for (i = 0; i < 3; i++)
|
||||
cga_DrawHLine(x + 1, y + 1 + i, w, 1, target); /*top margin*/
|
||||
cga_DrawVLine(x, y + 2, 2, 0, target); /*left top corner 1*/
|
||||
cga_DrawVLine(x + 1, y + 1, 1, 0, target); /*left top corner 2*/
|
||||
cga_DrawVLine(x + w, y + 1, 1, 0, target); /*right top corner 1*/
|
||||
cga_DrawVLine(x + w + 1, y + 2, 2, 0, target); /*right top corner 2*/
|
||||
|
||||
char_draw_coords_y = draw_y + 4;
|
||||
string_ended = 0;
|
||||
do {
|
||||
char_draw_coords_x = draw_x;
|
||||
cga_PrintChar(0x3B, target);
|
||||
msg = printStringPadded(msg, target);
|
||||
cga_PrintChar(0x3C, target);
|
||||
char_draw_coords_y += 6;
|
||||
} while (!string_ended);
|
||||
|
||||
x = draw_x * 4;
|
||||
y = char_draw_coords_y;
|
||||
cga_DrawHLine(x + 1, y, w, 1, target); /*bottom margin*/
|
||||
cga_DrawVLine(x + 1, y, 1, 0, target); /*bottom left corner 1*/
|
||||
cga_DrawHLine(x + 2, y + 1, w - 2, 0, target); /*box bottom*/
|
||||
cga_DrawVLine(x + 1, y, 1, 0, target); /*TODO: duplicated?*/
|
||||
cga_DrawVLine(x + w, y, 1, 0, target); /*bottom right corner*/
|
||||
}
|
||||
|
||||
void drawMessage(byte *msg, byte *target) {
|
||||
uint16 x, y;
|
||||
uint16 w, h;
|
||||
calcStringSize(msg, &w, &h);
|
||||
char_draw_max_width = (h < 5) ? (w + 2) : 20;
|
||||
char_draw_max_height = calcTextLines(msg) * 6 + 7;
|
||||
|
||||
x = cursor_x / 4;
|
||||
if (x < 9)
|
||||
x = 9;
|
||||
if (x + char_draw_max_width + 2 >= 73)
|
||||
x = 73 - (char_draw_max_width + 2);
|
||||
|
||||
y = cursor_y;
|
||||
if (y + char_draw_max_height >= 200)
|
||||
y = 200 - char_draw_max_height;
|
||||
|
||||
draw_x = x;
|
||||
draw_y = y;
|
||||
|
||||
cga_BackupImageReal(CalcXY_p(x, y), char_draw_max_width + 2, char_draw_max_height); /*backup orig. screen data*/
|
||||
cga_DrawTextBox(msg, target); /*draw box with text*/
|
||||
promptWait(); /*wait keypress*/
|
||||
cga_RestoreBackupImage(target); /*restore screen data*/
|
||||
}
|
||||
|
||||
#if 1
|
||||
void debugMessage(char *msg, ...) {
|
||||
int16 i;
|
||||
byte c;
|
||||
byte m[256];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, msg);
|
||||
vsnprintf((char *)m, 256, msg, ap);
|
||||
va_end(ap);
|
||||
|
||||
for (i = 0; m[i]; i++) {
|
||||
c = m[i];
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
c = 0x21 + (c - 'A');
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
c = 0x21 + (c - 'a');
|
||||
else if (c >= '0' && c <= '9')
|
||||
c = 0x10 + (c - '0');
|
||||
else if (c == ' ')
|
||||
c = 0x20;
|
||||
else if (c == '\n')
|
||||
c = 0x00;
|
||||
else
|
||||
c = 0x1F;
|
||||
m[i] = c;
|
||||
}
|
||||
|
||||
cur_str_end = m + i;
|
||||
|
||||
drawMessage(m, frontbuffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // End of namespace Chamber
|
||||
48
engines/chamber/print.h
Normal file
48
engines/chamber/print.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* 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 CHAMBER_PRINT_H
|
||||
#define CHAMBER_PRINT_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
extern byte *cur_str_end;
|
||||
|
||||
extern byte draw_x;
|
||||
extern byte draw_y;
|
||||
|
||||
extern byte chars_color_bonw[];
|
||||
extern byte chars_color_bonc[];
|
||||
extern byte chars_color_wonb[];
|
||||
extern byte chars_color_wonc[];
|
||||
|
||||
void printStringCentered(byte *str, byte *target);
|
||||
byte *printStringPadded(byte *str, byte *target);
|
||||
|
||||
void drawMessage(byte *msg, byte *target);
|
||||
|
||||
void cga_DrawTextBox(byte *msg, byte *target);
|
||||
|
||||
void calcStringSize(byte *str, uint16 *w, uint16 *n);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
34
engines/chamber/r_pers.cpp
Normal file
34
engines/chamber/r_pers.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
#include "chamber/resdata.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
|
||||
byte pers1_data[RES_PERS1_MAX];
|
||||
byte pers2_data[RES_PERS2_MAX];
|
||||
|
||||
byte desci_data[RES_DESCI_MAX];
|
||||
byte diali_data[RES_DIALI_MAX];
|
||||
|
||||
} // End of namespace Chamber
|
||||
29
engines/chamber/r_puzzl.cpp
Normal file
29
engines/chamber/r_puzzl.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
#include "chamber/resdata.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
byte puzzl_data[RES_PUZZL_MAX];
|
||||
|
||||
} // End of namespace Chamber
|
||||
29
engines/chamber/r_sprit.cpp
Normal file
29
engines/chamber/r_sprit.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
#include "chamber/resdata.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
byte sprit_data[RES_SPRIT_MAX];
|
||||
|
||||
} // End of namespace Chamber
|
||||
31
engines/chamber/r_texts.cpp
Normal file
31
engines/chamber/r_texts.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
#include "chamber/resdata.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
|
||||
byte vepci_data[RES_VEPCI_MAX];
|
||||
byte motsi_data[RES_MOTSI_MAX];
|
||||
|
||||
} // End of namespace Chamber
|
||||
302
engines/chamber/resdata.cpp
Normal file
302
engines/chamber/resdata.cpp
Normal file
@@ -0,0 +1,302 @@
|
||||
/* 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/file.h"
|
||||
|
||||
#include "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/resdata.h"
|
||||
#include "chamber/decompr.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
extern void askDisk2(void);
|
||||
extern int16 loadSplash(const char *filename);
|
||||
|
||||
/*
|
||||
Get bank entry
|
||||
TODO: port SeekToString to this routine
|
||||
*/
|
||||
byte *seekToEntry(byte *bank, uint16 num, byte **end) {
|
||||
byte len;
|
||||
byte *p = bank;
|
||||
|
||||
while (num--) {
|
||||
len = *p;
|
||||
p += len;
|
||||
}
|
||||
len = *p;
|
||||
*end = p + len;
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
byte *seekToEntryW(byte *bank, uint16 num, byte **end) {
|
||||
uint16 len;
|
||||
byte *p = bank;
|
||||
|
||||
while (num--) {
|
||||
len = p[0] | (p[1] << 8);
|
||||
p += len;
|
||||
}
|
||||
len = p[0] | (p[1] << 8);
|
||||
*end = p + len;
|
||||
return p + 2;
|
||||
}
|
||||
|
||||
uint16 loadFile(const char *filename, byte *buffer) {
|
||||
Common::File in;
|
||||
|
||||
in.open(filename);
|
||||
|
||||
if (!in.isOpen())
|
||||
return 0;
|
||||
|
||||
return in.read(buffer, 0xFFFF0);
|
||||
}
|
||||
|
||||
uint16 saveFile(char *filename, byte *buffer, uint16 size) {
|
||||
warning("STUB: SaveFile(%s, buffer, %d)", filename, size);
|
||||
return 0;
|
||||
#if 0
|
||||
int16 f;
|
||||
int16 wlen;
|
||||
f = open(filename, O_RDONLY | O_BINARY);
|
||||
if (f == -1)
|
||||
return 0;
|
||||
wlen = write(f, buffer, size);
|
||||
close(f);
|
||||
if (wlen == -1)
|
||||
return 0;
|
||||
return (uint16)wlen;
|
||||
#endif
|
||||
}
|
||||
|
||||
int16 loadFilesList(ResEntry_t *entries) {
|
||||
int16 i;
|
||||
for (i = 0; entries[i].name[0] != '$'; i++) {
|
||||
if (!loadFile(entries[i].name, (byte *)entries[i].buffer))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
byte *arpla_data = NULL;
|
||||
byte *aleat_data = NULL;
|
||||
byte *icone_data = NULL;
|
||||
byte *souco_data = NULL;
|
||||
byte *carpc_data = NULL;
|
||||
byte *souri_data = NULL;
|
||||
byte *templ_data = NULL;
|
||||
byte *mursm_data = NULL;
|
||||
byte *gauss_data = NULL;
|
||||
byte *lutin_data = NULL;
|
||||
byte *anima_data = NULL;
|
||||
byte *anico_data = NULL;
|
||||
byte *zones_data = NULL;
|
||||
|
||||
ResEntry_tp res_static[] = {
|
||||
{"ARPLA.BIN", &arpla_data},
|
||||
{"ALEAT.BIN", &aleat_data},
|
||||
{"ICONE.BIN", &icone_data},
|
||||
{"SOUCO.BIN", &souco_data},
|
||||
{"CARPC.BIN", &carpc_data},
|
||||
{"SOURI.BIN", &souri_data},
|
||||
{"TEMPL.BIN", &templ_data},
|
||||
{"MURSM.BIN", &mursm_data},
|
||||
{"GAUSS.BIN", &gauss_data},
|
||||
{"LUTIN.BIN", &lutin_data},
|
||||
{"ANIMA.BIN", &anima_data},
|
||||
{"ANICO.BIN", &anico_data},
|
||||
{"ZONES.BIN", &zones_data},
|
||||
{"$", NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
Load resident data files. Original game has all these data files embedded in the executable.
|
||||
NB! Static data includes the font file, don't use any text print routines before it's loaded.
|
||||
*/
|
||||
int16 loadStaticData() {
|
||||
Common::File pxi;
|
||||
|
||||
if (g_vm->getLanguage() == Common::EN_USA)
|
||||
pxi.open("kult1.pxi");
|
||||
else
|
||||
pxi.open("ere.pxi");
|
||||
|
||||
uint numMods = pxi.readUint16BE();
|
||||
uint modBase = 2 + numMods * 4;
|
||||
|
||||
uint32 *modOffs = new uint32[numMods];
|
||||
|
||||
for (uint i = 0; i < numMods; i++)
|
||||
modOffs[i] = modBase + pxi.readUint32BE();
|
||||
|
||||
// So far, take only resource 0. Additional selection is required
|
||||
uint32 modOfs = modOffs[0];
|
||||
pxi.seek(modOfs);
|
||||
|
||||
uint32 modPsize = pxi.readUint32BE();
|
||||
uint32 modUsize = pxi.readUint32BE();
|
||||
|
||||
byte *modData = new byte[modPsize];
|
||||
|
||||
pxi.read(modData, modPsize);
|
||||
|
||||
warning("Module %d : at 0x%6X, psize = %6d, usize = %6d", 0, modOfs, modPsize, modUsize);
|
||||
|
||||
byte *rawData = new byte[modUsize];
|
||||
g_vm->_pxiData = rawData;
|
||||
|
||||
uint32 rawSize = decompress(modData, rawData);
|
||||
warning("decoded to %d bytes", rawSize);
|
||||
|
||||
delete[] modData;
|
||||
|
||||
if (rawData[0] != 'M' || rawData[1] != 'Z')
|
||||
error("Module decompressed, but is not an EXE file");
|
||||
|
||||
uint16 hdrparas = READ_LE_UINT16(rawData + 8);
|
||||
uint32 off = hdrparas * 16;
|
||||
|
||||
warning("hdrparas: 0x%x, off: 0x%x", hdrparas, off);
|
||||
|
||||
const char *firstRes = "ARPLA.";
|
||||
int32 resOffs = -1;
|
||||
|
||||
for (uint i = off; i < rawSize; i++)
|
||||
if (!strncmp((char *)rawData + i, firstRes, strlen(firstRes))) {
|
||||
resOffs = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (resOffs == -1)
|
||||
error("No internal resources table found");
|
||||
|
||||
warning("Found resources table at 0x%X", resOffs - off);
|
||||
|
||||
while (rawData[resOffs] != '$') {
|
||||
Common::String resName((char *)rawData + resOffs);
|
||||
|
||||
resOffs += MAX(resName.size() + 1, 10U); // work around malformed resource entry in the US release
|
||||
|
||||
uint16 reso = READ_LE_UINT16(rawData + resOffs);
|
||||
resOffs += 2;
|
||||
uint16 ress = READ_LE_UINT16(rawData + resOffs);
|
||||
resOffs += 2;
|
||||
|
||||
warning("%s : %X", resName.c_str(), ress * 16 + reso);
|
||||
|
||||
int i;
|
||||
for (i = 0; res_static[i].name[0] != '$'; i++) { // Yeah, linear search
|
||||
if (!strcmp(res_static[i].name, resName.c_str())) {
|
||||
*res_static[i].buffer = rawData + off + ress * 16 + reso;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (res_static[i].name[0] == '$')
|
||||
warning("loadStaticData(): Extra resource %s", resName.c_str());
|
||||
}
|
||||
|
||||
// And now check that everything was loaded
|
||||
bool missing = false;
|
||||
for (int i = 0; res_static[i].name[0] != '$'; i++) {
|
||||
if (*res_static[i].buffer == NULL) {
|
||||
warning("loadStaticData(): Resource %s is not present", res_static[i].name);
|
||||
missing = true;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] modOffs;
|
||||
|
||||
return !missing;
|
||||
}
|
||||
|
||||
ResEntry_t res_texts[] = {
|
||||
{"VEPCI.BIN", vepci_data},
|
||||
{"MOTSI.BIN", motsi_data},
|
||||
{"$", NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
Load strings data (commands/names)
|
||||
*/
|
||||
int16 loadVepciData() {
|
||||
return loadFilesList(res_texts);
|
||||
}
|
||||
|
||||
int16 loadFond(void) {
|
||||
return loadSplash("FOND.BIN");
|
||||
}
|
||||
|
||||
ResEntry_t res_sprites[] = {
|
||||
{"PUZZL.BIN", puzzl_data},
|
||||
{"SPRIT.BIN", sprit_data},
|
||||
{"$", NULL}
|
||||
};
|
||||
|
||||
int16 loadSpritesData(void) {
|
||||
return loadFilesList(res_sprites);
|
||||
}
|
||||
|
||||
ResEntry_t res_person[] = {
|
||||
{"PERS1.BIN", pers1_data},
|
||||
{"PERS2.BIN", pers2_data},
|
||||
{"$", NULL}
|
||||
};
|
||||
|
||||
int16 loadPersData(void) {
|
||||
/*Originally it tries to load pers1 + pers2 as a single contiguos resource, if have enough memory*/
|
||||
/*If memory is low, necessary file is loaded on demand, according to requested bank resource index*/
|
||||
/*Here we load both parts to their own memory buffers then select one in LoadPersSprit()*/
|
||||
return loadFilesList(res_person);
|
||||
}
|
||||
|
||||
ResEntry_t res_desci[] = {
|
||||
{"DESCI.BIN", desci_data},
|
||||
{"$", NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
Load strings data (obj. descriptions)
|
||||
*/
|
||||
int16 loadDesciData(void) {
|
||||
while (!loadFilesList(res_desci))
|
||||
askDisk2();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ResEntry_t res_diali[] = {
|
||||
{"DIALI.BIN", diali_data},
|
||||
{"$", NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
Load strings data (dialogs)
|
||||
*/
|
||||
int16 loadDialiData(void) {
|
||||
while (!loadFilesList(res_diali))
|
||||
askDisk2();
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
109
engines/chamber/resdata.h
Normal file
109
engines/chamber/resdata.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/* 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 CHAMBER_RESDATA_H
|
||||
#define CHAMBER_RESDATA_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
typedef struct ResEntry_t {
|
||||
char name[5 + 1 + 3 + 1];
|
||||
void *buffer;
|
||||
} ResEntry_t;
|
||||
|
||||
typedef struct ResEntry_tp {
|
||||
char name[5 + 1 + 3 + 1];
|
||||
byte **buffer;
|
||||
} ResEntry_tp;
|
||||
|
||||
/* Max resource file size among all languages */
|
||||
#define RES_ALEAT_MAX 256
|
||||
#define RES_ANICO_MAX 667
|
||||
#define RES_ANIMA_MAX 2046
|
||||
#define RES_ARPLA_MAX 7910
|
||||
#define RES_CARPC_MAX 384
|
||||
#define RES_GAUSS_MAX 1449
|
||||
#define RES_ICONE_MAX 2756
|
||||
#define RES_LUTIN_MAX 2800
|
||||
#define RES_MURSM_MAX 76
|
||||
#define RES_SOUCO_MAX 424
|
||||
#define RES_SOURI_MAX 1152
|
||||
#define RES_TEMPL_MAX 27337
|
||||
#define RES_ZONES_MAX 9014
|
||||
#define RES_PUZZL_MAX 45671
|
||||
#define RES_SPRIT_MAX 23811
|
||||
#define RES_PERS1_MAX 14294
|
||||
#define RES_PERS2_MAX 10587
|
||||
#define RES_DESCI_MAX 10515
|
||||
#define RES_DIALI_MAX 9636
|
||||
#define RES_MOTSI_MAX 1082
|
||||
#define RES_VEPCI_MAX 1345
|
||||
|
||||
extern byte vepci_data[];
|
||||
extern byte motsi_data[];
|
||||
|
||||
extern byte puzzl_data[];
|
||||
extern byte sprit_data[];
|
||||
|
||||
extern byte pers1_data[];
|
||||
extern byte pers2_data[];
|
||||
|
||||
extern byte desci_data[];
|
||||
extern byte diali_data[];
|
||||
|
||||
extern byte *arpla_data;
|
||||
extern byte *aleat_data;
|
||||
extern byte *carpc_data;
|
||||
extern byte *icone_data;
|
||||
extern byte *souco_data;
|
||||
extern byte *souri_data;
|
||||
extern byte *templ_data;
|
||||
extern byte *mursm_data;
|
||||
extern byte *gauss_data;
|
||||
extern byte *lutin_data;
|
||||
extern byte *anima_data;
|
||||
extern byte *anico_data;
|
||||
extern byte *zones_data;
|
||||
|
||||
byte *seekToEntry(byte *bank, uint16 num, byte **end);
|
||||
byte *seekToEntryW(byte *bank, uint16 num, byte **end);
|
||||
|
||||
uint16 loadFile(const char *filename, byte *buffer);
|
||||
uint16 saveFile(char *filename, byte *buffer, uint16 size);
|
||||
int16 loadFilesList(ResEntry_t *entries);
|
||||
|
||||
int16 loadStaticData(void);
|
||||
int16 loadFond(void);
|
||||
int16 loadSpritesData(void);
|
||||
int16 loadPersData(void);
|
||||
|
||||
extern ResEntry_t res_texts[];
|
||||
int16 loadVepciData(void);
|
||||
|
||||
extern ResEntry_t res_desci[];
|
||||
int16 loadDesciData(void);
|
||||
|
||||
extern ResEntry_t res_diali[];
|
||||
int16 loadDialiData(void);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
1918
engines/chamber/room.cpp
Normal file
1918
engines/chamber/room.cpp
Normal file
File diff suppressed because it is too large
Load Diff
237
engines/chamber/room.h
Normal file
237
engines/chamber/room.h
Normal file
@@ -0,0 +1,237 @@
|
||||
/* 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 CHAMBER_ROOM_H
|
||||
#define CHAMBER_ROOM_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
#define SPOTFLG_1 0x01
|
||||
#define SPOTFLG_2 0x02
|
||||
#define SPOTFLG_8 0x08
|
||||
#define SPOTFLG_10 0x10
|
||||
#define SPOTFLG_20 0x20
|
||||
#define SPOTFLG_40 0x40
|
||||
#define SPOTFLG_80 0x80
|
||||
|
||||
/*static room object*/
|
||||
/*TODO: manipulated from script, do not change*/
|
||||
#include "common/pack-start.h"
|
||||
typedef struct spot_t {
|
||||
byte sx;
|
||||
byte ex;
|
||||
byte sy;
|
||||
byte ey;
|
||||
byte flags;
|
||||
byte hint;
|
||||
uint16 command;
|
||||
} spot_t;
|
||||
#include "common/pack-end.h"
|
||||
|
||||
#define PERSFLAGS 0xF0
|
||||
#define PERSFLG_10 0x10
|
||||
#define PERSFLG_20 0x20
|
||||
#define PERSFLG_40 0x40
|
||||
#define PERSFLG_80 0x80
|
||||
|
||||
/*person*/
|
||||
/*TODO: manipulated from script, do not change*/
|
||||
#include "common/pack-start.h"
|
||||
typedef struct pers_t {
|
||||
byte area; /*location*/
|
||||
byte flags; /*flags in bits 7..4 and room index in bits 3..0*/
|
||||
byte name; /*name index*/
|
||||
byte index; /*animations index (in lutins_table) in bits 7..3 , spot index in bits 2..0*/
|
||||
byte item; /*inventory item index (1-based)*/
|
||||
} pers_t;
|
||||
#include "common/pack-end.h"
|
||||
|
||||
#define ANIMFLG_USESPOT 0x80
|
||||
|
||||
typedef struct animdesc_t {
|
||||
byte index; /*flag in bit 7, animation index in bits 6..0*/
|
||||
union {
|
||||
struct {
|
||||
byte x, y;
|
||||
} coords;
|
||||
uint16 desc;
|
||||
} params;
|
||||
} animdesc_t;
|
||||
|
||||
typedef struct vortanims_t {
|
||||
byte room;
|
||||
animdesc_t field_1;
|
||||
animdesc_t field_4;
|
||||
animdesc_t field_7;
|
||||
animdesc_t field_A;
|
||||
} vortanims_t;
|
||||
|
||||
typedef struct turkeyanims_t {
|
||||
byte room;
|
||||
animdesc_t field_1;
|
||||
animdesc_t field_4;
|
||||
} turkeyanims_t;
|
||||
|
||||
extern byte scratch_mem1[8010];
|
||||
extern byte *scratch_mem2;
|
||||
|
||||
extern rect_t room_bounds_rect;
|
||||
|
||||
extern byte last_object_hint;
|
||||
extern byte object_hint;
|
||||
extern byte command_hint;
|
||||
extern byte last_command_hint;
|
||||
|
||||
extern uint16 next_protozorqs_ticks;
|
||||
extern uint16 next_vorts_ticks;
|
||||
extern uint16 next_vorts_cmd;
|
||||
extern uint16 next_turkey_ticks;
|
||||
extern uint16 next_turkey_cmd;
|
||||
|
||||
#define MAX_SPRITES 16
|
||||
|
||||
extern byte *sprites_list[MAX_SPRITES];
|
||||
|
||||
#define MAX_DOORS 5
|
||||
|
||||
extern byte *doors_list[MAX_DOORS];
|
||||
|
||||
extern byte zone_palette;
|
||||
|
||||
extern spot_t *zone_spots;
|
||||
extern spot_t *zone_spots_end;
|
||||
extern spot_t *zone_spots_cur;
|
||||
|
||||
extern vortanims_t vortsanim_list[];
|
||||
extern vortanims_t *vortanims_ptr;
|
||||
|
||||
extern turkeyanims_t turkeyanim_list[];
|
||||
extern turkeyanims_t *turkeyanims_ptr;
|
||||
extern pers_t *aspirant_ptr;
|
||||
extern spot_t *aspirant_spot;
|
||||
extern spot_t *found_spot;
|
||||
extern byte **spot_sprite;
|
||||
|
||||
extern byte *lutin_mem;
|
||||
|
||||
extern byte skip_zone_transition;
|
||||
|
||||
extern byte in_de_profundis;
|
||||
|
||||
extern byte zone_name;
|
||||
extern byte room_hint_bar_width;
|
||||
extern byte zone_spr_index;
|
||||
extern byte zone_obj_count;
|
||||
extern byte room_hint_bar_coords_x;
|
||||
extern byte room_hint_bar_coords_y;
|
||||
|
||||
extern uint16 drops_cleanup_time;
|
||||
|
||||
extern const byte patrol_route[];
|
||||
extern const byte *timed_seq_ptr;
|
||||
|
||||
typedef struct thewalldoor_t {
|
||||
byte height;
|
||||
byte width;
|
||||
uint16 pitch;
|
||||
uint16 offs;
|
||||
byte *pixels;
|
||||
} thewalldoor_t;
|
||||
|
||||
extern thewalldoor_t the_wall_doors[2];
|
||||
|
||||
int16 isInRect(byte x, byte y, rect_t *rect);
|
||||
int16 isCursorInRect(rect_t *rect);
|
||||
void selectSpotCursor(void);
|
||||
|
||||
void checkHotspots(byte m, byte v);
|
||||
|
||||
void animateSpot(const animdesc_t *info);
|
||||
byte *loadPuzzlToScratch(byte index);
|
||||
|
||||
void drawObjectHint(void);
|
||||
void showObjectHint(byte *target);
|
||||
void drawCommandHint(void);
|
||||
void showCommandHint(byte *target);
|
||||
|
||||
void drawCharacterSprite(byte spridx, byte x, byte y, byte *target);
|
||||
char drawZoneAniSprite(rect_t *rect, uint16 index, byte *target);
|
||||
|
||||
void drawHintsAndCursor(byte *target);
|
||||
|
||||
void drawTheWallDoors(void);
|
||||
void mergeSpritesData(byte *target, uint16 pitch, byte *source, uint16 w, uint16 h);
|
||||
void mergeSpritesDataFlip(byte *target, uint16 pitch, byte *source, uint16 w, uint16 h);
|
||||
|
||||
void refreshSpritesData(void);
|
||||
void blitSpritesToBackBuffer(void);
|
||||
byte *backupSpotImage(spot_t *spot, byte **spotback, byte *buffer);
|
||||
void backupSpotsImages(void);
|
||||
|
||||
void selectPalette(void);
|
||||
void selectSpecificPalette(byte index);
|
||||
|
||||
byte findSpotByFlags(byte mask, byte value);
|
||||
byte selectPerson(byte offset);
|
||||
|
||||
void findPerson(void);
|
||||
|
||||
void beforeChangeZone(byte index);
|
||||
void drawRoomItemsIndicator(void);
|
||||
void drawRoomStaticObject(byte *aptr, byte *rx, byte *ry, byte *rw, byte *rh);
|
||||
void drawRoomStatics(void);
|
||||
void redrawRoomStatics(byte index, byte y_step);
|
||||
void drawPersons(void);
|
||||
void refreshZone(void);
|
||||
void changeZone(byte index);
|
||||
|
||||
void drawSpots(byte *target);
|
||||
void animateSpots(byte *target);
|
||||
|
||||
byte findInitialSpot(void);
|
||||
void animRoomDoorOpen(byte index);
|
||||
void animRoomDoorClose(byte index);
|
||||
|
||||
uint16 getPuzzlSprite(byte index, byte x, byte y, uint16 *w, uint16 *h, uint16 *ofs);
|
||||
|
||||
void bounceCurrentItem(byte flags, byte y);
|
||||
|
||||
void backupScreenOfSpecialRoom(void);
|
||||
void restoreScreenOfSpecialRoom(void);
|
||||
|
||||
void theWallPhase3_DoorOpen1(void);
|
||||
void theWallPhase0_DoorOpen2(void);
|
||||
void theWallPhase1_DoorClose1(void);
|
||||
void theWallPhase2_DoorClose2(void);
|
||||
|
||||
void prepareAspirant(void);
|
||||
void prepareVorts(void);
|
||||
void prepareTurkey(void);
|
||||
|
||||
void updateProtozorqs(void);
|
||||
void checkGameTimeLimit(void);
|
||||
void cleanupDroppedItems(void);
|
||||
|
||||
void resetAllPersons(void);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
699
engines/chamber/savegame.cpp
Normal file
699
engines/chamber/savegame.cpp
Normal file
@@ -0,0 +1,699 @@
|
||||
/* 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 "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/savegame.h"
|
||||
#include "chamber/resdata.h"
|
||||
#include "chamber/script.h"
|
||||
#include "chamber/cga.h"
|
||||
#include "chamber/room.h"
|
||||
#include "chamber/dialog.h"
|
||||
#include "chamber/room.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
#if 0
|
||||
static const char restart_name[] = "CLEARx.BIN";
|
||||
|
||||
#ifdef VERSION_USA
|
||||
static const char savegame_name[] = "SCENACx.BIN";
|
||||
#else
|
||||
static const char savegame_name[] = "SCENAx.BIN";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_USA
|
||||
|
||||
#define CGA_SAVE_BEG_OFS 0x769B
|
||||
#define CGA_SAVE_END_OFS 0x9EDA
|
||||
|
||||
#define CGA_SAVE_WORD_VARS_OFS 0x79C1
|
||||
#define CGA_SAVE_BYTE_VARS_OFS 0x7B33
|
||||
#define CGA_SAVE_INVENTORY_OFS 0x7762
|
||||
#define CGA_SAVE_ZONES_OFS 0x7BA4
|
||||
#define CGA_SAVE_PERS_OFS 0x78E2
|
||||
#define CGA_SAVE_STACK_OFS 0x76DF
|
||||
#define CGA_SAVE_SPRITES_OFS 0x5264
|
||||
#define CGA_SAVE_SPRLIST_OFS 0x76AD
|
||||
#define CGA_SAVE_SPRBUFF_OFS 0x4C68
|
||||
#define CGA_SAVE_ARPLA_OFS 0x26F6
|
||||
#define CGA_SAVE_SCRSTACK_OFS 0x76DF
|
||||
#define CGA_SAVE_TEMPL_OFS 0x1AC7
|
||||
#define CGA_SAVE_VORTANIMS_OFS 0xA7B7
|
||||
#define CGA_SAVE_TURKEYANIMS_OFS 0xA8FC
|
||||
#define CGA_SAVE_TIMEDSEQ_OFS 0xA96E
|
||||
|
||||
#else
|
||||
|
||||
#define CGA_SAVE_BEG_OFS 0x751E
|
||||
#define CGA_SAVE_END_OFS 0x9D5D
|
||||
|
||||
#define CGA_SAVE_WORD_VARS_OFS 0x7844
|
||||
#define CGA_SAVE_BYTE_VARS_OFS 0x79B6
|
||||
#define CGA_SAVE_INVENTORY_OFS 0x75E5
|
||||
#define CGA_SAVE_ZONES_OFS 0x7A27
|
||||
#define CGA_SAVE_PERS_OFS 0x7765
|
||||
#define CGA_SAVE_STACK_OFS 0x7562
|
||||
#define CGA_SAVE_SPRITES_OFS 0x5264
|
||||
#define CGA_SAVE_SPRLIST_OFS 0x7530
|
||||
#define CGA_SAVE_SPRBUFF_OFS 0x4C68
|
||||
#define CGA_SAVE_ARPLA_OFS 0x26F6
|
||||
#define CGA_SAVE_SCRSTACK_OFS 0x7562
|
||||
#define CGA_SAVE_TEMPL_OFS 0x182C
|
||||
#define CGA_SAVE_VORTANIMS_OFS 0xA609
|
||||
#define CGA_SAVE_TURKEYANIMS_OFS 0xA74E
|
||||
#define CGA_SAVE_TIMEDSEQ_OFS 0xA7C0
|
||||
|
||||
#endif
|
||||
|
||||
#define SAVEADDR(value, base, nativesize, origsize, origbase) \
|
||||
((value) ? LE16(((((byte*)(value)) - (byte*)(base)) / nativesize) * origsize + origbase) : 0)
|
||||
|
||||
#define LOADADDR(value, base, nativesize, origsize, origbase) \
|
||||
((value) ? ((((LE16(value)) - (origbase)) / origsize) * nativesize + (byte*)base) : 0)
|
||||
|
||||
#define WRITE(buffer, size) \
|
||||
wlen = write(f, buffer, size); if(wlen != size) goto error;
|
||||
|
||||
#define READ(buffer, size) \
|
||||
rlen = read(f, buffer, size); if(rlen != size) goto error;
|
||||
|
||||
#if 0
|
||||
int16 readSaveData(int16 f, int16 clean) {
|
||||
int16 rlen;
|
||||
uint16 zero = 0;
|
||||
byte *p;
|
||||
int16 i;
|
||||
|
||||
#define BYTES(buffer, size) READ(buffer, size)
|
||||
#define UBYTE(variable) { byte temp_v; READ(&temp_v, 1); variable = temp_v; }
|
||||
#define SBYTE(variable) { int8 temp_v; READ(&temp_v, 1); variable = temp_v; }
|
||||
#define USHORT(variable) { uint16 temp_v; READ(&temp_v, 2); variable = temp_v; }
|
||||
#define SSHORT(variable) { int16 temp_v; READ(&temp_v, 2); variable = temp_v; }
|
||||
#define POINTER(variable, base, nativesize, origsize, origbase) \
|
||||
{ int16 temp_v; READ(&temp_v, 2); variable = LOADADDR(temp_v, base, nativesize, origsize, origbase); }
|
||||
|
||||
/*script_vars pointers*/
|
||||
POINTER(script_vars[ScrPool0_WordVars0], &script_word_vars, 2, 2, CGA_SAVE_WORD_VARS_OFS);
|
||||
POINTER(script_vars[ScrPool1_WordVars1], &script_word_vars, 2, 2, CGA_SAVE_WORD_VARS_OFS);
|
||||
POINTER(script_vars[ScrPool2_ByteVars], &script_byte_vars, 1, 1, CGA_SAVE_BYTE_VARS_OFS);
|
||||
POINTER(script_vars[ScrPool3_CurrentItem], inventory_items, sizeof(item_t), sizeof(item_t), CGA_SAVE_INVENTORY_OFS);
|
||||
POINTER(script_vars[ScrPool4_ZoneSpots], zones_data, 1, 1, CGA_SAVE_ZONES_OFS);
|
||||
POINTER(script_vars[ScrPool5_Persons], pers_list, 1, 1, CGA_SAVE_PERS_OFS);
|
||||
POINTER(script_vars[ScrPool6_Inventory], inventory_items, sizeof(item_t), sizeof(item_t), CGA_SAVE_INVENTORY_OFS);
|
||||
POINTER(script_vars[ScrPool7_Zapstiks], inventory_items, sizeof(item_t), sizeof(item_t), CGA_SAVE_INVENTORY_OFS);
|
||||
POINTER(script_vars[ScrPool8_CurrentPers], pers_list, 1, 1, CGA_SAVE_PERS_OFS);
|
||||
|
||||
/* sprites_list */
|
||||
for (i = 0; i < MAX_SPRITES; i++) {
|
||||
POINTER(sprites_list[i], scratch_mem1, 1, 1, CGA_SAVE_SPRITES_OFS);
|
||||
}
|
||||
|
||||
/* doors list */
|
||||
for (i = 0; i < MAX_DOORS; i++) {
|
||||
POINTER(doors_list[i], arpla_data, 1, 1, CGA_SAVE_ARPLA_OFS);
|
||||
}
|
||||
|
||||
/* zone_spots */
|
||||
POINTER((byte *)zone_spots, zones_data, 1, 1, CGA_SAVE_ZONES_OFS);
|
||||
|
||||
/* zone_spots_end */
|
||||
POINTER((byte *)zone_spots_end, zones_data, 1, 1, CGA_SAVE_ZONES_OFS);
|
||||
|
||||
/* zone_spots_cur */
|
||||
POINTER((byte *)zone_spots_cur, zones_data, 1, 1, CGA_SAVE_ZONES_OFS);
|
||||
|
||||
/* script_stack_ptr */
|
||||
/*TODO: FIX ME: original stack works in reverse order (from higher address to lower)*/
|
||||
POINTER((byte *)script_stack_ptr, script_stack, 1, 1, CGA_SAVE_SCRSTACK_OFS);
|
||||
|
||||
/* script_stack */
|
||||
/*TODO: FIX ME: original stack works in reverse order (from higher address to lower)*/
|
||||
for (i = 0; i < 5 * 2; i++) {
|
||||
POINTER(script_stack[i], templ_data, 1, 1, CGA_SAVE_TEMPL_OFS);
|
||||
}
|
||||
|
||||
/* padding */
|
||||
USHORT(zero);
|
||||
|
||||
/* vort_ptr */
|
||||
POINTER((byte *)vort_ptr, pers_list, 1, 1, CGA_SAVE_PERS_OFS);
|
||||
|
||||
/* vortanims_ptr */
|
||||
POINTER((byte *)vortanims_ptr, vortsanim_list, 1, 1, CGA_SAVE_VORTANIMS_OFS);
|
||||
|
||||
/* turkeyanims_ptr */
|
||||
POINTER((byte *)turkeyanims_ptr, turkeyanim_list, 1, 1, CGA_SAVE_TURKEYANIMS_OFS);
|
||||
|
||||
/* aspirant_ptr */
|
||||
POINTER((byte *)aspirant_ptr, pers_list, 1, 1, CGA_SAVE_PERS_OFS);
|
||||
|
||||
/* aspirant_spot */
|
||||
POINTER((byte *)aspirant_spot, zones_data, 1, 1, CGA_SAVE_ZONES_OFS);
|
||||
|
||||
/* found_spot */
|
||||
POINTER((byte *)found_spot, zones_data, 1, 1, CGA_SAVE_ZONES_OFS);
|
||||
|
||||
/* spot_sprite */
|
||||
POINTER((byte *)spot_sprite, sprites_list, sizeof(sprites_list[0]), 2, CGA_SAVE_SPRLIST_OFS);
|
||||
|
||||
/* timed_seq_ptr */
|
||||
POINTER(timed_seq_ptr, patrol_route, 1, 1, CGA_SAVE_TIMEDSEQ_OFS);
|
||||
|
||||
/* keep_sp */
|
||||
/* TODO: how to save it? but it's probably useless anyway */
|
||||
USHORT(zero);
|
||||
|
||||
/* unused ptr to script code */
|
||||
p = templ_data;
|
||||
POINTER(p, templ_data, 1, 1, CGA_SAVE_TEMPL_OFS);
|
||||
|
||||
/* padding */
|
||||
UBYTE(zero);
|
||||
|
||||
/* the wall doors state */
|
||||
for (i = 0; i < 2; i++) {
|
||||
thewalldoor_t *door = &the_wall_doors[i];
|
||||
UBYTE(door->height);
|
||||
UBYTE(door->width);
|
||||
USHORT(door->pitch);
|
||||
USHORT(door->offs);
|
||||
POINTER(door->pixels, sprit_load_buffer, 1, 1, CGA_SAVE_SPRBUFF_OFS);
|
||||
}
|
||||
|
||||
/* wait_delta */
|
||||
UBYTE(wait_delta);
|
||||
|
||||
/* padding */
|
||||
UBYTE(zero);
|
||||
|
||||
/* dirty_rects */
|
||||
for (i = 0; i < MAX_DIRTY_RECT; i++) {
|
||||
dirty_rect_t *dr = &dirty_rects[i];
|
||||
UBYTE(dr->kind);
|
||||
USHORT(dr->offs);
|
||||
UBYTE(dr->height);
|
||||
UBYTE(dr->width);
|
||||
UBYTE(dr->y);
|
||||
UBYTE(dr->x);
|
||||
}
|
||||
|
||||
/* inventory_items */
|
||||
for (i = 0; i < MAX_INV_ITEMS; i++) {
|
||||
/*TODO: properly serialize this*/
|
||||
BYTES(&inventory_items[i], sizeof(item_t));
|
||||
}
|
||||
|
||||
/* room_hint_bar_coords_y */
|
||||
UBYTE(room_hint_bar_coords_y);
|
||||
|
||||
/* room_hint_bar_coords_x */
|
||||
UBYTE(room_hint_bar_coords_x);
|
||||
|
||||
/* padding */
|
||||
USHORT(zero);
|
||||
|
||||
/* fight_pers_ofs */
|
||||
/* NB! raw offset */
|
||||
USHORT(fight_pers_ofs);
|
||||
|
||||
/* pers_list */
|
||||
for (i = 0; i < PERS_MAX; i++) {
|
||||
/*TODO: properly serialize this*/
|
||||
BYTES(&pers_list[i], sizeof(pers_t));
|
||||
}
|
||||
|
||||
/* drops_cleanup_time */
|
||||
USHORT(drops_cleanup_time);
|
||||
|
||||
/* room_bounds_rect */
|
||||
/*TODO: properly serialize this*/
|
||||
BYTES(&room_bounds_rect, sizeof(rect_t));
|
||||
|
||||
/* last_object_hint */
|
||||
UBYTE(last_object_hint);
|
||||
|
||||
/* object_hint */
|
||||
UBYTE(object_hint);
|
||||
|
||||
/* command_hint */
|
||||
UBYTE(command_hint);
|
||||
|
||||
/* zone_name */
|
||||
UBYTE(zone_name);
|
||||
|
||||
/* room_hint_bar_width */
|
||||
UBYTE(room_hint_bar_width);
|
||||
|
||||
/* last_command_hint */
|
||||
UBYTE(last_command_hint);
|
||||
|
||||
/* zone_spr_index */
|
||||
UBYTE(zone_spr_index);
|
||||
|
||||
/* zone_obj_count */
|
||||
UBYTE(zone_obj_count);
|
||||
|
||||
/* padding */
|
||||
USHORT(zero);
|
||||
|
||||
/* padding */
|
||||
UBYTE(zero);
|
||||
|
||||
/* in_de_profundis */
|
||||
UBYTE(in_de_profundis);
|
||||
|
||||
/* script_word_vars */
|
||||
BYTES(&script_word_vars, sizeof(script_word_vars));
|
||||
|
||||
/* menu_commands_12 */
|
||||
BYTES(menu_commands_12, sizeof(menu_commands_12));
|
||||
|
||||
/* menu_commands_22 */
|
||||
BYTES(menu_commands_22, sizeof(menu_commands_22));
|
||||
|
||||
/* menu_commands_24 */
|
||||
BYTES(menu_commands_24, sizeof(menu_commands_24));
|
||||
|
||||
/* menu_commands_23 */
|
||||
BYTES(menu_commands_23, sizeof(menu_commands_23));
|
||||
|
||||
/* next_vorts_cmd */
|
||||
USHORT(next_vorts_cmd);
|
||||
|
||||
/* next_vorts_ticks */
|
||||
USHORT(next_vorts_ticks);
|
||||
|
||||
/* next_turkey_cmd */
|
||||
USHORT(next_turkey_cmd);
|
||||
|
||||
/* next_turkey_ticks */
|
||||
USHORT(next_turkey_ticks);
|
||||
|
||||
/* next_protozorqs_ticks */
|
||||
USHORT(next_protozorqs_ticks);
|
||||
|
||||
/* padding */
|
||||
for (i = 0; i < 7; i++) USHORT(zero);
|
||||
|
||||
/* script_byte_vars */
|
||||
BYTES(&script_byte_vars, sizeof(script_byte_vars));
|
||||
|
||||
/* zones_data */
|
||||
BYTES(zones_data, RES_ZONES_MAX);
|
||||
|
||||
if (clean == 0) {
|
||||
/* screen data */
|
||||
BYTES(backbuffer, 0x3FFF);
|
||||
|
||||
CGA_BackBufferToRealFull();
|
||||
SelectPalette();
|
||||
|
||||
BYTES(backbuffer, 0x3FFF);
|
||||
}
|
||||
|
||||
#undef BYTES
|
||||
#undef UBYTE
|
||||
#undef SBYTE
|
||||
#undef USHORT
|
||||
#undef SSHORT
|
||||
#undef POINTER
|
||||
|
||||
return 0;
|
||||
|
||||
error:;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int16 writeSaveData(int16 f, int16 clean) {
|
||||
int16 wlen;
|
||||
uint16 zero = 0;
|
||||
byte *p;
|
||||
int16 i;
|
||||
|
||||
#define BYTES(buffer, size) WRITE(buffer, size)
|
||||
#define UBYTE(variable) { byte temp_v = variable; WRITE(&temp_v, 1); }
|
||||
#define SBYTE(variable) { int8 temp_v = variable; WRITE(&temp_v, 1); }
|
||||
#define USHORT(variable) { uint16 temp_v = variable; WRITE(&temp_v, 2); }
|
||||
#define SSHORT(variable) { int16 temp_v = variable; WRITE(&temp_v, 2); }
|
||||
#define POINTER(variable, base, nativesize, origsize, origbase) \
|
||||
{ int16 temp_v = SAVEADDR(variable, base, nativesize, origsize, origbase); WRITE(&temp_v, 2); }
|
||||
|
||||
/*script_vars pointers*/
|
||||
POINTER(script_vars[ScrPool0_WordVars0], &script_word_vars, 2, 2, CGA_SAVE_WORD_VARS_OFS);
|
||||
POINTER(script_vars[ScrPool1_WordVars1], &script_word_vars, 2, 2, CGA_SAVE_WORD_VARS_OFS);
|
||||
POINTER(script_vars[ScrPool2_ByteVars], &script_byte_vars, 1, 1, CGA_SAVE_BYTE_VARS_OFS);
|
||||
POINTER(script_vars[ScrPool3_CurrentItem], inventory_items, sizeof(item_t), sizeof(item_t), CGA_SAVE_INVENTORY_OFS);
|
||||
POINTER(script_vars[ScrPool4_ZoneSpots], zones_data, 1, 1, CGA_SAVE_ZONES_OFS);
|
||||
POINTER(script_vars[ScrPool5_Persons], pers_list, 1, 1, CGA_SAVE_PERS_OFS);
|
||||
POINTER(script_vars[ScrPool6_Inventory], inventory_items, sizeof(item_t), sizeof(item_t), CGA_SAVE_INVENTORY_OFS);
|
||||
POINTER(script_vars[ScrPool7_Zapstiks], inventory_items, sizeof(item_t), sizeof(item_t), CGA_SAVE_INVENTORY_OFS);
|
||||
POINTER(script_vars[ScrPool8_CurrentPers], pers_list, 1, 1, CGA_SAVE_PERS_OFS);
|
||||
|
||||
/* sprites_list */
|
||||
for (i = 0; i < MAX_SPRITES; i++) {
|
||||
POINTER(sprites_list[i], scratch_mem1, 1, 1, CGA_SAVE_SPRITES_OFS);
|
||||
}
|
||||
|
||||
/* doors list */
|
||||
for (i = 0; i < MAX_DOORS; i++) {
|
||||
POINTER(doors_list[i], arpla_data, 1, 1, CGA_SAVE_ARPLA_OFS);
|
||||
}
|
||||
|
||||
/* zone_spots */
|
||||
POINTER(zone_spots, zones_data, 1, 1, CGA_SAVE_ZONES_OFS);
|
||||
|
||||
/* zone_spots_end */
|
||||
POINTER(zone_spots_end, zones_data, 1, 1, CGA_SAVE_ZONES_OFS);
|
||||
|
||||
/* zone_spots_cur */
|
||||
POINTER(zone_spots_cur, zones_data, 1, 1, CGA_SAVE_ZONES_OFS);
|
||||
|
||||
/* script_stack_ptr */
|
||||
/*TODO: FIX ME: original stack works in reverse order (from higher address to lower)*/
|
||||
POINTER(script_stack_ptr, script_stack, 1, 1, CGA_SAVE_SCRSTACK_OFS);
|
||||
|
||||
/* script_stack */
|
||||
/*TODO: FIX ME: original stack works in reverse order (from higher address to lower)*/
|
||||
for (i = 0; i < 5 * 2; i++) {
|
||||
POINTER(script_stack[i], templ_data, 1, 1, CGA_SAVE_TEMPL_OFS);
|
||||
}
|
||||
|
||||
/* padding */
|
||||
USHORT(zero);
|
||||
|
||||
/* vort_ptr */
|
||||
POINTER(vort_ptr, pers_list, 1, 1, CGA_SAVE_PERS_OFS);
|
||||
|
||||
/* vortanims_ptr */
|
||||
POINTER(vortanims_ptr, vortsanim_list, 1, 1, CGA_SAVE_VORTANIMS_OFS);
|
||||
|
||||
/* turkeyanims_ptr */
|
||||
POINTER(turkeyanims_ptr, turkeyanim_list, 1, 1, CGA_SAVE_TURKEYANIMS_OFS);
|
||||
|
||||
/* aspirant_ptr */
|
||||
POINTER(aspirant_ptr, pers_list, 1, 1, CGA_SAVE_PERS_OFS);
|
||||
|
||||
/* aspirant_spot */
|
||||
POINTER(aspirant_spot, zones_data, 1, 1, CGA_SAVE_ZONES_OFS);
|
||||
|
||||
/* found_spot */
|
||||
POINTER(found_spot, zones_data, 1, 1, CGA_SAVE_ZONES_OFS);
|
||||
|
||||
/* spot_sprite */
|
||||
POINTER(spot_sprite, sprites_list, sizeof(sprites_list[0]), 2, CGA_SAVE_SPRLIST_OFS);
|
||||
|
||||
/* timed_seq_ptr */
|
||||
POINTER(timed_seq_ptr, patrol_route, 1, 1, CGA_SAVE_TIMEDSEQ_OFS);
|
||||
|
||||
/* keep_sp */
|
||||
/* TODO: how to save it? but it's probably useless anyway */
|
||||
USHORT(zero);
|
||||
|
||||
/* unused ptr to script code */
|
||||
p = templ_data;
|
||||
POINTER(p, templ_data, 1, 1, CGA_SAVE_TEMPL_OFS);
|
||||
|
||||
/* padding */
|
||||
UBYTE(zero);
|
||||
|
||||
/* the wall doors state */
|
||||
for (i = 0; i < 2; i++) {
|
||||
thewalldoor_t *door = &the_wall_doors[i];
|
||||
UBYTE(door->height);
|
||||
UBYTE(door->width);
|
||||
USHORT(door->pitch);
|
||||
USHORT(door->offs);
|
||||
POINTER(door->pixels, sprit_load_buffer, 1, 1, CGA_SAVE_SPRBUFF_OFS);
|
||||
}
|
||||
|
||||
/* wait_delta */
|
||||
UBYTE(wait_delta);
|
||||
|
||||
/* padding */
|
||||
UBYTE(zero);
|
||||
|
||||
/* dirty_rects */
|
||||
for (i = 0; i < MAX_DIRTY_RECT; i++) {
|
||||
dirty_rect_t *dr = &dirty_rects[i];
|
||||
UBYTE(dr->kind);
|
||||
USHORT(dr->offs);
|
||||
UBYTE(dr->height);
|
||||
UBYTE(dr->width);
|
||||
UBYTE(dr->y);
|
||||
UBYTE(dr->x);
|
||||
}
|
||||
|
||||
/* inventory_items */
|
||||
for (i = 0; i < MAX_INV_ITEMS; i++) {
|
||||
/*TODO: properly serialize this*/
|
||||
BYTES(&inventory_items[i], sizeof(item_t));
|
||||
}
|
||||
|
||||
/* room_hint_bar_coords_y */
|
||||
UBYTE(room_hint_bar_coords_y);
|
||||
|
||||
/* room_hint_bar_coords_x */
|
||||
UBYTE(room_hint_bar_coords_x);
|
||||
|
||||
/* padding */
|
||||
USHORT(zero);
|
||||
|
||||
/* fight_pers_ofs */
|
||||
/* NB! raw offset */
|
||||
USHORT(fight_pers_ofs);
|
||||
|
||||
/* pers_list */
|
||||
for (i = 0; i < PERS_MAX; i++) {
|
||||
/*TODO: properly serialize this*/
|
||||
BYTES(&pers_list[i], sizeof(pers_t));
|
||||
}
|
||||
|
||||
/* drops_cleanup_time */
|
||||
USHORT(drops_cleanup_time);
|
||||
|
||||
/* room_bounds_rect */
|
||||
/*TODO: properly serialize this*/
|
||||
BYTES(&room_bounds_rect, sizeof(rect_t));
|
||||
|
||||
/* last_object_hint */
|
||||
UBYTE(last_object_hint);
|
||||
|
||||
/* object_hint */
|
||||
UBYTE(object_hint);
|
||||
|
||||
/* command_hint */
|
||||
UBYTE(command_hint);
|
||||
|
||||
/* zone_name */
|
||||
UBYTE(zone_name);
|
||||
|
||||
/* room_hint_bar_width */
|
||||
UBYTE(room_hint_bar_width);
|
||||
|
||||
/* last_command_hint */
|
||||
UBYTE(last_command_hint);
|
||||
|
||||
/* zone_spr_index */
|
||||
UBYTE(zone_spr_index);
|
||||
|
||||
/* zone_obj_count */
|
||||
UBYTE(zone_obj_count);
|
||||
|
||||
/* padding */
|
||||
USHORT(zero);
|
||||
|
||||
/* padding */
|
||||
UBYTE(zero);
|
||||
|
||||
/* in_de_profundis */
|
||||
UBYTE(in_de_profundis);
|
||||
|
||||
/* script_word_vars */
|
||||
BYTES(&script_word_vars, sizeof(script_word_vars));
|
||||
|
||||
/* menu_commands_12 */
|
||||
BYTES(menu_commands_12, sizeof(menu_commands_12));
|
||||
|
||||
/* menu_commands_22 */
|
||||
BYTES(menu_commands_22, sizeof(menu_commands_22));
|
||||
|
||||
/* menu_commands_24 */
|
||||
BYTES(menu_commands_24, sizeof(menu_commands_24));
|
||||
|
||||
/* menu_commands_23 */
|
||||
BYTES(menu_commands_23, sizeof(menu_commands_23));
|
||||
|
||||
/* next_vorts_cmd */
|
||||
USHORT(next_vorts_cmd);
|
||||
|
||||
/* next_vorts_ticks */
|
||||
USHORT(next_vorts_ticks);
|
||||
|
||||
/* next_turkey_cmd */
|
||||
USHORT(next_turkey_cmd);
|
||||
|
||||
/* next_turkey_ticks */
|
||||
USHORT(next_turkey_ticks);
|
||||
|
||||
/* next_protozorqs_ticks */
|
||||
USHORT(next_protozorqs_ticks);
|
||||
|
||||
/* padding */
|
||||
for (i = 0; i < 7; i++) USHORT(zero);
|
||||
|
||||
/* script_byte_vars */
|
||||
BYTES(&script_byte_vars, sizeof(script_byte_vars));
|
||||
|
||||
/* zones_data */
|
||||
BYTES(zones_data, RES_ZONES_MAX);
|
||||
|
||||
if (clean == 0) {
|
||||
/* screen data */
|
||||
BYTES(frontbuffer, 0x3FFF);
|
||||
BYTES(backbuffer, 0x3FFF);
|
||||
}
|
||||
|
||||
#undef BYTES
|
||||
#undef UBYTE
|
||||
#undef SBYTE
|
||||
#undef USHORT
|
||||
#undef SSHORT
|
||||
#undef POINTER
|
||||
|
||||
return 0;
|
||||
|
||||
error:;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int16 loadScena(void) {
|
||||
warning("STUB: loadScena()");
|
||||
return 1;
|
||||
#if 0
|
||||
int16 f;
|
||||
int16 res;
|
||||
|
||||
script_byte_vars.game_paused = 1;
|
||||
|
||||
f = open(savegame_name, O_RDONLY | O_BINARY);
|
||||
if (f == -1) {
|
||||
script_byte_vars.game_paused = 0;
|
||||
return 1; /*error*/
|
||||
}
|
||||
/*
|
||||
Save format:
|
||||
vars memory (751E-9D5D)
|
||||
frontbuffer (0x3FFF bytes)
|
||||
backbuffer (0x3FFF bytes)
|
||||
*/
|
||||
|
||||
res = ReadSaveData(f, 0);
|
||||
|
||||
if (res == 0) {
|
||||
/*re-initialize sprites list*/
|
||||
BackupSpotsImages();
|
||||
}
|
||||
|
||||
close(f);
|
||||
script_byte_vars.game_paused = 0;
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
int16 saveScena(void) {
|
||||
warning("STUB: saveScena()");
|
||||
return 1;
|
||||
#if 0
|
||||
int16 f;
|
||||
int16 res;
|
||||
|
||||
script_byte_vars.game_paused = 1;
|
||||
BlitSpritesToBackBuffer();
|
||||
command_hint = 100;
|
||||
DrawCommandHint();
|
||||
ShowCommandHint(frontbuffer);
|
||||
|
||||
f = open(savegame_name, O_CREAT | O_WRONLY | O_BINARY);
|
||||
if (f == -1) {
|
||||
script_byte_vars.game_paused = 0;
|
||||
return 1; /*error*/
|
||||
}
|
||||
|
||||
res = WriteSaveData(f, 0);
|
||||
|
||||
close(f);
|
||||
|
||||
if (res != 0)
|
||||
unlink(savegame_name);
|
||||
|
||||
script_byte_vars.game_paused = 0;
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
void saveRestartGame(void) {
|
||||
warning("STUB: saveRestartGame()");
|
||||
#if 0
|
||||
int16 f;
|
||||
|
||||
f = open(restart_name, O_CREAT | O_WRONLY | O_BINARY);
|
||||
if (f == -1) {
|
||||
return; /*error*/
|
||||
}
|
||||
|
||||
WriteSaveData(f, 1);
|
||||
|
||||
close(f);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
//extern jmp_buf restart_jmp;
|
||||
extern void askDisk2(void);
|
||||
|
||||
void restartGame(void) {
|
||||
warning("STUB: restartGame()");
|
||||
g_vm->_shouldRestart = true;
|
||||
|
||||
#if 0
|
||||
int16 f;
|
||||
int16 res;
|
||||
|
||||
for (;; askDisk2()) {
|
||||
f = open(restart_name, O_RDONLY | O_BINARY);
|
||||
if (f != -1) {
|
||||
res = readSaveData(f, 1);
|
||||
close(f);
|
||||
if (res == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
script_byte_vars.cur_spot_flags = 0xFF;
|
||||
script_byte_vars.load_flag = 2;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
34
engines/chamber/savegame.h
Normal file
34
engines/chamber/savegame.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/* 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 CHAMBER_SAVEGAME_H
|
||||
#define CHAMBER_SAVEGAME_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
int16 loadScena(void);
|
||||
int16 saveScena(void);
|
||||
void saveRestartGame(void);
|
||||
void restartGame(void);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
4458
engines/chamber/script.cpp
Normal file
4458
engines/chamber/script.cpp
Normal file
File diff suppressed because it is too large
Load Diff
245
engines/chamber/script.h
Normal file
245
engines/chamber/script.h
Normal file
@@ -0,0 +1,245 @@
|
||||
/* 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 CHAMBER_SCRIPT_H
|
||||
#define CHAMBER_SCRIPT_H
|
||||
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/room.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
enum ScriptPools {
|
||||
kScrPool0_WordVars0,
|
||||
kScrPool1_WordVars1,
|
||||
kScrPool2_ByteVars,
|
||||
kScrPool3_CurrentItem,
|
||||
kScrPool4_ZoneSpots,
|
||||
kScrPool5_Persons,
|
||||
kScrPool6_Inventory,
|
||||
kScrPool7_Zapstiks,
|
||||
kScrPool8_CurrentPers,
|
||||
kScrPools_MAX
|
||||
};
|
||||
|
||||
/*Byte-packed, members accessed from script code by hardcoded offsets*/
|
||||
typedef struct script_byte_vars_t {
|
||||
byte zone_index; /* 0 */
|
||||
byte zone_room; /* 1 */
|
||||
byte last_door; /* 2 */
|
||||
byte cur_spot_idx; /* 3 */
|
||||
byte the_wall_phase; /* 4 */
|
||||
byte prev_zone_index; /* 5 */
|
||||
byte bvar_06; /* 6 */
|
||||
byte bvar_07; /* 7 */
|
||||
byte bvar_08; /* 8 */
|
||||
byte bvar_09; /* 9 */
|
||||
byte bvar_0A; /* A */
|
||||
byte bvar_0B; /* B */
|
||||
byte zone_area; /* C */
|
||||
byte dead_flag; /* D */
|
||||
volatile byte timer_ticks; /* E */
|
||||
byte gauss_phase; /* F */
|
||||
|
||||
byte bvar_10; /* 10 */
|
||||
byte rand_value; /* 11 */
|
||||
byte load_flag; /* 12 */
|
||||
byte spot_m; /* 13 */
|
||||
byte spot_v; /* 14 */
|
||||
byte bvar_15; /* 15 */
|
||||
byte bvar_16; /* 16 */
|
||||
byte bvar_17; /* 17 */
|
||||
byte bvar_18; /* 18 */
|
||||
byte bvar_19; /* 19 */
|
||||
byte bvar_1A; /* 1A */
|
||||
byte bvar_1B; /* 1B */
|
||||
byte bvar_1C; /* 1C */
|
||||
byte bvar_1D; /* 1D */
|
||||
byte bvar_1E; /* 1E */
|
||||
byte bvar_1F; /* 1F */
|
||||
|
||||
byte cur_pers; /* 20 */
|
||||
byte used_commands; /* 21 */
|
||||
byte tries_left; /* 22 */
|
||||
byte inv_item_index; /* 23 */
|
||||
byte bvar_24; /* 24 */
|
||||
byte bvar_25; /* 25 */
|
||||
byte bvar_26; /* 26 */
|
||||
byte bvar_27; /* 27 */
|
||||
byte bvar_28; /* 28 */
|
||||
byte bvar_29; /* 29 */
|
||||
byte bvar_2A; /* 2A */
|
||||
byte hands; /* 2B */
|
||||
byte check_used_commands; /* 2C */
|
||||
byte bvar_2D; /* 2D */
|
||||
byte palette_index; /* 2E */
|
||||
byte bvar_2F; /* 2F */
|
||||
|
||||
byte bvar_30; /* 30 */
|
||||
byte zapstiks_owned; /* 31 */
|
||||
byte bvar_32; /* 32 */
|
||||
byte bvar_33; /* 33 */
|
||||
byte bvar_34; /* 34 */
|
||||
byte skulls_submitted; /* 35 */
|
||||
byte bvar_36; /* 36 */
|
||||
byte bvar_37; /* 37 */
|
||||
byte zone_area_copy; /* 38 */
|
||||
byte aspirant_flags; /* 39 */
|
||||
byte aspirant_pers_ofs;/* 3A */
|
||||
byte steals_count; /* 3B */
|
||||
byte fight_status; /* 3C */
|
||||
byte extreme_violence; /* 3D */
|
||||
byte trade_accepted; /* 3E */
|
||||
byte bvar_3F; /* 3F */
|
||||
|
||||
byte bvar_40; /* 40 */
|
||||
byte bvar_41; /* 41 */
|
||||
byte bvar_42; /* 42 */
|
||||
byte bvar_43; /* 43 */
|
||||
byte dirty_rect_kind; /* 44 */
|
||||
byte bvar_45; /* 45 */
|
||||
byte bvar_46; /* 46 */
|
||||
byte game_paused; /* 47 */
|
||||
byte skull_trader_status;/* 48 */
|
||||
byte cur_spot_flags; /* 49 */
|
||||
byte bvar_4A; /* 4A */
|
||||
byte bvar_4B; /* 4B */
|
||||
byte bvar_4C; /* 4C */
|
||||
byte bvar_4D; /* 4D */
|
||||
byte bvar_4E; /* 4E */
|
||||
byte bvar_4F; /* 4F */
|
||||
|
||||
byte bvar_50; /* 50 */
|
||||
byte bvar_51; /* 51 */
|
||||
byte bvar_52; /* 52 */
|
||||
byte bvar_53; /* 53 */
|
||||
byte bvar_54; /* 54 */
|
||||
byte bvar_55; /* 55 */
|
||||
byte bvar_56; /* 56 */
|
||||
byte need_draw_spots; /* 57 */
|
||||
byte bvar_58; /* 58 */
|
||||
byte bvar_59; /* 59 */
|
||||
byte psy_energy; /* 5A */
|
||||
byte bvar_5B; /* 5B */
|
||||
byte bvar_5C; /* 5C */
|
||||
byte bvar_5D; /* 5D */
|
||||
byte bvar_5E; /* 5E */
|
||||
byte bvar_5F; /* 5F */
|
||||
|
||||
byte bvar_60; /* 60 */
|
||||
byte bvar_61; /* 61 */
|
||||
byte bvar_62; /* 62 */
|
||||
byte bvar_63; /* 63 */
|
||||
byte bvar_64; /* 64 */
|
||||
byte bvar_65; /* 65 */
|
||||
byte bvar_66; /* 66 */
|
||||
byte bvar_67; /* 67 */
|
||||
byte zapstik_stolen; /* 68 */
|
||||
byte bvar_69; /* 69 */
|
||||
byte bvar_6A; /* 6A */
|
||||
byte bvar_6B; /* 6B */
|
||||
byte bvar_6C; /* 6C */
|
||||
byte bvar_6D[4]; /* 6D */
|
||||
} script_byte_vars_t;
|
||||
|
||||
/*2-byte long vars, in BIG-endian order*/
|
||||
typedef struct script_word_vars_t {
|
||||
uint16 psi_cmds[6]; /* 0 */
|
||||
uint16 wvar_0C; /* C */
|
||||
uint16 wvar_0E; /* E */
|
||||
uint16 timer_ticks2; /* 10 */
|
||||
uint16 zone_obj_cmds[15 * 5]; /* 12 */
|
||||
uint16 next_aspirant_cmd; /* A8 */
|
||||
uint16 wvar_AA; /* AA */
|
||||
uint16 wvar_AC; /* AC */
|
||||
uint16 wvar_AE; /* AE */
|
||||
uint16 wvar_B0; /* B0 */
|
||||
uint16 wvar_B2; /* B2 */
|
||||
uint16 wvar_B4; /* B4 */
|
||||
uint16 next_protozorqs_cmd; /* B6 */
|
||||
uint16 wvar_B8; /* B8 */
|
||||
} script_word_vars_t;
|
||||
|
||||
extern void *script_vars[kScrPools_MAX];
|
||||
extern script_word_vars_t script_word_vars;
|
||||
extern script_byte_vars_t script_byte_vars;
|
||||
|
||||
/*Don't trade this item*/
|
||||
#define ITEMFLG_DONTWANT 1
|
||||
#define ITEMFLG_04 0x04
|
||||
#define ITEMFLG_08 0x08
|
||||
/*Skull Trader's item*/
|
||||
#define ITEMFLG_TRADER 0x10
|
||||
/*Aspirant's item*/
|
||||
#define ITEMFLG_ASPIR 0x20
|
||||
/*In a room?*/
|
||||
#define ITEMFLG_ROOM 0x40
|
||||
/*In pocket?*/
|
||||
#define ITEMFLG_OWNED 0x80
|
||||
|
||||
/*TODO: manipulated from script, do not change*/
|
||||
#include "common/pack-start.h"
|
||||
typedef struct item_t {
|
||||
byte flags;
|
||||
byte area; /*item location*/
|
||||
byte sprite; /*item sprite index*/
|
||||
byte name; /*item name index (relative)*/
|
||||
uint16 command; /*TODO: warning! in native format, check if never accessed from scripts*/
|
||||
} item_t;
|
||||
#include "common/pack-end.h"
|
||||
|
||||
#define MAX_INV_ITEMS 63
|
||||
extern item_t inventory_items[MAX_INV_ITEMS];
|
||||
|
||||
#define PERS_MAX 41
|
||||
extern pers_t pers_list[PERS_MAX];
|
||||
|
||||
extern byte *script_stack[5 * 2];
|
||||
extern byte **script_stack_ptr;
|
||||
|
||||
extern pers_t *vort_ptr;
|
||||
|
||||
#define SPECIAL_COMMANDS_MAX 20
|
||||
extern uint16 menu_commands_12[SPECIAL_COMMANDS_MAX];
|
||||
extern uint16 menu_commands_22[SPECIAL_COMMANDS_MAX];
|
||||
extern uint16 menu_commands_24[SPECIAL_COMMANDS_MAX];
|
||||
extern uint16 menu_commands_23[SPECIAL_COMMANDS_MAX];
|
||||
|
||||
extern uint16 fight_pers_ofs;
|
||||
|
||||
extern byte wait_delta;
|
||||
|
||||
extern byte rand_seed;
|
||||
byte getRand(void);
|
||||
uint16 getRandW(void);
|
||||
|
||||
extern uint16 the_command;
|
||||
|
||||
byte *getScriptSubroutine(uint16 index);
|
||||
|
||||
uint16 runCommand(void);
|
||||
uint16 runCommandKeepSp(void);
|
||||
|
||||
uint16 Swap16(uint16 x);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
275
engines/chamber/scrvars.h
Normal file
275
engines/chamber/scrvars.h
Normal file
@@ -0,0 +1,275 @@
|
||||
/* 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 CHAMBER_SCRVARS_H
|
||||
#define CHAMBER_SCRVARS_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
script_byte_vars_t script_byte_vars = {
|
||||
135, /* 0 */
|
||||
0, /* 1 */
|
||||
0, /* 2 */
|
||||
0, /* 3 */
|
||||
0, /* 4 */
|
||||
0, /* 5 */
|
||||
1, /* 6 */
|
||||
0, /* 7 */
|
||||
0, /* 8 */
|
||||
0, /* 9 */
|
||||
0, /* A */
|
||||
0, /* B */
|
||||
0, /* C */
|
||||
0, /* D */
|
||||
0, /* E */
|
||||
0, /* F */
|
||||
|
||||
0, /* 10 */
|
||||
0, /* 11 */
|
||||
0, /* 12 */
|
||||
0, /* 13 */
|
||||
0, /* 14 */
|
||||
0, /* 15 */
|
||||
0, /* 16 */
|
||||
0, /* 17 */
|
||||
0, /* 18 */
|
||||
0, /* 19 */
|
||||
0, /* 1A */
|
||||
0, /* 1B */
|
||||
0, /* 1C */
|
||||
0, /* 1D */
|
||||
0, /* 1E */
|
||||
0, /* 1F */
|
||||
|
||||
0, /* 20 */
|
||||
0, /* 21 */
|
||||
0, /* 22 */
|
||||
0, /* 23 */
|
||||
0xB, /* 24 */
|
||||
0, /* 25 */
|
||||
0, /* 26 */
|
||||
0, /* 27 */
|
||||
0, /* 28 */
|
||||
0, /* 29 */
|
||||
0, /* 2A */
|
||||
0, /* 2B */
|
||||
0, /* 2C */
|
||||
0, /* 2D */
|
||||
0, /* 2E */
|
||||
0, /* 2F */
|
||||
|
||||
0, /* 30 */
|
||||
0, /* 31 */
|
||||
0, /* 32 */
|
||||
0, /* 33 */
|
||||
0, /* 34 */
|
||||
0, /* 35 */
|
||||
0, /* 36 */
|
||||
0, /* 37 */
|
||||
0, /* 38 */
|
||||
0, /* 39 */
|
||||
0, /* 3A */
|
||||
0, /* 3B */
|
||||
0, /* 3C */
|
||||
0, /* 3D */
|
||||
0, /* 3E */
|
||||
0, /* 3F */
|
||||
|
||||
0, /* 40 */
|
||||
0, /* 41 */
|
||||
0, /* 42 */
|
||||
0, /* 43 */
|
||||
0, /* 44 */
|
||||
0, /* 45 */
|
||||
0, /* 46 */
|
||||
1, /* 47 */
|
||||
0, /* 48 */
|
||||
0xFF, /* 49 */
|
||||
0, /* 4A */
|
||||
0, /* 4B */
|
||||
0, /* 4C */
|
||||
0, /* 4D */
|
||||
0, /* 4E */
|
||||
0, /* 4F */
|
||||
|
||||
0, /* 50 */
|
||||
0, /* 51 */
|
||||
0, /* 52 */
|
||||
0, /* 53 */
|
||||
2, /* 54 */
|
||||
1, /* 55 */
|
||||
0, /* 56 */
|
||||
0, /* 57 */
|
||||
0, /* 58 */
|
||||
0, /* 59 */
|
||||
63, /* 5A */
|
||||
0, /* 5B */
|
||||
0, /* 5C */
|
||||
0, /* 5D */
|
||||
0, /* 5E */
|
||||
0, /* 5F */
|
||||
|
||||
0, /* 60 */
|
||||
0, /* 61 */
|
||||
1, /* 62 */
|
||||
0, /* 63 */
|
||||
0, /* 64 */
|
||||
0, /* 65 */
|
||||
0, /* 66 */
|
||||
0, /* 67 */
|
||||
0, /* 68 */
|
||||
0, /* 69 */
|
||||
0, /* 6A */
|
||||
0, /* 6B */
|
||||
0, /* 6C */
|
||||
{0,0,0,0} /* 6D..70 */
|
||||
};
|
||||
|
||||
script_word_vars_t script_word_vars = {
|
||||
{BE(0x9007), BE(0x9007), BE(0x9007), BE(0x9007), BE(0x9007), BE(0x9007)}, /* 00 .. 0B */
|
||||
BE(0), /* 0C */
|
||||
BE(0), /* 0E */
|
||||
BE(0), /* 10 */
|
||||
{0}, /* 12 */
|
||||
BE(0), /* A8 */
|
||||
BE(0), /* AA */
|
||||
BE(0), /* AC */
|
||||
BE(0), /* AE */
|
||||
BE(0), /* B0 */
|
||||
BE(0), /* B2 */
|
||||
BE(0), /* B4 */
|
||||
BE(0), /* B6 */
|
||||
BE(0) /* B8 */
|
||||
};
|
||||
|
||||
item_t inventory_items[MAX_INV_ITEMS] = {
|
||||
{0x00, 0, 26, 109, 0xC0D9}, /* 0 : SKULL */
|
||||
{0x00, 0, 26, 109, 0xC0D9}, /* 1 : SKULL */
|
||||
{0x00, 0, 26, 109, 0xC0D9}, /* 2 : SKULL */
|
||||
{ITEMFLG_TRADER|ITEMFLG_08, 0, 26, 109, 0xC0D9}, /* 3 : SKULL */
|
||||
{0x00, 0, 26, 109, 0xC0D9}, /* 4 : SKULL */
|
||||
{0x00, 0, 32, 104, 0xC0ED}, /* 5 : ROPE */
|
||||
{0x00, 0, 32, 104, 0xC0ED}, /* 6 : ROPE */
|
||||
{0x00, 0, 32, 104, 0xC0ED}, /* 7 : ROPE */
|
||||
{ITEMFLG_TRADER, 0, 32, 104, 0xC0ED}, /* 8 : ROPE */
|
||||
{0x00, 0, 32, 104, 0xC0ED}, /* 9 : ROPE */
|
||||
{0x00, 0, 33, 106, 0xC0EE}, /* 10 : STONE FLY */
|
||||
{0x00, 0, 33, 106, 0xC0EE}, /* 11 : STONE FLY */
|
||||
{0x00, 0, 33, 106, 0xC0EE}, /* 12 : STONE FLY */
|
||||
{ITEMFLG_TRADER, 0, 33, 106, 0xC0EE}, /* 13 : STONE FLY */
|
||||
{0x00, 0, 36, 107, 0xC0EC}, /* 14 : GOBLET */
|
||||
{0x00, 0, 36, 107, 0xC0EC}, /* 15 : GOBLET */
|
||||
{0x00, 0, 36, 107, 0xC0EC}, /* 16 : GOBLET */
|
||||
{ITEMFLG_TRADER, 0, 36, 107, 0xC0EC}, /* 17 : GOBLET */
|
||||
{0x00, 0, 37, 108, 0xC0D3}, /* 18 : DAGGER */
|
||||
{0x00, 0, 37, 108, 0xC0D3}, /* 19 : DAGGER */
|
||||
{0x00, 0, 37, 108, 0xC0D3}, /* 20 : DAGGER */
|
||||
{ITEMFLG_TRADER, 0, 37, 108, 0xC0D3}, /* 21 : DAGGER */
|
||||
{0x00, 0, 39, 105, 0xC0D6}, /* 22 : LANTERN */
|
||||
{0x00, 0, 39, 105, 0xC0D6}, /* 23 : LANTERN */
|
||||
{0x00, 0, 39, 105, 0xC0D6}, /* 24 : LANTERN */
|
||||
{ITEMFLG_TRADER, 0, 39, 105, 0xC0D6}, /* 25 : LANTERN */
|
||||
{ITEMFLG_DONTWANT, 0, 30, 136, 0xC126}, /* 26 : BLUE SPIDER */
|
||||
{ITEMFLG_DONTWANT, 0, 30, 136, 0xC126}, /* 27 : BLUE SPIDER */
|
||||
{ITEMFLG_DONTWANT, 0, 30, 136, 0xC126}, /* 28 : BLUE SPIDER */
|
||||
{ITEMFLG_DONTWANT, 0, 30, 136, 0xC126}, /* 29 : BLUE SPIDER */
|
||||
{ITEMFLG_DONTWANT, 0, 31, 135, 0xC126}, /* 30 : RED SPIDER */
|
||||
{ITEMFLG_DONTWANT, 0, 31, 135, 0xC126}, /* 31 : RED SPIDER */
|
||||
{ITEMFLG_DONTWANT, 0, 31, 135, 0xC126}, /* 32 : RED SPIDER */
|
||||
{ITEMFLG_DONTWANT, 0, 31, 135, 0xC126}, /* 33 : RED SPIDER */
|
||||
{ITEMFLG_DONTWANT, kAreaTheTwins, 38, 120, 0xC132}, /* 34 : DIE */
|
||||
{ITEMFLG_DONTWANT, kAreaTheTwins, 38, 120, 0xC132}, /* 35 : DIE */
|
||||
{ITEMFLG_DONTWANT, kAreaTheTwins, 38, 120, 0xC132}, /* 36 : DIE */
|
||||
{ITEMFLG_DONTWANT, kAreaTheTwins, 38, 120, 0xC132}, /* 37 : DIE */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 38 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 39 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 40 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 41 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 42 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 43 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 44 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 45 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 46 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 47 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 48 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 49 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 50 : ZAPSTIK */
|
||||
{0x00, 0, 28, 132, 0xC0EF}, /* 51 : ZAPSTIK */
|
||||
{0x00, 0, 106, 142, 0xC2C0}, /* 52 : MASK */
|
||||
{0x00, 0, 34, 111, 0xC315}, /* 53 : WHISTLE */
|
||||
{0x00, 0, 35, 110, 0xC27E}, /* 54 : EGG */
|
||||
{0x00, 0, 40, 115, 0xC0D3}, /* 55 : SACRIFICIAL BLADE */
|
||||
{ITEMFLG_ROOM, kAreaRefectory, 58, 117, 0xC127}, /* 56 : CHOPPER */
|
||||
{ITEMFLG_TRADER|ITEMFLG_08|ITEMFLG_DONTWANT, 0, 59, 116, 0xC2BD}, /* 57 : STATUE OF ZORQ */
|
||||
{0x00, 0, 105, 167, 0xC2BD}, /* 58 : STATUE OF SAURA */
|
||||
{0x00, 0, 107, 118, 0xC245}, /* 59 : FLASK */
|
||||
{0x00, 0, 108, 119, 0xC244}, /* 60 : BEAN */
|
||||
{0x35, 0, 35, 110, 0xC27E}, /* 61 : EGG */
|
||||
{0x35, 0, 35, 110, 0xC27E}, /* 62 : EGG */
|
||||
};
|
||||
|
||||
pers_t pers_list[PERS_MAX] = {
|
||||
{ 0, 0, 44, 16, 0}, /* 0 : VORT */
|
||||
{ kAreaTheMastersOrbit3, 0, 49, 25, kItemRope1}, /* 1 : ASPIRANT */
|
||||
{ 0, 0, 49, 89, kItemDagger1}, /* 2 : ASPIRANT */
|
||||
{ 0, 0, 49, 153, kItemGoblet1}, /* 3 : ASPIRANT */
|
||||
{ 0, 0, 49, 217, kItemFly1}, /* 4 : ASPIRANT */
|
||||
{ kAreaPlacatingThePowers, 0, 51, 209, 0}, /* 5 : TURKEY */
|
||||
{ kAreaAblutions, 0, 52, 186, 0}, /* 6 : PRIESTESS */
|
||||
{ kAreaCell1, 0, 52, 202, 0}, /* 7 : PRIESTESS */
|
||||
{ kAreaTheMastersOrbit1, 0, 42, 42, 0}, /* 8 : THE MASTER OF ORDEALS */
|
||||
{ kAreaTheConcourse, 0, 43, 52, 0}, /* 9 : PROTOZORQ */
|
||||
{ kAreaTheConcourse, 0, 43, 52, 0}, /* 10 : PROTOZORQ */
|
||||
{ kAreaTheConcourse, 0, 43, 52, 0}, /* 11 : PROTOZORQ */
|
||||
{ kAreaTheConcourse, 0, 43, 52, 0}, /* 12 : PROTOZORQ */
|
||||
{ kAreaTheRing2, 0, 43, 52, 0}, /* 13 : PROTOZORQ */
|
||||
{ kAreaTheMastersOrbit3, 0, 43, 52, 0}, /* 14 : PROTOZORQ */
|
||||
{ kAreaTheMastersOrbit1, 0, 43, 52, 0}, /* 15 : PROTOZORQ */
|
||||
{ kAreaTheMastersOrbit1, 0, 43, 53, 0}, /* 16 : PROTOZORQ */
|
||||
{ kAreaTheMastersOrbit1, 0, 43, 54, 0}, /* 17 : PROTOZORQ */
|
||||
{ kAreaTheMastersOrbit3, 0, 43, 53, 0}, /* 18 : PROTOZORQ */
|
||||
{ kAreaDreamsOfSlime, 0, 43, 36, 0}, /* 19 : PROTOZORQ */
|
||||
{ kAreaGuardRoom, 0, 43, 53, 0}, /* 20 : PROTOZORQ */
|
||||
{ kAreaGuardRoom, 0, 43, 54, 0}, /* 21 : PROTOZORQ */
|
||||
{ 0, 0, 43, 55, 0}, /* 22 : PROTOZORQ */
|
||||
{ kAreaTheNoose, 0, 45, 130, 0}, /* 23 : THE POORMOUTH */
|
||||
{kAreaInTheScorpionsPresence, 0, 46, 2, 0}, /* 24 : KHELE */
|
||||
{ kAreaTheWeb, 0, 47, 194, 0}, /* 25 : THE MISTRESS */
|
||||
{ kAreaThePowersOfTheAbyss, 0, 48, 138, 0}, /* 26 : DEILOS */
|
||||
{ 99, 0, 53, 236, 0}, /* 27 : SCI FI */
|
||||
{ kAreaCavern, 0, 54, 58, 0}, /* 28 : NORMAJEEN */
|
||||
{ kAreaCavern, 0, 55, 65, 0}, /* 29 : ASH */
|
||||
{ kAreaPlacatingThePowers, 0, 56, 125, 0}, /* 30 : MONKEY */
|
||||
{ 0, 0, 57, 166, 0}, /* 31 : HARSSK */
|
||||
{ 0, 0, 58, 175, 0}, /* 32 : ZORQ */
|
||||
{ 0, 0, 59, 183, 0}, /* 33 : QRIICH */
|
||||
{ 0, 0, 44, 8, 0}, /* 34 : VORT */
|
||||
{ 0, 0, 44, 0, 0}, /* 35 : VORT */
|
||||
{ kAreaPlacatingThePowers, 0, 52, 146, 0}, /* 36 : PRIESTESS */
|
||||
{ kAreaTheThresholdOfTruth, 0, 52, 82, 0}, /* 37 : PRIESTESS */
|
||||
{ 0, 0, 93, 243, 0}, /* 38 : CADAVER */
|
||||
{ kAreaPlacatingThePowers, 0, 51, 209, 0}, /* 39 : TURKEY */
|
||||
{ kAreaPlacatingThePowers, 0, 51, 209, 0}, /* 40 : TURKEY */
|
||||
};
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
137
engines/chamber/sound.cpp
Normal file
137
engines/chamber/sound.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
/* 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 "audio/mixer.h"
|
||||
#include "audio/softsynth/pcspk.h"
|
||||
|
||||
#include "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/sound.h"
|
||||
#include "chamber/ifgm.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
typedef struct pcsample_t {
|
||||
unsigned short repeat;
|
||||
unsigned short delay1;
|
||||
unsigned short delay1sweep;
|
||||
unsigned short delay2;
|
||||
unsigned short delay2sweep;
|
||||
unsigned short freq;
|
||||
unsigned short freqsweep;
|
||||
} pcsample_t;
|
||||
|
||||
#define N(x) (0xF000|x)
|
||||
|
||||
pcsample_t pc_samples[] = {
|
||||
{ 64, 32, 0, 32, 0, 256, 0},
|
||||
{ 1, 2560, 0, 2560, 0, 0, 0},
|
||||
{ 8, 2048, 0, 256, 256, 0, 0},
|
||||
{ 11, 2816, N(256), 2816, N(256), 256, 256},
|
||||
{ 1, 768, 0, 768, 0, 256, 0},
|
||||
{128, 48, 1, 48, 0, 61440u, 1},
|
||||
{128, 80, 1, 80, 0, 1, 1},
|
||||
{128, 128, 1, 128, 1, 16, 1},
|
||||
{128, 128, 1, 128, 0, 256, 16},
|
||||
{128, 128, 1, 128, 1, 61440u, N(16)},
|
||||
{ 16, 1536, 0, 1536, 0, 0, 0},
|
||||
{ 3, 768, 0, 768, N(256), 256, N(256)},
|
||||
};
|
||||
|
||||
#undef N
|
||||
|
||||
static void speakerPlay(pcsample_t *sample) {
|
||||
uint16 rep, freq, delay1, delay2;
|
||||
|
||||
freq = sample->freq;
|
||||
delay1 = sample->delay1;
|
||||
delay2 = sample->delay2;
|
||||
|
||||
for (rep = 0; rep < sample->repeat; rep++) {
|
||||
uint32 frequency = 1193180 / (freq ? freq : 1);
|
||||
uint32 delayOff = delay1 * 16; // Around 335 ticks per second
|
||||
uint32 delayOn = delay2 * 16;
|
||||
|
||||
g_vm->_speaker->playQueue(Audio::PCSpeaker::kWaveFormSilence, frequency, delayOff);
|
||||
g_vm->_speaker->playQueue(Audio::PCSpeaker::kWaveFormSquare, frequency, delayOn);
|
||||
|
||||
if (sample->delay1sweep & 0xF000)
|
||||
delay1 -= sample->delay1sweep & 0xFFF;
|
||||
else
|
||||
delay1 += sample->delay1sweep;
|
||||
|
||||
if (sample->delay2sweep & 0xF000)
|
||||
delay2 -= sample->delay2sweep & 0xFFF;
|
||||
else
|
||||
delay2 += sample->delay2sweep;
|
||||
|
||||
if (sample->freqsweep & 0xF000)
|
||||
freq -= sample->freqsweep & 0xFFF;
|
||||
else
|
||||
freq += sample->freqsweep;
|
||||
}
|
||||
}
|
||||
|
||||
#define kMaxSounds 12
|
||||
|
||||
byte sounds_table[kMaxSounds][3] = {
|
||||
{20, 0, 0},
|
||||
{19, 0, 0},
|
||||
{176, 0, 0},
|
||||
{144, 145, 146},
|
||||
{243, 0, 0},
|
||||
{18, 0, 0},
|
||||
{149, 21, 0},
|
||||
{27, 0, 0},
|
||||
{241, 25, 151},
|
||||
{22, 0, 0},
|
||||
{224, 0, 0},
|
||||
{31, 0, 0}
|
||||
};
|
||||
|
||||
void playSound(byte index) {
|
||||
int16 i;
|
||||
if (IFGM_PlaySound(index))
|
||||
return;
|
||||
|
||||
for (i = 0; i < kMaxSounds; i++) {
|
||||
if (sounds_table[i][0] == index
|
||||
|| sounds_table[i][1] == index
|
||||
|| sounds_table[i][2] == index) {
|
||||
speakerPlay(&pc_samples[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChamberEngine::initSound() {
|
||||
// Setup mixer
|
||||
syncSoundSettings();
|
||||
|
||||
_speaker = new Audio::PCSpeaker();
|
||||
_speaker->init();
|
||||
}
|
||||
|
||||
void ChamberEngine::deinitSound() {
|
||||
delete g_vm->_speaker;
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
31
engines/chamber/sound.h
Normal file
31
engines/chamber/sound.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* 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 CHAMBER_SOUND_H
|
||||
#define CHAMBER_SOUND_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
void playSound(byte index);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
64
engines/chamber/timer.cpp
Normal file
64
engines/chamber/timer.cpp
Normal 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/system.h"
|
||||
#include "common/timer.h"
|
||||
|
||||
#include "chamber/chamber.h"
|
||||
#include "chamber/common.h"
|
||||
#include "chamber/cga.h"
|
||||
#include "chamber/script.h"
|
||||
#include "chamber/resdata.h"
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
|
||||
void animateGauss(byte *target) {
|
||||
byte *sprite;
|
||||
byte phase = getRand() % 4;
|
||||
if (phase == script_byte_vars.gauss_phase)
|
||||
phase = (phase + 1) % 4;
|
||||
script_byte_vars.gauss_phase = phase;
|
||||
sprite = gauss_data + 8 + phase * (8 * 30);
|
||||
cga_Blit(sprite, 8, 8, 30, target, 80); /*draw to 0:4*/
|
||||
}
|
||||
|
||||
void timerCallback(void *refCon) {
|
||||
script_byte_vars.timer_ticks++;
|
||||
if (!script_byte_vars.game_paused) {
|
||||
if (script_byte_vars.timer_ticks % 16 == 0) {
|
||||
script_word_vars.timer_ticks2 = Swap16(Swap16(script_word_vars.timer_ticks2) + 1);
|
||||
#if 1
|
||||
animateGauss(frontbuffer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void initTimer(void) {
|
||||
g_system->getTimerManager()->installTimerProc(&timerCallback, 1000000 / 16, NULL, "mainTimer");
|
||||
}
|
||||
|
||||
void uninitTimer(void) {
|
||||
g_system->getTimerManager()->removeTimerProc(&timerCallback);
|
||||
}
|
||||
|
||||
} // End of namespace Chamber
|
||||
32
engines/chamber/timer.h
Normal file
32
engines/chamber/timer.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* 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 CHAMBER_TIMER_H
|
||||
#define CHAMBER_TIMER_H
|
||||
|
||||
namespace Chamber {
|
||||
|
||||
void initTimer(void);
|
||||
void uninitTimer(void);
|
||||
|
||||
} // End of namespace Chamber
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user