2002-06-29 16:11:13 +00:00
|
|
|
/* ScummVM - Scumm Interpreter
|
2006-05-05 00:42:37 +00:00
|
|
|
* Copyright (C) 2001 Ludvig Strigeus
|
2006-01-18 17:39:49 +00:00
|
|
|
* Copyright (C) 2001-2006 The ScummVM project
|
2002-06-29 16:11:13 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2005-10-18 01:30:26 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2002-06-29 16:11:13 +00:00
|
|
|
*
|
2006-02-11 12:46:41 +00:00
|
|
|
* $URL$
|
|
|
|
* $Id$
|
2002-06-29 16:11:13 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Video script opcodes for Simon1/Simon2
|
2005-06-24 15:23:51 +00:00
|
|
|
#include "common/stdafx.h"
|
2006-04-29 14:23:16 +00:00
|
|
|
|
2006-09-29 08:14:27 +00:00
|
|
|
#include "agos/agos.h"
|
|
|
|
#include "agos/intern.h"
|
|
|
|
#include "agos/vga.h"
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-01-10 22:06:49 +00:00
|
|
|
#include "common/system.h"
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
namespace AGOS {
|
2003-10-03 19:42:27 +00:00
|
|
|
|
2002-06-29 16:11:13 +00:00
|
|
|
// Opcode tables
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::setupVgaOpcodes() {
|
2005-11-05 18:47:03 +00:00
|
|
|
static const VgaOpcodeProc vga_opcode_table[] = {
|
|
|
|
NULL,
|
2006-09-29 09:44:30 +00:00
|
|
|
&AGOSEngine::vc1_fadeOut,
|
|
|
|
&AGOSEngine::vc2_call,
|
|
|
|
&AGOSEngine::vc3_loadSprite,
|
|
|
|
&AGOSEngine::vc4_fadeIn,
|
|
|
|
&AGOSEngine::vc5_skip_if_neq,
|
|
|
|
&AGOSEngine::vc6_skip_ifn_sib_with_a,
|
|
|
|
&AGOSEngine::vc7_skip_if_sib_with_a,
|
|
|
|
&AGOSEngine::vc8_skip_if_parent_is,
|
|
|
|
&AGOSEngine::vc9_skip_if_unk3_is,
|
|
|
|
&AGOSEngine::vc10_draw,
|
|
|
|
&AGOSEngine::vc11_clearPathFinder,
|
|
|
|
&AGOSEngine::vc12_delay,
|
|
|
|
&AGOSEngine::vc13_addToSpriteX,
|
|
|
|
&AGOSEngine::vc14_addToSpriteY,
|
|
|
|
&AGOSEngine::vc15_sync,
|
|
|
|
&AGOSEngine::vc16_waitSync,
|
|
|
|
&AGOSEngine::vc17_setPathfinderItem,
|
|
|
|
&AGOSEngine::vc18_jump,
|
|
|
|
&AGOSEngine::vc19_chain_to_script,
|
|
|
|
&AGOSEngine::vc20_setRepeat,
|
|
|
|
&AGOSEngine::vc21_endRepeat,
|
|
|
|
&AGOSEngine::vc22_setSpritePalette,
|
|
|
|
&AGOSEngine::vc23_setSpritePriority,
|
|
|
|
&AGOSEngine::vc24_setSpriteXY,
|
|
|
|
&AGOSEngine::vc25_halt_sprite,
|
|
|
|
&AGOSEngine::vc26_setSubWindow,
|
|
|
|
&AGOSEngine::vc27_resetSprite,
|
|
|
|
&AGOSEngine::vc28_dummy_op,
|
|
|
|
&AGOSEngine::vc29_stopAllSounds,
|
|
|
|
&AGOSEngine::vc30_setFrameRate,
|
|
|
|
&AGOSEngine::vc31_setWindow,
|
|
|
|
&AGOSEngine::vc32_copyVar,
|
|
|
|
&AGOSEngine::vc33_setMouseOn,
|
|
|
|
&AGOSEngine::vc34_setMouseOff,
|
|
|
|
&AGOSEngine::vc35_clearWindow,
|
|
|
|
&AGOSEngine::vc36_setWindowImage,
|
|
|
|
&AGOSEngine::vc37_addToSpriteY,
|
|
|
|
&AGOSEngine::vc38_skipIfVarZero,
|
|
|
|
&AGOSEngine::vc39_setVar,
|
|
|
|
&AGOSEngine::vc40,
|
|
|
|
&AGOSEngine::vc41,
|
|
|
|
&AGOSEngine::vc42_delayIfNotEQ,
|
|
|
|
&AGOSEngine::vc43_skipIfBitClear,
|
|
|
|
&AGOSEngine::vc44_skipIfBitSet,
|
|
|
|
&AGOSEngine::vc45_setSpriteX,
|
|
|
|
&AGOSEngine::vc46_setSpriteY,
|
|
|
|
&AGOSEngine::vc47_addToVar,
|
|
|
|
&AGOSEngine::vc48_setPathFinder,
|
|
|
|
&AGOSEngine::vc49_setBit,
|
|
|
|
&AGOSEngine::vc50_clearBit,
|
|
|
|
&AGOSEngine::vc51_enableBox,
|
|
|
|
&AGOSEngine::vc52_playSound,
|
|
|
|
&AGOSEngine::vc53_panSFX,
|
|
|
|
&AGOSEngine::vc54_no_op,
|
|
|
|
&AGOSEngine::vc55_moveBox,
|
|
|
|
&AGOSEngine::vc56_delay,
|
|
|
|
&AGOSEngine::vc57_blackPalette,
|
|
|
|
&AGOSEngine::vc58,
|
|
|
|
&AGOSEngine::vc59,
|
|
|
|
&AGOSEngine::vc60_killSprite,
|
|
|
|
&AGOSEngine::vc61_setMaskImage,
|
|
|
|
&AGOSEngine::vc62_fastFadeOut,
|
|
|
|
&AGOSEngine::vc63_fastFadeIn,
|
|
|
|
&AGOSEngine::vc64_skipIfSpeechEnded,
|
|
|
|
&AGOSEngine::vc65_slowFadeIn,
|
|
|
|
&AGOSEngine::vc66_skipIfNotEqual,
|
|
|
|
&AGOSEngine::vc67_skipIfGE,
|
|
|
|
&AGOSEngine::vc68_skipIfLE,
|
|
|
|
&AGOSEngine::vc69_playTrack,
|
|
|
|
&AGOSEngine::vc70_queueMusic,
|
|
|
|
&AGOSEngine::vc71_checkMusicQueue,
|
|
|
|
&AGOSEngine::vc72_play_track_2,
|
|
|
|
&AGOSEngine::vc73_setMark,
|
|
|
|
&AGOSEngine::vc74_clearMark,
|
|
|
|
&AGOSEngine::vc75_setScale,
|
|
|
|
&AGOSEngine::vc76_setScaleXOffs,
|
|
|
|
&AGOSEngine::vc77_setScaleYOffs,
|
|
|
|
&AGOSEngine::vc78_computeXY,
|
|
|
|
&AGOSEngine::vc79_computePosNum,
|
|
|
|
&AGOSEngine::vc80_setOverlayImage,
|
|
|
|
&AGOSEngine::vc81_setRandom,
|
|
|
|
&AGOSEngine::vc82_getPathValue,
|
|
|
|
&AGOSEngine::vc83_playSoundLoop,
|
|
|
|
&AGOSEngine::vc84_stopSoundLoop,
|
2005-11-05 18:47:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
_vga_opcode_table = vga_opcode_table;
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
|
|
|
|
// Script parser
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::runVgaScript() {
|
2002-07-07 19:06:48 +00:00
|
|
|
for (;;) {
|
2002-06-29 16:11:13 +00:00
|
|
|
uint opcode;
|
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
if (_continousVgaScript) {
|
|
|
|
if (_vcPtr != (const byte *)&_vc_get_out_of_code) {
|
2006-07-22 16:09:34 +00:00
|
|
|
printf("%.5d %.5X: %5d %4d ", _vgaTickCounter, (unsigned int)(_vcPtr - _curVgaFile1), _vgaCurSpriteId, _vgaCurZoneNum);
|
2005-05-06 11:37:33 +00:00
|
|
|
dump_video_script(_vcPtr, true);
|
2003-03-06 19:16:24 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) {
|
2005-05-06 11:37:33 +00:00
|
|
|
opcode = READ_BE_UINT16(_vcPtr);
|
|
|
|
_vcPtr += 2;
|
2002-06-29 16:11:13 +00:00
|
|
|
} else {
|
2005-05-06 11:37:33 +00:00
|
|
|
opcode = *_vcPtr++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-05-04 02:23:52 +00:00
|
|
|
if (opcode >= _numVideoOpcodes)
|
2002-06-29 16:11:13 +00:00
|
|
|
error("Invalid VGA opcode '%d' encountered", opcode);
|
|
|
|
|
|
|
|
if (opcode == 0)
|
|
|
|
return;
|
|
|
|
|
2005-11-05 18:47:03 +00:00
|
|
|
(this->*_vga_opcode_table[opcode]) ();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
bool AGOSEngine::itemIsSiblingOf(uint16 a) {
|
2006-04-29 12:25:15 +00:00
|
|
|
Item *item;
|
|
|
|
|
|
|
|
CHECK_BOUNDS(a, _objectArray);
|
|
|
|
|
|
|
|
item = _objectArray[a];
|
|
|
|
if (item == NULL)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return me()->parent == item->parent;
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
bool AGOSEngine::itemIsParentOf(uint16 a, uint16 b) {
|
2006-04-29 12:25:15 +00:00
|
|
|
Item *item_a, *item_b;
|
|
|
|
|
|
|
|
CHECK_BOUNDS(a, _objectArray);
|
|
|
|
CHECK_BOUNDS(b, _objectArray);
|
|
|
|
|
|
|
|
item_a = _objectArray[a];
|
|
|
|
item_b = _objectArray[b];
|
|
|
|
|
|
|
|
if (item_a == NULL || item_b == NULL)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return derefItem(item_a->parent) == item_b;
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
bool AGOSEngine::vc_maybe_skip_proc_1(uint16 a, int16 b) {
|
2006-04-29 12:25:15 +00:00
|
|
|
Item *item;
|
|
|
|
|
|
|
|
CHECK_BOUNDS(a, _objectArray);
|
|
|
|
|
|
|
|
item = _objectArray[a];
|
|
|
|
if (item == NULL)
|
|
|
|
return true;
|
|
|
|
return item->state == b;
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
VgaSprite *AGOSEngine::findCurSprite() {
|
2006-04-29 14:11:29 +00:00
|
|
|
VgaSprite *vsp = _vgaSprites;
|
|
|
|
while (vsp->id) {
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) {
|
2006-04-29 14:11:29 +00:00
|
|
|
if (vsp->id == _vgaCurSpriteId)
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
if (vsp->id == _vgaCurSpriteId && vsp->zoneNum == _vgaCurZoneNum)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
vsp++;
|
|
|
|
}
|
|
|
|
return vsp;
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
int AGOSEngine::vcReadVarOrWord() {
|
2005-12-13 00:20:11 +00:00
|
|
|
int16 var = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
if (var < 0)
|
2005-12-13 00:20:11 +00:00
|
|
|
var = vcReadVar(-var);
|
2002-06-29 16:11:13 +00:00
|
|
|
return var;
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
uint AGOSEngine::vcReadNextWord() {
|
2005-10-07 06:59:49 +00:00
|
|
|
uint a;
|
2005-10-12 00:35:54 +00:00
|
|
|
a = readUint16Wrapper(_vcPtr);
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr += 2;
|
2002-06-29 16:11:13 +00:00
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
uint AGOSEngine::vcReadNextByte() {
|
2005-05-06 11:37:33 +00:00
|
|
|
return *_vcPtr++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
uint AGOSEngine::vcReadVar(uint var) {
|
2006-09-29 00:50:22 +00:00
|
|
|
assert(var < _numVars);
|
2006-04-24 10:35:57 +00:00
|
|
|
return (uint16)_variableArrayPtr[var];
|
2006-04-15 01:09:04 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vcWriteVar(uint var, int16 value) {
|
2006-09-29 00:50:22 +00:00
|
|
|
assert(var < _numVars);
|
2006-04-15 22:14:39 +00:00
|
|
|
_variableArrayPtr[var] = value;
|
2006-04-15 01:09:04 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vcSkipNextInstruction() {
|
2006-09-19 11:59:13 +00:00
|
|
|
static const byte opcodeParamLenWW[] = {
|
|
|
|
0, 6, 2, 10, 6, 4, 2, 2,
|
|
|
|
4, 4, 8, 2, 2, 2, 2, 2,
|
|
|
|
2, 2, 2, 0, 4, 2, 2, 2,
|
|
|
|
8, 0, 10, 0, 8, 0, 2, 2,
|
|
|
|
0, 0, 0, 4, 4, 4, 2, 4,
|
|
|
|
4, 4, 4, 2, 2, 4, 2, 2,
|
|
|
|
2, 2, 2, 2, 2, 4, 6, 6,
|
|
|
|
0, 0, 0, 0, 2, 2, 0, 0,
|
|
|
|
};
|
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
static const byte opcodeParamLenSimon1[] = {
|
2002-07-07 19:06:48 +00:00
|
|
|
0, 6, 2, 10, 6, 4, 2, 2,
|
|
|
|
4, 4, 10, 0, 2, 2, 2, 2,
|
2002-06-29 16:11:13 +00:00
|
|
|
2, 0, 2, 0, 4, 2, 4, 2,
|
2002-07-07 19:06:48 +00:00
|
|
|
8, 0, 10, 0, 8, 0, 2, 2,
|
2002-06-29 16:11:13 +00:00
|
|
|
4, 0, 0, 4, 4, 2, 2, 4,
|
|
|
|
4, 4, 4, 2, 2, 2, 2, 4,
|
|
|
|
0, 2, 2, 2, 2, 4, 6, 6,
|
|
|
|
0, 0, 0, 0, 2, 6, 0, 0,
|
|
|
|
};
|
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
static const byte opcodeParamLenSimon2[] = {
|
2002-06-29 16:11:13 +00:00
|
|
|
0, 6, 2, 12, 6, 4, 2, 2,
|
|
|
|
4, 4, 9, 0, 1, 2, 2, 2,
|
|
|
|
2, 0, 2, 0, 4, 2, 4, 2,
|
|
|
|
7, 0, 10, 0, 8, 0, 2, 2,
|
|
|
|
4, 0, 0, 4, 4, 2, 2, 4,
|
|
|
|
4, 4, 4, 2, 2, 2, 2, 4,
|
|
|
|
0, 2, 2, 2, 2, 4, 6, 6,
|
|
|
|
2, 0, 6, 6, 4, 6, 0, 0,
|
|
|
|
0, 0, 4, 4, 4, 4, 4, 0,
|
|
|
|
4, 2, 2
|
|
|
|
};
|
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
static const byte opcodeParamLenFeebleFiles[] = {
|
2005-10-09 09:03:37 +00:00
|
|
|
0, 6, 2, 12, 6, 4, 2, 2,
|
|
|
|
4, 4, 9, 0, 1, 2, 2, 2,
|
|
|
|
2, 0, 2, 0, 4, 2, 4, 2,
|
|
|
|
7, 0, 10, 0, 8, 0, 2, 2,
|
|
|
|
4, 0, 0, 4, 4, 2, 2, 4,
|
|
|
|
4, 4, 4, 2, 2, 2, 2, 4,
|
|
|
|
0, 2, 2, 2, 6, 6, 6, 6,
|
|
|
|
2, 0, 6, 6, 4, 6, 0, 0,
|
|
|
|
0, 0, 4, 4, 4, 4, 4, 0,
|
|
|
|
4, 2, 2, 4, 6, 6, 0, 0,
|
|
|
|
6, 4, 2, 6, 0
|
|
|
|
};
|
|
|
|
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 opcode;
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2006-04-24 06:46:31 +00:00
|
|
|
opcode = vcReadNextByte();
|
2005-12-13 00:20:11 +00:00
|
|
|
_vcPtr += opcodeParamLenFeebleFiles[opcode];
|
2005-11-12 06:01:24 +00:00
|
|
|
} else if (getGameType() == GType_SIMON2) {
|
2006-04-24 06:46:31 +00:00
|
|
|
opcode = vcReadNextByte();
|
2005-12-13 00:20:11 +00:00
|
|
|
_vcPtr += opcodeParamLenSimon2[opcode];
|
2006-09-19 11:59:13 +00:00
|
|
|
} else if (getGameType() == GType_SIMON1) {
|
2006-04-24 06:46:31 +00:00
|
|
|
opcode = vcReadNextWord();
|
2005-12-13 00:20:11 +00:00
|
|
|
_vcPtr += opcodeParamLenSimon1[opcode];
|
2006-09-19 11:59:13 +00:00
|
|
|
} else {
|
|
|
|
opcode = vcReadNextWord();
|
|
|
|
_vcPtr += opcodeParamLenWW[opcode];
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
if (_continousVgaScript)
|
2006-05-04 12:20:49 +00:00
|
|
|
printf("; skipped\n");
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// VGA Script commands
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc1_fadeOut() {
|
2002-06-29 16:11:13 +00:00
|
|
|
/* dummy opcode */
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr += 6;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc2_call() {
|
2002-06-29 16:11:13 +00:00
|
|
|
VgaPointersEntry *vpe;
|
2006-05-04 06:18:19 +00:00
|
|
|
uint16 count, num, res;
|
2002-06-29 16:11:13 +00:00
|
|
|
byte *old_file_1, *old_file_2;
|
2004-12-18 01:33:21 +00:00
|
|
|
byte *b, *bb;
|
2006-05-05 05:53:36 +00:00
|
|
|
const byte *vcPtrOrg;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
num = vcReadVarOrWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
old_file_1 = _curVgaFile1;
|
|
|
|
old_file_2 = _curVgaFile2;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2002-07-07 19:06:48 +00:00
|
|
|
for (;;) {
|
2002-06-29 16:11:13 +00:00
|
|
|
res = num / 100;
|
2005-05-06 11:37:33 +00:00
|
|
|
vpe = &_vgaBufferPointers[res];
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
_curVgaFile1 = vpe->vgaFile1;
|
|
|
|
_curVgaFile2 = vpe->vgaFile2;
|
2002-06-29 16:11:13 +00:00
|
|
|
if (vpe->vgaFile1 != NULL)
|
|
|
|
break;
|
2006-04-10 23:44:17 +00:00
|
|
|
if (_zoneNumber != res)
|
|
|
|
_noOverWrite = _zoneNumber;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
loadZone(res);
|
2006-04-10 23:44:17 +00:00
|
|
|
_noOverWrite = 0xFFFF;
|
2002-07-07 19:06:48 +00:00
|
|
|
}
|
|
|
|
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
bb = _curVgaFile1;
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2005-10-09 12:12:24 +00:00
|
|
|
b = bb + READ_LE_UINT16(&((VgaFileHeader_Feeble *) bb)->hdr2_start);
|
2006-05-04 06:18:19 +00:00
|
|
|
count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageCount);
|
2005-10-09 12:12:24 +00:00
|
|
|
b = bb + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageTable);
|
|
|
|
|
2006-05-04 06:18:19 +00:00
|
|
|
while (count--) {
|
|
|
|
if (READ_LE_UINT16(&((ImageHeader_Feeble *) b)->id) == num)
|
|
|
|
break;
|
2005-10-09 12:12:24 +00:00
|
|
|
b += sizeof(ImageHeader_Feeble);
|
2006-05-04 06:18:19 +00:00
|
|
|
}
|
|
|
|
assert(READ_LE_UINT16(&((ImageHeader_Feeble *) b)->id) == num);
|
2006-09-28 23:22:07 +00:00
|
|
|
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
|
2005-10-09 12:12:24 +00:00
|
|
|
b = bb + READ_BE_UINT16(&((VgaFileHeader_Simon *) bb)->hdr2_start);
|
2006-05-04 06:18:19 +00:00
|
|
|
count = READ_BE_UINT16(&((VgaFileHeader2_Simon *) b)->imageCount);
|
2005-10-09 12:12:24 +00:00
|
|
|
b = bb + READ_BE_UINT16(&((VgaFileHeader2_Simon *) b)->imageTable);
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-05-04 06:18:19 +00:00
|
|
|
while (count--) {
|
|
|
|
if (READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == num)
|
|
|
|
break;
|
2005-10-09 12:12:24 +00:00
|
|
|
b += sizeof(ImageHeader_Simon);
|
2006-05-04 06:18:19 +00:00
|
|
|
}
|
|
|
|
assert(READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == num);
|
2006-09-28 23:22:07 +00:00
|
|
|
} else {
|
|
|
|
b = bb + READ_BE_UINT16(bb + 10);
|
|
|
|
b += 20;
|
|
|
|
|
|
|
|
count = READ_BE_UINT16(&((VgaFileHeader2_WW *) b)->imageCount);
|
|
|
|
b = bb + READ_BE_UINT16(&((VgaFileHeader2_WW *) b)->imageTable);
|
|
|
|
|
|
|
|
while (count--) {
|
|
|
|
if (READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == num)
|
|
|
|
break;
|
|
|
|
b += sizeof(ImageHeader_WW);
|
|
|
|
}
|
|
|
|
assert(READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == num);
|
2005-10-09 12:12:24 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-05-05 05:53:36 +00:00
|
|
|
vcPtrOrg = _vcPtr;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2005-10-09 12:12:24 +00:00
|
|
|
_vcPtr = _curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble *) b)->scriptOffs);
|
2006-09-28 23:22:07 +00:00
|
|
|
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
|
2005-10-12 00:35:54 +00:00
|
|
|
_vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon *) b)->scriptOffs);
|
2006-09-28 23:22:07 +00:00
|
|
|
} else {
|
|
|
|
_vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_WW *) b)->scriptOffs);
|
2005-10-09 12:12:24 +00:00
|
|
|
}
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
//dump_vga_script(_vcPtr, res, num);
|
2006-04-21 00:18:23 +00:00
|
|
|
runVgaScript();
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
_curVgaFile1 = old_file_1;
|
|
|
|
_curVgaFile2 = old_file_2;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-05-05 05:53:36 +00:00
|
|
|
_vcPtr = vcPtrOrg;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc3_loadSprite() {
|
2006-04-10 23:44:17 +00:00
|
|
|
uint16 windowNum, zoneNum, palette, x, y, vgaSpriteId;
|
2006-05-04 06:28:51 +00:00
|
|
|
uint16 count, res;
|
2002-06-29 16:11:13 +00:00
|
|
|
VgaSprite *vsp;
|
|
|
|
VgaPointersEntry *vpe;
|
2002-07-07 19:06:48 +00:00
|
|
|
byte *p, *pp;
|
2003-07-14 12:00:20 +00:00
|
|
|
byte *old_file_1;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
windowNum = vcReadNextWord(); /* 0 */
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) {
|
2005-12-13 00:20:11 +00:00
|
|
|
vgaSpriteId = vcReadNextWord(); /* 2 */
|
2006-04-10 23:44:17 +00:00
|
|
|
zoneNum = vgaSpriteId / 100;
|
2002-06-29 16:11:13 +00:00
|
|
|
} else {
|
2006-04-10 23:44:17 +00:00
|
|
|
zoneNum = vcReadNextWord(); /* 0 */
|
2005-12-13 00:20:11 +00:00
|
|
|
vgaSpriteId = vcReadNextWord(); /* 2 */
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
x = vcReadNextWord(); /* 4 */
|
|
|
|
y = vcReadNextWord(); /* 6 */
|
2006-03-22 10:04:01 +00:00
|
|
|
palette = vcReadNextWord(); /* 8 */
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-05-26 10:14:06 +00:00
|
|
|
if (isSpriteLoaded(vgaSpriteId, zoneNum))
|
2002-06-29 16:11:13 +00:00
|
|
|
return;
|
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
vsp = _vgaSprites;
|
2002-07-07 19:06:48 +00:00
|
|
|
while (vsp->id)
|
|
|
|
vsp++;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_WW)
|
|
|
|
vsp->palette = 0;
|
|
|
|
else
|
|
|
|
vsp->palette = palette;
|
2005-10-05 11:37:26 +00:00
|
|
|
vsp->windowNum = windowNum;
|
2002-11-28 00:22:24 +00:00
|
|
|
vsp->priority = 0;
|
2005-05-06 12:23:19 +00:00
|
|
|
vsp->flags = 0;
|
2002-06-29 16:11:13 +00:00
|
|
|
vsp->image = 0;
|
2003-10-21 10:34:56 +00:00
|
|
|
vsp->x = x;
|
|
|
|
vsp->y = y;
|
2005-05-06 12:23:19 +00:00
|
|
|
vsp->id = vgaSpriteId;
|
2006-04-10 23:44:17 +00:00
|
|
|
vsp->zoneNum = res = zoneNum;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
old_file_1 = _curVgaFile1;
|
2002-07-07 19:06:48 +00:00
|
|
|
for (;;) {
|
2005-05-06 11:37:33 +00:00
|
|
|
vpe = &_vgaBufferPointers[res];
|
|
|
|
_curVgaFile1 = vpe->vgaFile1;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
|
|
|
if (vpe->vgaFile1 != NULL)
|
|
|
|
break;
|
2006-04-10 23:44:17 +00:00
|
|
|
if (_zoneNumber != res)
|
|
|
|
_noOverWrite = _zoneNumber;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
loadZone(res);
|
2006-04-10 23:44:17 +00:00
|
|
|
_noOverWrite = 0xFFFF;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
pp = _curVgaFile1;
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2005-10-09 12:12:24 +00:00
|
|
|
p = pp + READ_LE_UINT16(&((VgaFileHeader_Feeble *) pp)->hdr2_start);
|
2006-05-04 06:28:51 +00:00
|
|
|
count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationCount);
|
2005-10-09 12:12:24 +00:00
|
|
|
p = pp + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationTable);
|
|
|
|
|
2006-05-04 06:28:51 +00:00
|
|
|
while (count--) {
|
|
|
|
if (READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->id) == vgaSpriteId)
|
|
|
|
break;
|
2005-10-09 12:12:24 +00:00
|
|
|
p += sizeof(AnimationHeader_Feeble);
|
2006-05-04 06:28:51 +00:00
|
|
|
}
|
|
|
|
assert(READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->id) == vgaSpriteId);
|
2006-09-28 23:22:07 +00:00
|
|
|
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
|
2005-10-09 12:12:24 +00:00
|
|
|
p = pp + READ_BE_UINT16(&((VgaFileHeader_Simon *) pp)->hdr2_start);
|
2006-05-04 06:28:51 +00:00
|
|
|
count = READ_BE_UINT16(&((VgaFileHeader2_Simon *) p)->animationCount);
|
2005-10-09 12:12:24 +00:00
|
|
|
p = pp + READ_BE_UINT16(&((VgaFileHeader2_Simon *) p)->animationTable);
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-05-04 06:28:51 +00:00
|
|
|
while (count--) {
|
|
|
|
if (READ_BE_UINT16(&((AnimationHeader_Simon *) p)->id) == vgaSpriteId)
|
|
|
|
break;
|
2005-10-09 12:12:24 +00:00
|
|
|
p += sizeof(AnimationHeader_Simon);
|
2006-05-04 06:28:51 +00:00
|
|
|
}
|
|
|
|
assert(READ_BE_UINT16(&((AnimationHeader_Simon *) p)->id) == vgaSpriteId);
|
2006-09-28 23:22:07 +00:00
|
|
|
} else {
|
|
|
|
p = pp + READ_BE_UINT16(pp + 10);
|
|
|
|
p += 20;
|
|
|
|
|
|
|
|
count = READ_BE_UINT16(&((VgaFileHeader2_WW *) p)->animationCount);
|
|
|
|
p = pp + READ_BE_UINT16(&((VgaFileHeader2_WW *) p)->animationTable);
|
|
|
|
|
|
|
|
while (count--) {
|
|
|
|
if (READ_BE_UINT16(&((AnimationHeader_WW *) p)->id) == vgaSpriteId)
|
|
|
|
break;
|
|
|
|
p += sizeof(AnimationHeader_WW);
|
|
|
|
}
|
|
|
|
assert(READ_BE_UINT16(&((AnimationHeader_WW *) p)->id) == vgaSpriteId);
|
2005-10-09 12:12:24 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
|
|
|
|
#ifdef DUMP_FILE_NR
|
2002-07-07 19:06:48 +00:00
|
|
|
{
|
|
|
|
static bool dumped = false;
|
|
|
|
if (res == DUMP_FILE_NR && !dumped) {
|
|
|
|
dumped = true;
|
2005-05-06 11:37:33 +00:00
|
|
|
dump_vga_file(_curVgaFile1);
|
2002-07-07 19:06:48 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef DUMP_BITMAPS_FILE_NR
|
2002-07-07 19:06:48 +00:00
|
|
|
{
|
|
|
|
static bool dumped = false;
|
|
|
|
if (res == DUMP_BITMAPS_FILE_NR && !dumped) {
|
|
|
|
dumped = true;
|
2005-05-06 11:37:33 +00:00
|
|
|
dump_vga_bitmaps(_curVgaFile2, _curVgaFile1, res);
|
2002-07-07 19:06:48 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-10-09 12:12:24 +00:00
|
|
|
if (_startVgaScript) {
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2005-10-09 12:12:24 +00:00
|
|
|
dump_vga_script(_curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), res, vgaSpriteId);
|
2006-09-28 23:22:07 +00:00
|
|
|
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
|
2005-10-09 12:12:24 +00:00
|
|
|
dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon*)p)->scriptOffs), res, vgaSpriteId);
|
2006-09-28 23:22:07 +00:00
|
|
|
} else {
|
|
|
|
dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW*)p)->scriptOffs), res, vgaSpriteId);
|
2005-10-09 12:12:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2006-05-04 02:23:52 +00:00
|
|
|
addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->scriptOffs), vgaSpriteId, res);
|
2006-09-28 23:22:07 +00:00
|
|
|
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
|
2006-05-04 02:23:52 +00:00
|
|
|
addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon *) p)->scriptOffs), vgaSpriteId, res);
|
2006-09-28 23:22:07 +00:00
|
|
|
} else {
|
|
|
|
addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW *) p)->scriptOffs), vgaSpriteId, res);
|
2005-10-09 12:12:24 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
_curVgaFile1 = old_file_1;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc4_fadeIn() {
|
2002-06-29 16:11:13 +00:00
|
|
|
/* dummy opcode */
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr += 6;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc5_skip_if_neq() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 var = vcReadNextWord();
|
|
|
|
uint16 value = vcReadNextWord();
|
2005-12-13 00:20:11 +00:00
|
|
|
if (vcReadVar(var) != value)
|
|
|
|
vcSkipNextInstruction();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc6_skip_ifn_sib_with_a() {
|
2005-12-13 00:20:11 +00:00
|
|
|
if (!itemIsSiblingOf(vcReadNextWord()))
|
|
|
|
vcSkipNextInstruction();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc7_skip_if_sib_with_a() {
|
2005-12-13 00:20:11 +00:00
|
|
|
if (itemIsSiblingOf(vcReadNextWord()))
|
|
|
|
vcSkipNextInstruction();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc8_skip_if_parent_is() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 a = vcReadNextWord();
|
|
|
|
uint16 b = vcReadNextWord();
|
2003-03-07 03:26:30 +00:00
|
|
|
if (!itemIsParentOf(a, b))
|
2005-12-13 00:20:11 +00:00
|
|
|
vcSkipNextInstruction();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc9_skip_if_unk3_is() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 a = vcReadNextWord();
|
|
|
|
uint16 b = vcReadNextWord();
|
2002-07-07 19:06:48 +00:00
|
|
|
if (!vc_maybe_skip_proc_1(a, b))
|
2005-12-13 00:20:11 +00:00
|
|
|
vcSkipNextInstruction();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-04-14 09:57:43 +00:00
|
|
|
byte *vc10_depackColumn(VC10_state * vs) {
|
2002-06-29 16:11:13 +00:00
|
|
|
int8 a = vs->depack_cont;
|
2004-12-18 01:33:21 +00:00
|
|
|
const byte *src = vs->depack_src;
|
2002-06-29 16:11:13 +00:00
|
|
|
byte *dst = vs->depack_dest;
|
2005-11-13 11:53:57 +00:00
|
|
|
uint16 dh = vs->dh;
|
2002-06-29 16:11:13 +00:00
|
|
|
byte color;
|
|
|
|
|
2004-03-14 17:53:19 +00:00
|
|
|
if (a == -0x80)
|
|
|
|
a = *src++;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2002-07-07 19:06:48 +00:00
|
|
|
for (;;) {
|
|
|
|
if (a >= 0) {
|
2002-06-29 16:11:13 +00:00
|
|
|
color = *src++;
|
|
|
|
do {
|
|
|
|
*dst++ = color;
|
|
|
|
if (!--dh) {
|
2002-07-07 19:06:48 +00:00
|
|
|
if (--a < 0)
|
2002-06-29 16:11:13 +00:00
|
|
|
a = -0x80;
|
|
|
|
else
|
|
|
|
src--;
|
|
|
|
goto get_out;
|
|
|
|
}
|
2002-07-07 19:06:48 +00:00
|
|
|
} while (--a >= 0);
|
2002-06-29 16:11:13 +00:00
|
|
|
} else {
|
|
|
|
do {
|
|
|
|
*dst++ = *src++;
|
|
|
|
if (!--dh) {
|
2002-07-07 19:06:48 +00:00
|
|
|
if (++a == 0)
|
2002-06-29 16:11:13 +00:00
|
|
|
a = -0x80;
|
|
|
|
goto get_out;
|
|
|
|
}
|
2002-07-07 19:06:48 +00:00
|
|
|
} while (++a != 0);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
2004-03-14 17:53:19 +00:00
|
|
|
a = *src++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
get_out:;
|
|
|
|
vs->depack_src = src;
|
|
|
|
vs->depack_cont = a;
|
|
|
|
return vs->depack_dest + vs->y_skip;
|
|
|
|
}
|
|
|
|
|
2005-05-06 13:22:48 +00:00
|
|
|
void vc10_skip_cols(VC10_state *vs) {
|
2002-07-07 19:06:48 +00:00
|
|
|
while (vs->x_skip) {
|
2006-04-14 09:57:43 +00:00
|
|
|
vc10_depackColumn(vs);
|
2002-06-29 16:11:13 +00:00
|
|
|
vs->x_skip--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
byte *AGOSEngine::vc10_uncompressFlip(const byte *src, uint w, uint h) {
|
2005-11-08 11:34:56 +00:00
|
|
|
w *= 8;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-11-08 11:34:56 +00:00
|
|
|
byte *src_org, *dst_org;
|
|
|
|
byte color;
|
|
|
|
int8 cur = -0x80;
|
|
|
|
uint i, w_cur = w;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2005-11-08 11:34:56 +00:00
|
|
|
dst_org = _videoBuf1 + w;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-11-08 11:34:56 +00:00
|
|
|
do {
|
|
|
|
byte *dst = dst_org;
|
|
|
|
uint h_cur = h;
|
|
|
|
|
|
|
|
if (cur == -0x80)
|
|
|
|
cur = *src++;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
if (cur >= 0) {
|
|
|
|
/* rle_same */
|
|
|
|
color = *src++;
|
|
|
|
do {
|
|
|
|
*dst = color;
|
|
|
|
dst += w;
|
|
|
|
if (!--h_cur) {
|
|
|
|
if (--cur < 0)
|
|
|
|
cur = -0x80;
|
|
|
|
else
|
|
|
|
src--;
|
|
|
|
goto next_line;
|
|
|
|
}
|
|
|
|
} while (--cur >= 0);
|
|
|
|
} else {
|
|
|
|
/* rle_diff */
|
|
|
|
do {
|
|
|
|
*dst = *src++;
|
|
|
|
dst += w;
|
|
|
|
if (!--h_cur) {
|
|
|
|
if (++cur == 0)
|
|
|
|
cur = -0x80;
|
|
|
|
goto next_line;
|
|
|
|
}
|
|
|
|
} while (++cur != 0);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
2005-11-08 11:34:56 +00:00
|
|
|
cur = *src++;
|
|
|
|
}
|
|
|
|
next_line:
|
|
|
|
dst_org++;
|
|
|
|
} while (--w_cur);
|
2002-06-29 16:11:13 +00:00
|
|
|
|
|
|
|
|
2005-11-08 11:34:56 +00:00
|
|
|
src_org = dst_org = _videoBuf1 + w;
|
|
|
|
|
|
|
|
do {
|
|
|
|
byte *dst = dst_org;
|
|
|
|
for (i = 0; i != w; ++i) {
|
|
|
|
byte b = src_org[i];
|
|
|
|
b = (b >> 4) | (b << 4);
|
|
|
|
*--dst = b;
|
|
|
|
}
|
|
|
|
|
|
|
|
src_org += w;
|
|
|
|
dst_org += w;
|
|
|
|
} while (--h);
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
return _videoBuf1;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
byte *AGOSEngine::vc10_flip(const byte *src, uint w, uint h) {
|
2005-05-06 11:37:33 +00:00
|
|
|
if (src == _vc10BasePtrOld)
|
|
|
|
return _videoBuf1;
|
2003-07-30 09:36:48 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
_vc10BasePtrOld = src;
|
2003-07-30 09:36:48 +00:00
|
|
|
|
2005-11-08 11:34:56 +00:00
|
|
|
byte *dst_org, *src_org;
|
|
|
|
uint i;
|
|
|
|
|
|
|
|
w *= 8;
|
|
|
|
src_org = dst_org = _videoBuf1 + w;
|
|
|
|
|
2003-07-30 09:36:48 +00:00
|
|
|
do {
|
2005-11-08 11:34:56 +00:00
|
|
|
byte *dst = dst_org;
|
|
|
|
for (i = 0; i != w; ++i) {
|
|
|
|
byte b = src_org[i];
|
|
|
|
b = (b >> 4) | (b << 4);
|
|
|
|
*--dst = b;
|
|
|
|
}
|
|
|
|
|
|
|
|
src_org += w;
|
|
|
|
dst_org += w;
|
|
|
|
} while (--h);
|
2003-07-30 09:36:48 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
return _videoBuf1;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* must not be const */
|
|
|
|
static uint16 _video_windows[128] = {
|
2006-09-28 23:22:07 +00:00
|
|
|
0, 0, 20, 200,
|
|
|
|
0, 0, 3, 136,
|
|
|
|
17, 0, 3, 136,
|
|
|
|
0, 0, 20, 200,
|
|
|
|
0, 0, 20, 134
|
2002-06-29 16:11:13 +00:00
|
|
|
};
|
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
/* Elvira 1/2 & Waxworks
|
|
|
|
static uint16 _video_windows[128] = {
|
|
|
|
3, 0, 14, 136,
|
|
|
|
0, 0, 3, 136,
|
|
|
|
17, 0, 3, 136,
|
|
|
|
0, 0, 20, 200,
|
|
|
|
3, 3, 14, 127,
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::decodeColumn(byte *dst, const byte *src, int height) {
|
2005-05-06 11:37:33 +00:00
|
|
|
const uint pitch = _dxSurfacePitch;
|
2002-06-29 16:11:13 +00:00
|
|
|
int8 reps = (int8)0x80;
|
|
|
|
byte color;
|
|
|
|
byte *dst_org = dst;
|
2003-03-07 03:26:30 +00:00
|
|
|
uint h = height, w = 8;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
|
|
|
for (;;) {
|
2002-06-29 16:11:13 +00:00
|
|
|
reps = *src++;
|
|
|
|
if (reps >= 0) {
|
|
|
|
color = *src++;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
|
|
|
do {
|
2002-06-29 16:11:13 +00:00
|
|
|
*dst = color;
|
|
|
|
dst += pitch;
|
|
|
|
|
|
|
|
/* reached bottom? */
|
|
|
|
if (--h == 0) {
|
2002-07-07 19:06:48 +00:00
|
|
|
/* reached right edge? */
|
2002-06-29 16:11:13 +00:00
|
|
|
if (--w == 0)
|
|
|
|
return;
|
|
|
|
dst = ++dst_org;
|
2003-03-07 03:26:30 +00:00
|
|
|
h = height;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
2002-07-07 19:06:48 +00:00
|
|
|
} while (--reps >= 0);
|
2002-06-29 16:11:13 +00:00
|
|
|
} else {
|
2002-07-07 19:06:48 +00:00
|
|
|
|
|
|
|
do {
|
2002-06-29 16:11:13 +00:00
|
|
|
*dst = *src++;
|
|
|
|
dst += pitch;
|
|
|
|
|
|
|
|
/* reached bottom? */
|
|
|
|
if (--h == 0) {
|
2002-07-07 19:06:48 +00:00
|
|
|
/* reached right edge? */
|
2002-06-29 16:11:13 +00:00
|
|
|
if (--w == 0)
|
|
|
|
return;
|
|
|
|
dst = ++dst_org;
|
2003-03-07 03:26:30 +00:00
|
|
|
h = height;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
} while (++reps != 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::decodeRow(byte *dst, const byte *src, int width) {
|
2006-04-08 00:12:16 +00:00
|
|
|
const uint pitch = _dxSurfacePitch;
|
|
|
|
int8 reps = (int8)0x80;
|
|
|
|
byte color;
|
|
|
|
byte *dst_org = dst;
|
|
|
|
uint w = width, h = 8;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
reps = *src++;
|
|
|
|
if (reps >= 0) {
|
|
|
|
color = *src++;
|
|
|
|
|
|
|
|
do {
|
|
|
|
*dst++ = color;
|
|
|
|
|
|
|
|
/* reached right edge? */
|
|
|
|
if (--w == 0) {
|
|
|
|
/* reached bottom? */
|
|
|
|
if (--h == 0)
|
|
|
|
return;
|
|
|
|
dst_org += pitch;
|
|
|
|
dst = dst_org;
|
|
|
|
w = width;
|
|
|
|
}
|
|
|
|
} while (--reps >= 0);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
do {
|
|
|
|
*dst++ = *src++;
|
|
|
|
|
|
|
|
/* reached right edge? */
|
|
|
|
if (--w == 0) {
|
|
|
|
/* reached bottom? */
|
|
|
|
if (--h == 0)
|
|
|
|
return;
|
|
|
|
dst_org += pitch;
|
|
|
|
dst = dst_org;
|
|
|
|
w = width;
|
|
|
|
}
|
|
|
|
} while (++reps != 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc10_draw() {
|
2002-06-29 16:11:13 +00:00
|
|
|
byte *p2;
|
2002-07-07 19:06:48 +00:00
|
|
|
uint width, height;
|
2002-06-29 16:11:13 +00:00
|
|
|
byte flags;
|
|
|
|
VC10_state state;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
state.image = (int16)vcReadNextWord();
|
2002-07-07 19:06:48 +00:00
|
|
|
if (state.image == 0)
|
2002-06-29 16:11:13 +00:00
|
|
|
return;
|
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2005-11-11 09:05:19 +00:00
|
|
|
state.palette = (_vcPtr[0] * 16);
|
2006-09-19 11:59:13 +00:00
|
|
|
_vcPtr += 2;
|
|
|
|
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
|
2005-11-11 09:05:19 +00:00
|
|
|
state.palette = (_vcPtr[1] * 16);
|
2006-09-19 11:59:13 +00:00
|
|
|
_vcPtr += 2;
|
|
|
|
} else {
|
|
|
|
state.palette = 0;
|
2005-11-11 09:05:19 +00:00
|
|
|
}
|
2006-09-19 11:59:13 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
state.x = (int16)vcReadNextWord();
|
2006-02-16 22:35:43 +00:00
|
|
|
state.x -= _scrollX;
|
2005-11-05 18:47:03 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
state.y = (int16)vcReadNextWord();
|
2006-02-16 22:35:43 +00:00
|
|
|
state.y -= _scrollY;
|
2006-02-14 21:20:10 +00:00
|
|
|
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) {
|
2005-12-13 00:20:11 +00:00
|
|
|
state.flags = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
} else {
|
2005-12-13 00:20:11 +00:00
|
|
|
state.flags = vcReadNextByte();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (state.image < 0)
|
2005-12-13 00:20:11 +00:00
|
|
|
state.image = vcReadVar(-state.image);
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
p2 = _curVgaFile2 + state.image * 8;
|
2006-04-07 14:40:33 +00:00
|
|
|
state.depack_src = _curVgaFile2 + readUint32Wrapper(p2);
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2005-10-07 06:59:49 +00:00
|
|
|
width = READ_LE_UINT16(p2 + 6);
|
2005-11-11 02:56:36 +00:00
|
|
|
height = READ_LE_UINT16(p2 + 4) & 0x7FFF;
|
2005-11-08 11:34:56 +00:00
|
|
|
flags = p2[5];
|
2005-10-07 06:59:49 +00:00
|
|
|
} else {
|
2005-11-11 09:05:19 +00:00
|
|
|
width = READ_BE_UINT16(p2 + 6) / 16;
|
2005-11-08 11:34:56 +00:00
|
|
|
height = p2[5];
|
|
|
|
flags = p2[4];
|
2005-10-07 06:59:49 +00:00
|
|
|
}
|
|
|
|
|
2002-07-07 19:06:48 +00:00
|
|
|
if (height == 0 || width == 0)
|
2002-06-29 16:11:13 +00:00
|
|
|
return;
|
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
if (_dumpImages)
|
2006-04-10 23:44:17 +00:00
|
|
|
dump_single_bitmap(_vgaCurZoneNum, state.image, state.depack_src, width, height,
|
2005-10-05 11:37:26 +00:00
|
|
|
state.palette);
|
2006-03-16 03:48:42 +00:00
|
|
|
// Check if image is compressed
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2006-02-16 22:49:26 +00:00
|
|
|
if (flags & 0x80) {
|
2006-03-16 03:48:42 +00:00
|
|
|
state.flags |= kDFCompressed;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
2006-02-16 22:49:26 +00:00
|
|
|
} else {
|
2006-03-16 03:48:42 +00:00
|
|
|
if (flags & 0x80 && !(state.flags & kDFCompressedFlip)) {
|
|
|
|
if (state.flags & kDFFlip) {
|
|
|
|
state.flags &= ~kDFFlip;
|
|
|
|
state.flags |= kDFCompressedFlip;
|
2006-02-16 22:49:26 +00:00
|
|
|
} else {
|
2006-03-16 03:48:42 +00:00
|
|
|
state.flags |= kDFCompressed;
|
2006-02-16 22:49:26 +00:00
|
|
|
}
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-04-07 14:27:28 +00:00
|
|
|
state.width = state.draw_width = width; /* cl */
|
|
|
|
state.height = state.draw_height = height; /* ch */
|
2006-04-06 06:14:47 +00:00
|
|
|
|
2006-04-07 14:27:28 +00:00
|
|
|
state.depack_cont = -0x80;
|
2006-04-06 06:14:47 +00:00
|
|
|
|
2006-04-07 14:27:28 +00:00
|
|
|
state.x_skip = 0; /* colums to skip = bh */
|
|
|
|
state.y_skip = 0; /* rows to skip = bl */
|
2006-04-06 06:14:47 +00:00
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
uint maxWidth = (getGameType() == GType_FF || getGameType() == GType_PP) ? 640 : 20;
|
2006-04-07 14:27:28 +00:00
|
|
|
if ((getGameType() == GType_SIMON2 || getGameType() == GType_FF) && width > maxWidth) {
|
|
|
|
horizontalScroll(&state);
|
|
|
|
return;
|
2006-01-11 04:06:51 +00:00
|
|
|
}
|
2006-04-07 14:27:28 +00:00
|
|
|
if (getGameType() == GType_FF && height > 480) {
|
|
|
|
verticalScroll(&state);
|
2002-07-07 19:06:48 +00:00
|
|
|
return;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2 || getGameType() == GType_WW) {
|
2006-03-16 03:48:42 +00:00
|
|
|
if (state.flags & kDFCompressedFlip) {
|
2005-11-11 09:05:19 +00:00
|
|
|
state.depack_src = vc10_uncompressFlip(state.depack_src, width, height);
|
2006-03-16 03:48:42 +00:00
|
|
|
} else if (state.flags & kDFFlip) {
|
2005-11-11 09:05:19 +00:00
|
|
|
state.depack_src = vc10_flip(state.depack_src, width, height);
|
|
|
|
}
|
2003-05-25 03:03:40 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-03-22 13:54:26 +00:00
|
|
|
state.surf2_addr = getFrontBuf();
|
2006-02-16 22:35:43 +00:00
|
|
|
state.surf2_pitch = _dxSurfacePitch;
|
|
|
|
|
2006-03-22 13:54:26 +00:00
|
|
|
state.surf_addr = getBackBuf();
|
2006-02-16 22:35:43 +00:00
|
|
|
state.surf_pitch = _dxSurfacePitch;
|
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2006-02-16 22:35:43 +00:00
|
|
|
drawImages_Feeble(&state);
|
|
|
|
} else {
|
|
|
|
drawImages(&state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
bool AGOSEngine::drawImages_clip(VC10_state *state) {
|
2006-02-16 22:35:43 +00:00
|
|
|
const uint16 *vlut;
|
|
|
|
uint maxWidth, maxHeight;
|
|
|
|
int cur;
|
|
|
|
|
|
|
|
vlut = &_video_windows[_windowNum * 4];
|
|
|
|
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2 || getGameType() == GType_WW) {
|
2006-02-16 22:35:43 +00:00
|
|
|
state->draw_width = state->width * 2;
|
2005-11-13 11:53:57 +00:00
|
|
|
}
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-02-16 22:35:43 +00:00
|
|
|
cur = state->x;
|
2002-06-29 16:11:13 +00:00
|
|
|
if (cur < 0) {
|
|
|
|
do {
|
2006-02-16 22:35:43 +00:00
|
|
|
if (!--state->draw_width)
|
|
|
|
return 0;
|
|
|
|
state->x_skip++;
|
2002-07-07 19:06:48 +00:00
|
|
|
} while (++cur);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
2006-02-16 22:35:43 +00:00
|
|
|
state->x = cur;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-29 06:16:28 +00:00
|
|
|
maxWidth = (getGameType() == GType_FF || getGameType() == GType_PP) ? _screenWidth : (vlut[2] * 2);
|
2006-02-16 22:35:43 +00:00
|
|
|
cur += state->draw_width - maxWidth;
|
2002-06-29 16:11:13 +00:00
|
|
|
if (cur > 0) {
|
|
|
|
do {
|
2006-02-16 22:35:43 +00:00
|
|
|
if (!--state->draw_width)
|
|
|
|
return 0;
|
2002-06-29 16:11:13 +00:00
|
|
|
} while (--cur);
|
|
|
|
}
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-02-16 22:35:43 +00:00
|
|
|
cur = state->y;
|
2002-06-29 16:11:13 +00:00
|
|
|
if (cur < 0) {
|
|
|
|
do {
|
2006-02-16 22:35:43 +00:00
|
|
|
if (!--state->draw_height)
|
|
|
|
return 0;
|
|
|
|
state->y_skip++;
|
2002-07-07 19:06:48 +00:00
|
|
|
} while (++cur);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
2006-02-16 22:35:43 +00:00
|
|
|
state->y = cur;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-29 06:16:28 +00:00
|
|
|
maxHeight = (getGameType() == GType_FF || getGameType() == GType_PP) ? _screenHeight : vlut[3];
|
2006-02-16 22:35:43 +00:00
|
|
|
cur += state->draw_height - maxHeight;
|
2002-06-29 16:11:13 +00:00
|
|
|
if (cur > 0) {
|
|
|
|
do {
|
2006-02-16 22:35:43 +00:00
|
|
|
if (!--state->draw_height)
|
|
|
|
return 0;
|
2002-06-29 16:11:13 +00:00
|
|
|
} while (--cur);
|
|
|
|
}
|
|
|
|
|
2006-02-16 22:35:43 +00:00
|
|
|
assert(state->draw_width != 0 && state->draw_height != 0);
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2 || getGameType() == GType_WW) {
|
2006-02-16 22:35:43 +00:00
|
|
|
state->draw_width *= 4;
|
2005-11-19 11:37:41 +00:00
|
|
|
}
|
|
|
|
|
2006-02-16 22:35:43 +00:00
|
|
|
return 1;
|
2005-11-19 11:37:41 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::drawImages_Feeble(VC10_state *state) {
|
2006-03-16 03:48:42 +00:00
|
|
|
if (state->flags & kDFCompressed) {
|
|
|
|
if (state->flags & kDFScaled) {
|
2006-03-16 04:10:34 +00:00
|
|
|
state->surf_addr = getScaleBuf();
|
2006-03-16 03:15:05 +00:00
|
|
|
state->surf_pitch = _dxSurfacePitch;
|
|
|
|
|
|
|
|
uint w, h;
|
|
|
|
byte *src, *dst, *dst_org;
|
|
|
|
|
|
|
|
state->dl = state->width;
|
|
|
|
state->dh = state->height;
|
|
|
|
|
|
|
|
dst_org = state->surf_addr;
|
|
|
|
w = 0;
|
|
|
|
do {
|
2006-04-14 09:57:43 +00:00
|
|
|
src = vc10_depackColumn(state);
|
2006-03-16 03:15:05 +00:00
|
|
|
dst = dst_org;
|
|
|
|
|
|
|
|
h = 0;
|
|
|
|
do {
|
2006-03-22 08:56:10 +00:00
|
|
|
*dst = *src;
|
2006-03-16 03:15:05 +00:00
|
|
|
dst += _screenWidth;
|
2006-03-22 08:56:10 +00:00
|
|
|
src++;
|
2006-03-16 03:15:05 +00:00
|
|
|
} while (++h != state->draw_height);
|
|
|
|
dst_org++;
|
|
|
|
} while (++w != state->draw_width);
|
|
|
|
|
2006-03-22 23:38:16 +00:00
|
|
|
if (_vgaCurSpritePriority % 10 != 9) {
|
2006-03-16 03:15:05 +00:00
|
|
|
_scaleX = state->x;
|
|
|
|
_scaleY = state->y;
|
|
|
|
_scaleWidth = state->width;
|
2006-03-16 10:30:59 +00:00
|
|
|
_scaleHeight = state->height;
|
2006-03-16 03:15:05 +00:00
|
|
|
} else {
|
2006-03-22 11:57:46 +00:00
|
|
|
scaleClip(state->height, state->width, state->y, state->x, state->y + _scrollY);
|
2006-03-16 03:15:05 +00:00
|
|
|
}
|
2006-03-22 13:54:26 +00:00
|
|
|
} else if (state->flags & kDFOverlayed) {
|
2006-03-16 04:10:34 +00:00
|
|
|
state->surf_addr = getScaleBuf();
|
2006-03-16 03:15:05 +00:00
|
|
|
state->surf_pitch = _dxSurfacePitch;
|
2006-04-07 13:39:59 +00:00
|
|
|
state->surf_addr += (state->x + _scrollX) + (state->y + _scrollY) * state->surf_pitch;
|
2006-03-16 03:15:05 +00:00
|
|
|
|
|
|
|
uint w, h;
|
|
|
|
byte *src, *dst, *dst_org;
|
|
|
|
|
|
|
|
state->dl = state->width;
|
|
|
|
state->dh = state->height;
|
|
|
|
|
|
|
|
dst_org = state->surf_addr;
|
|
|
|
w = 0;
|
|
|
|
do {
|
|
|
|
byte color;
|
|
|
|
|
2006-04-14 09:57:43 +00:00
|
|
|
src = vc10_depackColumn(state);
|
2006-03-16 03:15:05 +00:00
|
|
|
dst = dst_org;
|
2005-11-19 11:37:41 +00:00
|
|
|
|
2006-03-16 03:15:05 +00:00
|
|
|
h = 0;
|
|
|
|
do {
|
|
|
|
color = *src;
|
|
|
|
if (color != 0)
|
|
|
|
*dst = color;
|
|
|
|
dst += _screenWidth;
|
|
|
|
src++;
|
|
|
|
} while (++h != state->draw_height);
|
|
|
|
dst_org++;
|
|
|
|
} while (++w != state->draw_width);
|
|
|
|
|
2006-03-22 23:38:16 +00:00
|
|
|
if (_vgaCurSpritePriority % 10 == 9) {
|
2006-03-22 11:57:46 +00:00
|
|
|
scaleClip(_scaleHeight, _scaleWidth, _scaleY, _scaleX, _scaleY + _scrollY);
|
2006-03-16 03:15:05 +00:00
|
|
|
}
|
2006-02-16 22:35:43 +00:00
|
|
|
} else {
|
|
|
|
if (drawImages_clip(state) == 0)
|
|
|
|
return;
|
2005-11-19 11:37:41 +00:00
|
|
|
|
2006-02-16 22:35:43 +00:00
|
|
|
state->surf_addr += state->x + state->y * state->surf_pitch;
|
2005-11-19 11:37:41 +00:00
|
|
|
|
2006-02-16 22:35:43 +00:00
|
|
|
uint w, h;
|
|
|
|
byte *src, *dst, *dst_org;
|
2005-11-19 11:37:41 +00:00
|
|
|
|
2006-03-23 04:49:03 +00:00
|
|
|
state->dl = state->width;
|
|
|
|
state->dh = state->height;
|
|
|
|
|
|
|
|
vc10_skip_cols(state);
|
|
|
|
|
|
|
|
|
2006-03-16 03:48:42 +00:00
|
|
|
if (state->flags & kDFMasked) {
|
2006-09-29 06:16:28 +00:00
|
|
|
if (getGameType() == GType_FF && !getBitFlag(81)) {
|
2006-03-16 03:15:05 +00:00
|
|
|
if (state->x > _feebleRect.right)
|
|
|
|
return;
|
|
|
|
if (state->y > _feebleRect.bottom)
|
|
|
|
return;
|
|
|
|
if (state->x + state->width < _feebleRect.left)
|
|
|
|
return;
|
|
|
|
if (state->y + state->height < _feebleRect.top)
|
|
|
|
return;
|
2006-02-16 22:35:43 +00:00
|
|
|
}
|
2005-11-19 11:37:41 +00:00
|
|
|
|
2006-02-16 22:35:43 +00:00
|
|
|
dst_org = state->surf_addr;
|
|
|
|
w = 0;
|
|
|
|
do {
|
|
|
|
byte color;
|
2005-11-19 11:37:41 +00:00
|
|
|
|
2006-04-14 09:57:43 +00:00
|
|
|
src = vc10_depackColumn(state);
|
2006-02-16 22:35:43 +00:00
|
|
|
dst = dst_org;
|
|
|
|
|
|
|
|
h = 0;
|
|
|
|
do {
|
|
|
|
color = *src;
|
|
|
|
if (color)
|
|
|
|
*dst = color;
|
|
|
|
dst += _screenWidth;
|
|
|
|
src++;
|
|
|
|
} while (++h != state->draw_height);
|
|
|
|
dst_org++;
|
|
|
|
} while (++w != state->draw_width);
|
|
|
|
} else {
|
|
|
|
dst_org = state->surf_addr;
|
|
|
|
w = 0;
|
2006-02-16 16:39:45 +00:00
|
|
|
do {
|
2006-02-16 22:35:43 +00:00
|
|
|
byte color;
|
2006-02-16 16:39:45 +00:00
|
|
|
|
2006-04-14 09:57:43 +00:00
|
|
|
src = vc10_depackColumn(state);
|
2006-02-16 22:35:43 +00:00
|
|
|
dst = dst_org;
|
|
|
|
|
|
|
|
h = 0;
|
|
|
|
do {
|
|
|
|
color = *src;
|
2006-03-16 03:48:42 +00:00
|
|
|
if ((state->flags & kDFNonTrans) || color != 0)
|
2006-02-16 22:35:43 +00:00
|
|
|
*dst = color;
|
|
|
|
dst += _screenWidth;
|
|
|
|
src++;
|
|
|
|
} while (++h != state->draw_height);
|
|
|
|
dst_org++;
|
|
|
|
} while (++w != state->draw_width);
|
|
|
|
}
|
2006-02-16 16:39:45 +00:00
|
|
|
}
|
|
|
|
} else {
|
2006-02-16 22:35:43 +00:00
|
|
|
if (drawImages_clip(state) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
state->surf_addr += state->x + state->y * state->surf_pitch;
|
|
|
|
|
2006-02-16 16:39:45 +00:00
|
|
|
const byte *src;
|
|
|
|
byte *dst;
|
|
|
|
uint count;
|
|
|
|
|
|
|
|
src = state->depack_src + state->width * state->y_skip;
|
|
|
|
dst = state->surf_addr;
|
2006-02-16 22:35:43 +00:00
|
|
|
do {
|
|
|
|
for (count = 0; count != state->draw_width; count++) {
|
|
|
|
byte color;
|
|
|
|
color = src[count + state->x_skip];
|
|
|
|
if (color) {
|
2006-03-16 03:48:42 +00:00
|
|
|
if ((state->flags & kDFShaded) && color == 220)
|
2006-02-16 22:35:43 +00:00
|
|
|
color = 244;
|
2006-02-16 16:39:45 +00:00
|
|
|
|
2006-02-16 22:35:43 +00:00
|
|
|
dst[count] = color;
|
2006-02-16 16:39:45 +00:00
|
|
|
}
|
2006-02-16 22:35:43 +00:00
|
|
|
}
|
|
|
|
dst += _screenWidth;
|
|
|
|
src += state->width;
|
|
|
|
} while (--state->draw_height);
|
|
|
|
}
|
2005-11-19 11:37:41 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::drawImages(VC10_state *state) {
|
2005-11-19 11:37:41 +00:00
|
|
|
const uint16 *vlut = &_video_windows[_windowNum * 4];
|
|
|
|
|
2006-02-16 22:35:43 +00:00
|
|
|
if (drawImages_clip(state) == 0)
|
|
|
|
return;
|
|
|
|
|
2005-11-19 11:37:41 +00:00
|
|
|
uint offs, offs2;
|
|
|
|
// Allow one section of Simon the Sorcerer 1 introduction to be displayed
|
|
|
|
// in lower half of screen
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_WW) {
|
|
|
|
//if (_windowNum == 4 || _windowNum >= 10) {
|
|
|
|
offs = state->x * 8;
|
|
|
|
offs2 = state->y;
|
|
|
|
//} else {
|
|
|
|
// offs = ((vlut[0] - _video_windows[16]) * 2 + state->x) * 8;
|
|
|
|
// offs2 = (vlut[1] - _video_windows[17] + state->y);
|
|
|
|
//}
|
|
|
|
} else if (getGameType() == GType_SIMON1) {
|
|
|
|
if (_windowNum != 2 || _windowNum != 3) {
|
|
|
|
offs = ((vlut[0]) * 2 + state->x) * 8;
|
|
|
|
offs2 = (vlut[1] + state->y);
|
|
|
|
} else {
|
|
|
|
offs = ((vlut[0] - _video_windows[16]) * 2 + state->x) * 8;
|
|
|
|
offs2 = (vlut[1] - _video_windows[17] + state->y);
|
|
|
|
}
|
2005-11-19 11:37:41 +00:00
|
|
|
} else {
|
|
|
|
offs = ((vlut[0] - _video_windows[16]) * 2 + state->x) * 8;
|
|
|
|
offs2 = (vlut[1] - _video_windows[17] + state->y);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2005-11-19 11:37:41 +00:00
|
|
|
state->surf2_addr += offs + offs2 * state->surf2_pitch;
|
|
|
|
state->surf_addr += offs + offs2 * state->surf_pitch;
|
|
|
|
|
2006-03-16 03:48:42 +00:00
|
|
|
if (state->flags & kDFMasked) {
|
2002-06-29 16:11:13 +00:00
|
|
|
byte *mask, *src, *dst;
|
|
|
|
byte h;
|
|
|
|
uint w;
|
|
|
|
|
2005-11-19 11:37:41 +00:00
|
|
|
state->x_skip *= 4;
|
|
|
|
state->dl = state->width;
|
|
|
|
state->dh = state->height;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2005-11-19 11:37:41 +00:00
|
|
|
vc10_skip_cols(state);
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2002-06-29 16:11:13 +00:00
|
|
|
w = 0;
|
|
|
|
do {
|
2006-04-14 09:57:43 +00:00
|
|
|
mask = vc10_depackColumn(state); /* esi */
|
2005-11-19 11:37:41 +00:00
|
|
|
src = state->surf2_addr + w * 2; /* ebx */
|
2006-03-22 13:54:26 +00:00
|
|
|
dst = state->surf_addr + w * 2; /* edi */
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-11-19 11:37:41 +00:00
|
|
|
h = state->draw_height;
|
2006-04-04 10:12:22 +00:00
|
|
|
if ((getGameType() == GType_SIMON1) && getBitFlag(88)) {
|
2003-07-30 16:25:05 +00:00
|
|
|
/* transparency */
|
|
|
|
do {
|
|
|
|
if (mask[0] & 0xF0) {
|
|
|
|
if ((dst[0] & 0x0F0) == 0x20)
|
|
|
|
dst[0] = src[0];
|
|
|
|
}
|
|
|
|
if (mask[0] & 0x0F) {
|
|
|
|
if ((dst[1] & 0x0F0) == 0x20)
|
|
|
|
dst[1] = src[1];
|
|
|
|
}
|
|
|
|
mask++;
|
2005-11-19 11:37:41 +00:00
|
|
|
dst += state->surf_pitch;
|
|
|
|
src += state->surf2_pitch;
|
2003-07-30 16:25:05 +00:00
|
|
|
} while (--h);
|
|
|
|
} else {
|
|
|
|
/* no transparency */
|
|
|
|
do {
|
|
|
|
if (mask[0] & 0xF0)
|
|
|
|
dst[0] = src[0];
|
|
|
|
if (mask[0] & 0x0F)
|
|
|
|
dst[1] = src[1];
|
|
|
|
mask++;
|
2005-11-19 11:37:41 +00:00
|
|
|
dst += state->surf_pitch;
|
|
|
|
src += state->surf2_pitch;
|
2003-07-30 16:25:05 +00:00
|
|
|
} while (--h);
|
|
|
|
}
|
2005-11-19 11:37:41 +00:00
|
|
|
} while (++w != state->draw_width);
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 13:22:48 +00:00
|
|
|
/* vc10_helper_5 */
|
2006-09-19 11:59:13 +00:00
|
|
|
} else if ((((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) &&
|
|
|
|
getGameType() != GType_WW) {
|
2004-12-18 01:33:21 +00:00
|
|
|
const byte *src;
|
|
|
|
byte *dst;
|
2002-07-07 19:06:48 +00:00
|
|
|
uint h, i;
|
|
|
|
|
2006-06-05 09:30:05 +00:00
|
|
|
if (state->flags & kDFCompressed) {
|
2005-11-19 11:37:41 +00:00
|
|
|
byte *dst_org = state->surf_addr;
|
|
|
|
src = state->depack_src;
|
2002-06-29 16:11:13 +00:00
|
|
|
/* AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE
|
|
|
|
* aaaaabbb bbcccccd ddddeeee efffffgg ggghhhhh
|
|
|
|
*/
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-06-05 09:30:05 +00:00
|
|
|
do {
|
|
|
|
uint count = state->draw_width / 4;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-06-05 09:30:05 +00:00
|
|
|
dst = dst_org;
|
|
|
|
do {
|
|
|
|
uint32 bits = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | (src[3]);
|
|
|
|
byte color;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-06-05 09:30:05 +00:00
|
|
|
color = (byte)((bits >> (32 - 5)) & 31);
|
|
|
|
if ((state->flags & kDFNonTrans) || color)
|
|
|
|
dst[0] = color;
|
|
|
|
color = (byte)((bits >> (32 - 10)) & 31);
|
|
|
|
if ((state->flags & kDFNonTrans) || color)
|
|
|
|
dst[1] = color;
|
|
|
|
color = (byte)((bits >> (32 - 15)) & 31);
|
|
|
|
if ((state->flags & kDFNonTrans) || color)
|
|
|
|
dst[2] = color;
|
|
|
|
color = (byte)((bits >> (32 - 20)) & 31);
|
|
|
|
if ((state->flags & kDFNonTrans) || color)
|
|
|
|
dst[3] = color;
|
|
|
|
color = (byte)((bits >> (32 - 25)) & 31);
|
|
|
|
if ((state->flags & kDFNonTrans) || color)
|
|
|
|
dst[4] = color;
|
|
|
|
color = (byte)((bits >> (32 - 30)) & 31);
|
|
|
|
if ((state->flags & kDFNonTrans) || color)
|
|
|
|
dst[5] = color;
|
|
|
|
|
|
|
|
bits = (bits << 8) | src[4];
|
|
|
|
|
|
|
|
color = (byte)((bits >> (40 - 35)) & 31);
|
|
|
|
if ((state->flags & kDFNonTrans) || color)
|
|
|
|
dst[6] = color;
|
|
|
|
color = (byte)((bits) & 31);
|
|
|
|
if ((state->flags & kDFNonTrans) || color)
|
|
|
|
dst[7] = color;
|
|
|
|
|
|
|
|
dst += 8;
|
|
|
|
src += 5;
|
|
|
|
} while (--count);
|
|
|
|
dst_org += _screenWidth;
|
|
|
|
} while (--state->draw_height);
|
|
|
|
} else {
|
|
|
|
src = state->depack_src + (state->width * state->y_skip * 16) + (state->x_skip * 8);
|
|
|
|
dst = state->surf_addr;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-06-05 09:30:05 +00:00
|
|
|
state->draw_width *= 2;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-06-05 09:30:05 +00:00
|
|
|
h = state->draw_height;
|
|
|
|
do {
|
|
|
|
for (i = 0; i != state->draw_width; i++)
|
|
|
|
if ((state->flags & kDFNonTrans) || src[i])
|
|
|
|
dst[i] = src[i];
|
|
|
|
dst += _screenWidth;
|
|
|
|
src += state->width * 16;
|
|
|
|
} while (--h);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
2005-05-06 13:22:48 +00:00
|
|
|
/* vc10_helper_4 */
|
2002-06-29 16:11:13 +00:00
|
|
|
} else {
|
2006-04-05 00:37:42 +00:00
|
|
|
if (getGameType() == GType_SIMON2 && state->flags & kDFUseFrontBuf && getBitFlag(171)) {
|
2005-11-19 11:37:41 +00:00
|
|
|
state->surf_addr = state->surf2_addr;
|
|
|
|
state->surf_pitch = state->surf2_pitch;
|
2002-07-07 19:06:48 +00:00
|
|
|
}
|
|
|
|
|
2006-03-16 03:48:42 +00:00
|
|
|
if (state->flags & kDFCompressed) {
|
2002-07-07 19:06:48 +00:00
|
|
|
uint w, h;
|
|
|
|
byte *src, *dst, *dst_org;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-11-19 11:37:41 +00:00
|
|
|
state->x_skip *= 4; /* reached */
|
2005-11-13 11:53:57 +00:00
|
|
|
|
2005-11-19 11:37:41 +00:00
|
|
|
state->dl = state->width;
|
|
|
|
state->dh = state->height;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-11-19 11:37:41 +00:00
|
|
|
vc10_skip_cols(state);
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-06-05 09:30:05 +00:00
|
|
|
dst_org = state->surf_addr;
|
|
|
|
if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */
|
|
|
|
dst_org += vcReadVar(252);
|
|
|
|
}
|
|
|
|
w = 0;
|
|
|
|
do {
|
|
|
|
byte color;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-06-05 09:30:05 +00:00
|
|
|
src = vc10_depackColumn(state);
|
|
|
|
dst = dst_org;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-06-05 09:30:05 +00:00
|
|
|
h = 0;
|
|
|
|
do {
|
|
|
|
color = (*src / 16);
|
|
|
|
if ((state->flags & kDFNonTrans) || color != 0)
|
|
|
|
dst[0] = color | state->palette;
|
|
|
|
color = (*src & 15);
|
|
|
|
if ((state->flags & kDFNonTrans) || color != 0)
|
|
|
|
dst[1] = color | state->palette;
|
|
|
|
dst += _screenWidth;
|
|
|
|
src++;
|
|
|
|
} while (++h != state->draw_height);
|
|
|
|
dst_org += 2;
|
|
|
|
} while (++w != state->draw_width);
|
2005-05-06 13:22:48 +00:00
|
|
|
/* vc10_helper_6 */
|
2002-06-29 16:11:13 +00:00
|
|
|
} else {
|
2004-12-18 01:33:21 +00:00
|
|
|
const byte *src;
|
|
|
|
byte *dst;
|
2002-06-29 16:11:13 +00:00
|
|
|
uint count;
|
|
|
|
|
2005-11-19 11:37:41 +00:00
|
|
|
src = state->depack_src + (state->width * state->y_skip) * 8;
|
|
|
|
dst = state->surf_addr;
|
|
|
|
state->x_skip *= 4;
|
2006-06-05 09:30:05 +00:00
|
|
|
do {
|
|
|
|
for (count = 0; count != state->draw_width; count++) {
|
|
|
|
byte color;
|
|
|
|
color = (src[count + state->x_skip] / 16);
|
|
|
|
if ((state->flags & kDFNonTrans) || color)
|
|
|
|
dst[count * 2] = color | state->palette;
|
|
|
|
color = (src[count + state->x_skip] & 15);
|
|
|
|
if ((state->flags & kDFNonTrans) || color)
|
|
|
|
dst[count * 2 + 1] = color | state->palette;
|
|
|
|
}
|
|
|
|
dst += _screenWidth;
|
|
|
|
src += state->width * 8;
|
|
|
|
} while (--state->draw_height);
|
2005-05-06 13:22:48 +00:00
|
|
|
/* vc10_helper_7 */
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::horizontalScroll(VC10_state *state) {
|
2006-04-07 14:27:28 +00:00
|
|
|
const byte *src;
|
|
|
|
byte *dst;
|
|
|
|
int w;
|
|
|
|
|
|
|
|
if (getGameType() == GType_FF)
|
|
|
|
_scrollXMax = state->width - 640;
|
|
|
|
else
|
|
|
|
_scrollXMax = state->width * 2 - 40;
|
|
|
|
_scrollYMax = 0;
|
|
|
|
_scrollImage = state->depack_src;
|
|
|
|
_scrollHeight = state->height;
|
2006-04-15 22:14:39 +00:00
|
|
|
if (_variableArrayPtr[34] < 0)
|
|
|
|
state->x = _variableArrayPtr[251];
|
2006-04-07 14:27:28 +00:00
|
|
|
|
|
|
|
_scrollX = state->x;
|
|
|
|
|
|
|
|
vcWriteVar(251, _scrollX);
|
|
|
|
|
|
|
|
dst = getBackBuf();
|
|
|
|
|
|
|
|
if (getGameType() == GType_FF)
|
|
|
|
src = state->depack_src + _scrollX / 2;
|
|
|
|
else
|
|
|
|
src = state->depack_src + _scrollX * 4;
|
|
|
|
|
|
|
|
for (w = 0; w < _screenWidth; w += 8) {
|
2006-04-08 00:12:16 +00:00
|
|
|
decodeColumn(dst, src + readUint32Wrapper(src), state->height);
|
2006-04-07 14:27:28 +00:00
|
|
|
dst += 8;
|
|
|
|
src += 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::verticalScroll(VC10_state *state) {
|
2006-04-07 14:27:28 +00:00
|
|
|
const byte *src;
|
|
|
|
byte *dst;
|
|
|
|
int h;
|
|
|
|
|
|
|
|
_scrollXMax = 0;
|
|
|
|
_scrollYMax = state->height - 480;
|
|
|
|
_scrollImage = state->depack_src;
|
|
|
|
_scrollWidth = state->width;
|
2006-04-15 22:14:39 +00:00
|
|
|
if (_variableArrayPtr[34] < 0)
|
|
|
|
state->y = _variableArrayPtr[250];
|
2006-04-07 14:27:28 +00:00
|
|
|
|
|
|
|
_scrollY = state->y;
|
|
|
|
|
|
|
|
vcWriteVar(250, _scrollY);
|
|
|
|
|
|
|
|
dst = getBackBuf();
|
|
|
|
src = state->depack_src + _scrollY / 2;
|
|
|
|
|
|
|
|
for (h = 0; h < _screenHeight; h += 8) {
|
2006-04-08 00:12:16 +00:00
|
|
|
decodeRow(dst, src + READ_LE_UINT32(src), state->width);
|
|
|
|
dst += 8 * state->width;
|
2006-04-07 14:27:28 +00:00
|
|
|
src += 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) {
|
2006-04-07 14:27:28 +00:00
|
|
|
Common::Rect srcRect, dstRect;
|
|
|
|
float factor, xscale;
|
|
|
|
|
|
|
|
srcRect.left = 0;
|
|
|
|
srcRect.top = 0;
|
|
|
|
srcRect.right = w;
|
|
|
|
srcRect.bottom = h;
|
|
|
|
|
|
|
|
if (scrollY > _baseY)
|
|
|
|
factor = 1 + ((scrollY - _baseY) * _scale);
|
|
|
|
else
|
|
|
|
factor = 1 - ((_baseY - scrollY) * _scale);
|
|
|
|
|
|
|
|
xscale = ((w * factor) / 2);
|
|
|
|
|
|
|
|
dstRect.left = (int16)(x - xscale);
|
|
|
|
if (dstRect.left > _screenWidth - 1)
|
|
|
|
return;
|
|
|
|
dstRect.top = (int16)(y - (h * factor));
|
|
|
|
if (dstRect.top > _screenHeight - 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
dstRect.right = (int16)(x + xscale);
|
|
|
|
dstRect.bottom = y;
|
|
|
|
|
|
|
|
_feebleRect = dstRect;
|
|
|
|
|
|
|
|
_variableArray[20] = _feebleRect.top;
|
|
|
|
_variableArray[21] = _feebleRect.left;
|
|
|
|
_variableArray[22] = _feebleRect.bottom;
|
|
|
|
_variableArray[23] = _feebleRect.right;
|
|
|
|
|
2006-04-14 07:06:54 +00:00
|
|
|
debug(5, "Left %d Right %d Top %d Bottom %d", dstRect.left, dstRect.right, dstRect.top, dstRect.bottom);
|
2006-04-07 14:27:28 +00:00
|
|
|
|
|
|
|
// Unlike normal rectangles in ScummVM, it seems that in the case of
|
|
|
|
// the destination rectangle the bottom and right coordinates are
|
|
|
|
// considered to be inside the rectangle. For the source rectangle,
|
|
|
|
// I believe that they are not.
|
|
|
|
|
|
|
|
int scaledW = dstRect.width() + 1;
|
|
|
|
int scaledH = dstRect.height() + 1;
|
|
|
|
|
|
|
|
byte *src = getScaleBuf();
|
|
|
|
byte *dst = getBackBuf();
|
|
|
|
|
|
|
|
dst += _dxSurfacePitch * dstRect.top + dstRect.left;
|
|
|
|
|
2006-04-14 05:15:11 +00:00
|
|
|
for (int dstY = 0; dstY < scaledH; dstY++) {
|
2006-04-07 14:27:28 +00:00
|
|
|
if (dstRect.top + dstY >= 0 && dstRect.top + dstY < _screenHeight) {
|
|
|
|
int srcY = (dstY * h) / scaledH;
|
|
|
|
byte *srcPtr = src + _dxSurfacePitch * srcY;
|
|
|
|
byte *dstPtr = dst + _dxSurfacePitch * dstY;
|
2006-04-14 05:15:11 +00:00
|
|
|
for (int dstX = 0; dstX < scaledW; dstX++) {
|
2006-04-07 14:27:28 +00:00
|
|
|
if (dstRect.left + dstX >= 0 && dstRect.left + dstX < _screenWidth) {
|
|
|
|
int srcX = (dstX * w) / scaledW;
|
|
|
|
if (srcPtr[srcX])
|
|
|
|
dstPtr[dstX] = srcPtr[srcX];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc11_clearPathFinder() {
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_WW) {
|
|
|
|
// FIXME
|
|
|
|
vcReadNextWord();
|
|
|
|
} else {
|
|
|
|
memset(&_pathFindArray, 0, sizeof(_pathFindArray));
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc12_delay() {
|
2005-12-13 00:20:11 +00:00
|
|
|
VgaSprite *vsp = findCurSprite();
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 num;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2006-04-20 08:58:30 +00:00
|
|
|
num = vcReadNextByte();
|
|
|
|
} else if (getGameType() == GType_SIMON2) {
|
2005-12-13 00:20:11 +00:00
|
|
|
num = vcReadNextByte() * _frameRate;
|
2006-04-20 08:58:30 +00:00
|
|
|
} else {
|
|
|
|
num = vcReadVarOrWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2004-01-30 03:26:47 +00:00
|
|
|
// Work around to allow inventory arrows to be
|
|
|
|
// shown in some versions of Simon the Sorcerer 1
|
2005-11-13 07:04:56 +00:00
|
|
|
if ((getGameType() == GType_SIMON1) && vsp->id == 128)
|
2004-01-30 03:26:47 +00:00
|
|
|
num = 0;
|
|
|
|
else
|
2006-05-04 02:23:52 +00:00
|
|
|
num += _vgaBaseDelay;
|
2003-10-26 04:37:11 +00:00
|
|
|
|
2006-04-21 00:18:23 +00:00
|
|
|
addVgaEvent(num, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum);
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr = (byte *)&_vc_get_out_of_code;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc13_addToSpriteX() {
|
2005-12-13 00:20:11 +00:00
|
|
|
VgaSprite *vsp = findCurSprite();
|
|
|
|
vsp->x += (int16)vcReadNextWord();
|
2005-05-06 11:37:33 +00:00
|
|
|
_vgaSpriteChanged++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc14_addToSpriteY() {
|
2005-12-13 00:20:11 +00:00
|
|
|
VgaSprite *vsp = findCurSprite();
|
|
|
|
vsp->y += (int16)vcReadNextWord();
|
2005-05-06 11:37:33 +00:00
|
|
|
_vgaSpriteChanged++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc15_sync() {
|
2005-05-06 11:37:33 +00:00
|
|
|
VgaSleepStruct *vfs = _vgaSleepStructs, *vfs_tmp;
|
2005-12-13 00:20:11 +00:00
|
|
|
uint16 id = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
while (vfs->ident != 0) {
|
|
|
|
if (vfs->ident == id) {
|
2006-05-04 02:23:52 +00:00
|
|
|
addVgaEvent(_vgaBaseDelay, vfs->code_ptr, vfs->sprite_id, vfs->cur_vga_file);
|
2002-06-29 16:11:13 +00:00
|
|
|
vfs_tmp = vfs;
|
|
|
|
do {
|
|
|
|
memcpy(vfs_tmp, vfs_tmp + 1, sizeof(VgaSleepStruct));
|
|
|
|
vfs_tmp++;
|
|
|
|
} while (vfs_tmp->ident != 0);
|
|
|
|
} else {
|
|
|
|
vfs++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-06-01 12:06:53 +00:00
|
|
|
_lastVgaWaitFor = id;
|
2002-06-29 16:11:13 +00:00
|
|
|
/* clear a wait event */
|
2005-05-06 11:37:33 +00:00
|
|
|
if (id == _vgaWaitFor)
|
|
|
|
_vgaWaitFor = 0;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc16_waitSync() {
|
2005-05-06 11:37:33 +00:00
|
|
|
VgaSleepStruct *vfs = _vgaSleepStructs;
|
2002-06-29 16:11:13 +00:00
|
|
|
while (vfs->ident)
|
|
|
|
vfs++;
|
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
vfs->ident = vcReadNextWord();
|
2005-05-06 11:37:33 +00:00
|
|
|
vfs->code_ptr = _vcPtr;
|
|
|
|
vfs->sprite_id = _vgaCurSpriteId;
|
2006-04-10 23:44:17 +00:00
|
|
|
vfs->cur_vga_file = _vgaCurZoneNum;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr = (byte *)&_vc_get_out_of_code;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc17_setPathfinderItem() {
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_WW) {
|
|
|
|
// FIXME
|
|
|
|
vcReadNextWord();
|
|
|
|
} else {
|
|
|
|
uint16 a = vcReadNextWord();
|
|
|
|
_pathFindArray[a - 1] = (const uint16 *)_vcPtr;
|
2005-10-09 12:12:24 +00:00
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
int end = (getGameType() == GType_FF || getGameType() == GType_PP) ? 9999 : 999;
|
2006-09-19 11:59:13 +00:00
|
|
|
while (readUint16Wrapper(_vcPtr) != end)
|
|
|
|
_vcPtr += 4;
|
|
|
|
_vcPtr += 2;
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc18_jump() {
|
2005-12-13 00:20:11 +00:00
|
|
|
int16 offs = vcReadNextWord();
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr += offs;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* chain to script? */
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc19_chain_to_script() {
|
2003-07-30 11:16:09 +00:00
|
|
|
/* unused */
|
2005-05-06 13:22:48 +00:00
|
|
|
error("vc19_chain_to_script: not implemented");
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* helper routines */
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc20_setRepeat() {
|
2005-07-30 21:11:48 +00:00
|
|
|
/* FIXME: This opcode is somewhat strange: it first reads a BE word from
|
2004-12-18 01:33:21 +00:00
|
|
|
* the script (advancing the script pointer in doing so); then it writes
|
|
|
|
* back the same word, this time as LE, into the script.
|
|
|
|
*/
|
2005-12-13 00:20:11 +00:00
|
|
|
uint16 a = vcReadNextWord();
|
2005-05-06 11:37:33 +00:00
|
|
|
WRITE_LE_UINT16(const_cast<byte *>(_vcPtr), a);
|
|
|
|
_vcPtr += 2;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc21_endRepeat() {
|
2005-12-13 00:20:11 +00:00
|
|
|
int16 a = vcReadNextWord();
|
2005-05-06 11:37:33 +00:00
|
|
|
const byte *tmp = _vcPtr + a;
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_SIMON1 || getGameType() == GType_WW)
|
2003-07-28 11:48:07 +00:00
|
|
|
tmp += 4;
|
2005-11-12 08:04:10 +00:00
|
|
|
else
|
|
|
|
tmp += 3;
|
2003-07-28 11:48:07 +00:00
|
|
|
|
2004-12-18 01:33:21 +00:00
|
|
|
uint16 val = READ_LE_UINT16(tmp);
|
2003-07-28 11:48:07 +00:00
|
|
|
if (val != 0) {
|
2004-12-18 01:33:21 +00:00
|
|
|
// Decrement counter
|
|
|
|
WRITE_LE_UINT16(const_cast<byte *>(tmp), val - 1);
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr = tmp + 2;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc22_setSpritePalette() {
|
2006-09-19 11:59:13 +00:00
|
|
|
byte *offs, *palptr, *src;
|
|
|
|
uint16 a, b, num, palSize;
|
|
|
|
|
|
|
|
if (getGameType() != GType_WW)
|
|
|
|
a = vcReadNextWord();
|
|
|
|
b = vcReadNextWord();
|
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2005-11-10 05:33:31 +00:00
|
|
|
num = 256;
|
|
|
|
palSize = 768;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-09-19 11:59:13 +00:00
|
|
|
palptr = _displayPalette;
|
|
|
|
offs = _curVgaFile1 + 6;
|
2006-09-28 23:22:07 +00:00
|
|
|
} else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
|
2006-09-19 11:59:13 +00:00
|
|
|
num = a == 0 ? 32 : 16;
|
|
|
|
palSize = 96;
|
|
|
|
|
|
|
|
palptr = &_displayPalette[(a * 64)];
|
|
|
|
offs = _curVgaFile1 + 6;
|
2006-09-28 23:22:07 +00:00
|
|
|
} else {
|
|
|
|
num = 16;
|
|
|
|
palSize = 32;
|
|
|
|
palptr = _displayPalette;
|
|
|
|
offs = _curVgaFile1 + READ_BE_UINT16(_curVgaFile1 + 6);
|
2006-09-19 11:59:13 +00:00
|
|
|
}
|
2006-09-28 23:22:07 +00:00
|
|
|
|
2006-09-19 11:59:13 +00:00
|
|
|
src = offs + b * palSize;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2002-06-29 16:11:13 +00:00
|
|
|
do {
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_WW) {
|
|
|
|
uint16 color = READ_BE_UINT16(src);
|
|
|
|
palptr[2] = ((color & 0x00f) >> 0) * 32;
|
|
|
|
palptr[1] = ((color & 0x0f0) >> 4) * 32;
|
|
|
|
palptr[0] = ((color & 0xf00) >> 8) * 32;
|
|
|
|
} else {
|
|
|
|
palptr[0] = src[0] * 4;
|
|
|
|
palptr[1] = src[1] * 4;
|
|
|
|
palptr[2] = src[2] * 4;
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
palptr[3] = 0;
|
|
|
|
|
|
|
|
palptr += 4;
|
2006-09-19 11:59:13 +00:00
|
|
|
src += (getGameType() == GType_WW) ? 2 : 3;
|
2002-06-29 16:11:13 +00:00
|
|
|
} while (--num);
|
|
|
|
|
2005-11-10 05:33:31 +00:00
|
|
|
_paletteFlag = 2;
|
2005-05-06 11:37:33 +00:00
|
|
|
_vgaSpriteChanged++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc23_setSpritePriority() {
|
2005-12-13 00:20:11 +00:00
|
|
|
VgaSprite *vsp = findCurSprite(), *vus2;
|
|
|
|
uint16 pri = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
VgaSprite bak;
|
|
|
|
|
2003-07-30 11:16:09 +00:00
|
|
|
if (vsp->id == 0)
|
2003-07-16 12:21:09 +00:00
|
|
|
return;
|
|
|
|
|
2002-06-29 16:11:13 +00:00
|
|
|
memcpy(&bak, vsp, sizeof(bak));
|
2002-11-28 00:22:24 +00:00
|
|
|
bak.priority = pri;
|
2005-10-05 11:37:26 +00:00
|
|
|
bak.windowNum |= 0x8000;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
|
|
|
vus2 = vsp;
|
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
if (vsp != _vgaSprites && pri < vsp[-1].priority) {
|
2002-06-29 16:11:13 +00:00
|
|
|
do {
|
|
|
|
vsp--;
|
2005-05-06 11:37:33 +00:00
|
|
|
} while (vsp != _vgaSprites && pri < vsp[-1].priority);
|
2002-06-29 16:11:13 +00:00
|
|
|
do {
|
2002-07-07 19:06:48 +00:00
|
|
|
memcpy(vus2, vus2 - 1, sizeof(VgaSprite));
|
2002-06-29 16:11:13 +00:00
|
|
|
} while (--vus2 != vsp);
|
|
|
|
memcpy(vus2, &bak, sizeof(VgaSprite));
|
2002-11-28 00:22:24 +00:00
|
|
|
} else if (vsp[1].id != 0 && pri >= vsp[1].priority) {
|
2002-06-29 16:11:13 +00:00
|
|
|
do {
|
|
|
|
vsp++;
|
2002-11-28 00:22:24 +00:00
|
|
|
} while (vsp[1].id != 0 && pri >= vsp[1].priority);
|
2002-06-29 16:11:13 +00:00
|
|
|
do {
|
2002-07-07 19:06:48 +00:00
|
|
|
memcpy(vus2, vus2 + 1, sizeof(VgaSprite));
|
2002-06-29 16:11:13 +00:00
|
|
|
} while (++vus2 != vsp);
|
|
|
|
memcpy(vus2, &bak, sizeof(VgaSprite));
|
|
|
|
} else {
|
2002-11-28 00:22:24 +00:00
|
|
|
vsp->priority = pri;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
2005-05-06 11:37:33 +00:00
|
|
|
_vgaSpriteChanged++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc24_setSpriteXY() {
|
2005-12-13 00:20:11 +00:00
|
|
|
VgaSprite *vsp = findCurSprite();
|
|
|
|
vsp->image = vcReadVarOrWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
vsp->x += (int16)vcReadNextWord();
|
|
|
|
vsp->y += (int16)vcReadNextWord();
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) {
|
2005-12-13 00:20:11 +00:00
|
|
|
vsp->flags = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
} else {
|
2005-12-13 00:20:11 +00:00
|
|
|
vsp->flags = vcReadNextByte();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
_vgaSpriteChanged++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc25_halt_sprite() {
|
2005-12-13 00:20:11 +00:00
|
|
|
VgaSprite *vsp = findCurSprite();
|
2002-06-29 16:11:13 +00:00
|
|
|
while (vsp->id != 0) {
|
2002-07-07 19:06:48 +00:00
|
|
|
memcpy(vsp, vsp + 1, sizeof(VgaSprite));
|
2002-06-29 16:11:13 +00:00
|
|
|
vsp++;
|
|
|
|
}
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr = (byte *)&_vc_get_out_of_code;
|
|
|
|
_vgaSpriteChanged++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc26_setSubWindow() {
|
2005-12-13 00:20:11 +00:00
|
|
|
uint16 *as = &_video_windows[vcReadNextWord() * 4]; // number
|
|
|
|
as[0] = vcReadNextWord(); // x
|
|
|
|
as[1] = vcReadNextWord(); // y
|
|
|
|
as[2] = vcReadNextWord(); // width
|
|
|
|
as[3] = vcReadNextWord(); // height
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc27_resetSprite() {
|
2002-07-07 19:06:48 +00:00
|
|
|
VgaSprite bak, *vsp;
|
2002-06-29 16:11:13 +00:00
|
|
|
VgaSleepStruct *vfs;
|
2002-07-07 19:06:48 +00:00
|
|
|
VgaTimerEntry *vte, *vte2;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
_lockWord |= 8;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-06-01 12:06:53 +00:00
|
|
|
_lastVgaWaitFor = 0;
|
|
|
|
|
2002-07-07 19:06:48 +00:00
|
|
|
memset(&bak, 0, sizeof(bak));
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
vsp = _vgaSprites;
|
2002-06-29 16:11:13 +00:00
|
|
|
while (vsp->id) {
|
2005-11-12 06:01:24 +00:00
|
|
|
if ((getGameType() == GType_SIMON1) && vsp->id == 128) {
|
2002-07-07 19:06:48 +00:00
|
|
|
memcpy(&bak, vsp, sizeof(VgaSprite));
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
vsp->id = 0;
|
|
|
|
vsp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bak.id != 0)
|
2005-05-06 11:37:33 +00:00
|
|
|
memcpy(_vgaSprites, &bak, sizeof(VgaSprite));
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
vfs = _vgaSleepStructs;
|
2002-06-29 16:11:13 +00:00
|
|
|
while (vfs->ident) {
|
|
|
|
vfs->ident = 0;
|
|
|
|
vfs++;
|
|
|
|
}
|
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
vte = _vgaTimerList;
|
2002-06-29 16:11:13 +00:00
|
|
|
while (vte->delay) {
|
2006-05-05 05:54:35 +00:00
|
|
|
if ((getGameType() == GType_SIMON1) && vte->sprite_id == 128) {
|
2002-06-29 16:11:13 +00:00
|
|
|
vte++;
|
2005-05-06 08:46:45 +00:00
|
|
|
} else {
|
|
|
|
vte2 = vte;
|
2002-06-29 16:11:13 +00:00
|
|
|
while (vte2->delay) {
|
2002-07-07 19:06:48 +00:00
|
|
|
memcpy(vte2, vte2 + 1, sizeof(VgaTimerEntry));
|
2002-06-29 16:11:13 +00:00
|
|
|
vte2++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
vcWriteVar(254, 0);
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-03-23 04:49:03 +00:00
|
|
|
if (getGameType() == GType_FF)
|
2006-04-25 08:01:57 +00:00
|
|
|
setBitFlag(42, true);
|
2006-03-23 04:49:03 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
_lockWord &= ~8;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc28_dummy_op() {
|
2003-07-30 11:16:09 +00:00
|
|
|
/* unused */
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr += 8;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc29_stopAllSounds() {
|
2006-09-29 06:58:59 +00:00
|
|
|
if (getGameType() != GType_PP)
|
|
|
|
_sound->stopVoice();
|
|
|
|
|
|
|
|
_sound->stopAllSfx();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc30_setFrameRate() {
|
2005-12-13 00:20:11 +00:00
|
|
|
_frameRate = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc31_setWindow() {
|
2005-12-13 00:20:11 +00:00
|
|
|
_windowNum = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc32_copyVar() {
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_WW) {
|
|
|
|
// FIXME
|
|
|
|
} else {
|
|
|
|
uint16 a = vcReadVar(vcReadNextWord());
|
|
|
|
vcWriteVar(vcReadNextWord(), a);
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc33_setMouseOn() {
|
2005-12-08 06:12:04 +00:00
|
|
|
if (_mouseHideCount != 0) {
|
|
|
|
_mouseHideCount = 1;
|
|
|
|
mouseOn();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc34_setMouseOff() {
|
2005-12-08 06:12:04 +00:00
|
|
|
mouseOff();
|
|
|
|
_mouseHideCount = 200;
|
2005-05-06 11:37:33 +00:00
|
|
|
_leftButtonDown = 0;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc35_clearWindow() {
|
2003-07-30 11:16:09 +00:00
|
|
|
/* unused */
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr += 4;
|
|
|
|
_vgaSpriteChanged++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc36_setWindowImage() {
|
2005-11-09 23:36:55 +00:00
|
|
|
_updateScreen = false;
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 vga_res = vcReadNextWord();
|
|
|
|
uint16 windowNum = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2006-06-12 06:47:38 +00:00
|
|
|
_copyPartialMode = 2;
|
|
|
|
} else if (getGameType() == GType_SIMON2) {
|
2006-04-13 10:03:45 +00:00
|
|
|
set_video_mode_internal(windowNum, vga_res);
|
2006-05-03 04:07:37 +00:00
|
|
|
} else if (getGameType() == GType_SIMON1) {
|
2005-10-05 12:16:49 +00:00
|
|
|
if (windowNum == 16) {
|
2005-05-06 11:37:33 +00:00
|
|
|
_copyPartialMode = 2;
|
2002-06-29 16:11:13 +00:00
|
|
|
} else {
|
2005-10-05 12:16:49 +00:00
|
|
|
set_video_mode_internal(windowNum, vga_res);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc37_addToSpriteY() {
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_WW) {
|
|
|
|
// FIXME
|
|
|
|
vcReadNextWord();
|
|
|
|
vcReadNextWord();
|
|
|
|
} else {
|
|
|
|
VgaSprite *vsp = findCurSprite();
|
|
|
|
vsp->y += vcReadVar(vcReadNextWord());
|
|
|
|
_vgaSpriteChanged++;
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc38_skipIfVarZero() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 var = vcReadNextWord();
|
2005-12-13 00:20:11 +00:00
|
|
|
if (vcReadVar(var) == 0)
|
|
|
|
vcSkipNextInstruction();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc39_setVar() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 var = vcReadNextWord();
|
2005-12-13 00:20:11 +00:00
|
|
|
int16 value = vcReadNextWord();
|
|
|
|
vcWriteVar(var, value);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc40() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 var = vcReadNextWord();
|
2005-12-13 00:20:11 +00:00
|
|
|
int16 value = vcReadVar(var) + vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-04-05 00:37:42 +00:00
|
|
|
if ((getGameType() == GType_SIMON2) && var == 15 && !getBitFlag(80)) {
|
2002-06-29 16:11:13 +00:00
|
|
|
int16 tmp;
|
|
|
|
|
2005-10-05 11:37:26 +00:00
|
|
|
if (_scrollCount != 0) {
|
|
|
|
if (_scrollCount >= 0)
|
2002-07-07 19:06:48 +00:00
|
|
|
goto no_scroll;
|
2005-10-05 11:37:26 +00:00
|
|
|
_scrollCount = 0;
|
2002-06-29 16:11:13 +00:00
|
|
|
} else {
|
2005-10-05 11:37:26 +00:00
|
|
|
if (_scrollFlag != 0)
|
2002-07-07 19:06:48 +00:00
|
|
|
goto no_scroll;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2005-10-05 11:37:26 +00:00
|
|
|
if (value - _scrollX >= 30) {
|
|
|
|
_scrollCount = 20;
|
|
|
|
tmp = _scrollXMax - _scrollX;
|
2002-06-29 16:11:13 +00:00
|
|
|
if (tmp < 20)
|
2005-10-05 11:37:26 +00:00
|
|
|
_scrollCount = tmp;
|
2006-04-21 00:18:23 +00:00
|
|
|
addVgaEvent(6, NULL, 0, 0); /* scroll event */
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
no_scroll:;
|
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
vcWriteVar(var, value);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc41() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 var = vcReadNextWord();
|
2005-12-13 00:20:11 +00:00
|
|
|
int16 value = vcReadVar(var) - vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-04-05 00:37:42 +00:00
|
|
|
if ((getGameType() == GType_SIMON2) && var == 15 && !getBitFlag(80)) {
|
2005-10-05 11:37:26 +00:00
|
|
|
if (_scrollCount != 0) {
|
|
|
|
if (_scrollCount < 0)
|
2002-07-07 19:06:48 +00:00
|
|
|
goto no_scroll;
|
2005-10-05 11:37:26 +00:00
|
|
|
_scrollCount = 0;
|
2002-06-29 16:11:13 +00:00
|
|
|
} else {
|
2005-10-05 11:37:26 +00:00
|
|
|
if (_scrollFlag != 0)
|
2002-07-07 19:06:48 +00:00
|
|
|
goto no_scroll;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2005-10-05 11:37:26 +00:00
|
|
|
if ((uint16)(value - _scrollX) < 11) {
|
|
|
|
_scrollCount = -20;
|
|
|
|
if (_scrollX < 20)
|
|
|
|
_scrollCount = -_scrollX;
|
2006-04-21 00:18:23 +00:00
|
|
|
addVgaEvent(6, NULL, 0, 0); /* scroll event */
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
no_scroll:;
|
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
vcWriteVar(var, value);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc42_delayIfNotEQ() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 val = vcReadVar(vcReadNextWord());
|
2005-12-13 00:20:11 +00:00
|
|
|
if (val != vcReadNextWord()) {
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-04-21 00:18:23 +00:00
|
|
|
addVgaEvent(_frameRate + 1, _vcPtr - 4, _vgaCurSpriteId, _vgaCurZoneNum);
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr = (byte *)&_vc_get_out_of_code;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc43_skipIfBitClear() {
|
2006-04-04 10:12:22 +00:00
|
|
|
if (!getBitFlag(vcReadNextWord())) {
|
2005-12-13 00:20:11 +00:00
|
|
|
vcSkipNextInstruction();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc44_skipIfBitSet() {
|
2006-04-04 10:12:22 +00:00
|
|
|
if (getBitFlag(vcReadNextWord())) {
|
2005-12-13 00:20:11 +00:00
|
|
|
vcSkipNextInstruction();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc45_setSpriteX() {
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_WW) {
|
|
|
|
//FIXME
|
|
|
|
vcReadNextWord();
|
|
|
|
vcReadNextWord();
|
|
|
|
} else {
|
|
|
|
VgaSprite *vsp = findCurSprite();
|
|
|
|
vsp->x = vcReadVar(vcReadNextWord());
|
|
|
|
_vgaSpriteChanged++;
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc46_setSpriteY() {
|
2005-12-13 00:20:11 +00:00
|
|
|
VgaSprite *vsp = findCurSprite();
|
|
|
|
vsp->y = vcReadVar(vcReadNextWord());
|
2005-05-06 11:37:33 +00:00
|
|
|
_vgaSpriteChanged++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc47_addToVar() {
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_WW) {
|
|
|
|
//FIXME
|
|
|
|
vcReadNextWord();
|
|
|
|
} else {
|
|
|
|
uint16 var = vcReadNextWord();
|
|
|
|
vcWriteVar(var, vcReadVar(var) + vcReadVar(vcReadNextWord()));
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc48_setPathFinder() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 a = (uint16)_variableArrayPtr[12];
|
2005-05-06 11:37:33 +00:00
|
|
|
const uint16 *p = _pathFindArray[a - 1];
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_WW) {
|
|
|
|
//FIXME
|
|
|
|
vcReadNextWord();
|
2006-09-28 23:22:07 +00:00
|
|
|
} else if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2005-12-13 00:20:11 +00:00
|
|
|
VgaSprite *vsp = findCurSprite();
|
2006-04-15 01:09:04 +00:00
|
|
|
int16 x, y, ydiff;
|
|
|
|
int16 x1, y1, x2, y2;
|
2005-11-18 12:40:03 +00:00
|
|
|
uint pos = 0;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-04-16 01:06:18 +00:00
|
|
|
x = vsp->x;
|
|
|
|
while (x >= (int16)readUint16Wrapper(p + 2)) {
|
2005-11-15 04:07:05 +00:00
|
|
|
p += 2;
|
2005-11-18 12:40:03 +00:00
|
|
|
pos++;
|
2005-11-15 04:07:05 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-04-15 01:09:04 +00:00
|
|
|
x1 = readUint16Wrapper(p);
|
2005-11-15 04:07:05 +00:00
|
|
|
y1 = readUint16Wrapper(p + 1);
|
2005-11-15 04:54:18 +00:00
|
|
|
x2 = readUint16Wrapper(p + 2);
|
2005-11-15 04:07:05 +00:00
|
|
|
y2 = readUint16Wrapper(p + 3);
|
|
|
|
|
2005-11-15 04:54:18 +00:00
|
|
|
if (x2 != 9999) {
|
2005-11-15 04:07:05 +00:00
|
|
|
ydiff = y2 - y1;
|
|
|
|
if (ydiff < 0) {
|
2005-11-15 04:54:18 +00:00
|
|
|
ydiff = -ydiff;
|
2005-11-15 04:07:05 +00:00
|
|
|
x = vsp->x & 7;
|
|
|
|
ydiff *= x;
|
|
|
|
ydiff /= 8;
|
|
|
|
ydiff = -ydiff;
|
|
|
|
} else {
|
|
|
|
x = vsp->x & 7;
|
|
|
|
ydiff *= x;
|
|
|
|
ydiff /= 8;
|
|
|
|
}
|
|
|
|
y1 += ydiff;
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-11-15 04:07:05 +00:00
|
|
|
y = vsp->y;
|
|
|
|
vsp->y = y1;
|
2006-04-08 00:12:16 +00:00
|
|
|
checkScrollY(y1 - y, y1);
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-04-15 22:14:39 +00:00
|
|
|
_variableArrayPtr[11] = x1;
|
|
|
|
_variableArrayPtr[13] = pos;
|
2005-11-15 04:07:05 +00:00
|
|
|
} else {
|
|
|
|
uint b = (uint16)_variableArray[13];
|
|
|
|
p += b * 2 + 1;
|
|
|
|
int c = _variableArray[14];
|
|
|
|
|
|
|
|
int step;
|
|
|
|
int y1, y2;
|
2006-04-15 22:14:39 +00:00
|
|
|
int16 *vp;
|
2005-11-15 04:07:05 +00:00
|
|
|
|
|
|
|
step = 2;
|
|
|
|
if (c < 0) {
|
|
|
|
c = -c;
|
|
|
|
step = -2;
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-11-15 04:07:05 +00:00
|
|
|
vp = &_variableArray[20];
|
|
|
|
|
|
|
|
do {
|
|
|
|
y2 = readUint16Wrapper(p);
|
|
|
|
p += step;
|
|
|
|
y1 = readUint16Wrapper(p) - y2;
|
|
|
|
|
|
|
|
vp[0] = y1 / 2;
|
|
|
|
vp[1] = y1 - (y1 / 2);
|
|
|
|
|
|
|
|
vp += 2;
|
|
|
|
} while (--c);
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::setBitFlag(uint bit, bool value) {
|
2006-03-23 04:49:03 +00:00
|
|
|
uint16 *bits = &_bitArray[bit / 16];
|
2002-07-07 19:06:48 +00:00
|
|
|
*bits = (*bits & ~(1 << (bit & 15))) | (value << (bit & 15));
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
bool AGOSEngine::getBitFlag(uint bit) {
|
2006-03-23 04:49:03 +00:00
|
|
|
uint16 *bits = &_bitArray[bit / 16];
|
2002-07-07 19:06:48 +00:00
|
|
|
return (*bits & (1 << (bit & 15))) != 0;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc49_setBit() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 bit = vcReadNextWord();
|
2006-04-21 04:36:26 +00:00
|
|
|
if (getGameType() == GType_FF && bit == 82) {
|
|
|
|
_variableArrayPtr = _variableArray2;
|
|
|
|
}
|
|
|
|
setBitFlag(bit, true);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc50_clearBit() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 bit = vcReadNextWord();
|
2006-04-21 04:36:26 +00:00
|
|
|
if (getGameType() == GType_FF && bit == 82) {
|
|
|
|
_variableArrayPtr = _variableArray;
|
|
|
|
}
|
|
|
|
setBitFlag(bit, false);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc51_enableBox() {
|
2006-04-14 09:57:43 +00:00
|
|
|
enableBox(vcReadNextWord());
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc52_playSound() {
|
2005-11-14 12:01:31 +00:00
|
|
|
bool ambient = false;
|
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
uint16 sound = vcReadNextWord();
|
2005-11-14 12:01:31 +00:00
|
|
|
if (sound >= 0x8000) {
|
|
|
|
ambient = true;
|
|
|
|
sound = -sound;
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2006-04-23 15:42:02 +00:00
|
|
|
int16 pan = vcReadNextWord();
|
|
|
|
int16 vol = vcReadNextWord();
|
2006-04-17 12:05:45 +00:00
|
|
|
|
|
|
|
if (ambient)
|
|
|
|
loadSound(sound, pan, vol, 2);
|
|
|
|
else
|
|
|
|
loadSound(sound, pan, vol, 1);
|
2005-11-12 06:01:24 +00:00
|
|
|
} else if (getGameType() == GType_SIMON2) {
|
2006-04-17 12:05:45 +00:00
|
|
|
if (ambient)
|
2005-11-14 12:01:31 +00:00
|
|
|
_sound->playAmbient(sound);
|
2006-04-17 12:05:45 +00:00
|
|
|
else
|
2005-11-14 12:01:31 +00:00
|
|
|
_sound->playEffects(sound);
|
2005-11-12 06:01:24 +00:00
|
|
|
} else if (getFeatures() & GF_TALKIE) {
|
2005-11-14 12:01:31 +00:00
|
|
|
_sound->playEffects(sound);
|
2005-11-20 10:26:14 +00:00
|
|
|
} else if (getGameId() == GID_SIMON1DOS) {
|
2005-11-14 12:01:31 +00:00
|
|
|
playSting(sound);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc53_panSFX() {
|
2006-04-21 00:18:23 +00:00
|
|
|
VgaSprite *vsp = findCurSprite();
|
2006-04-23 15:42:02 +00:00
|
|
|
int pan;
|
2006-04-21 00:18:23 +00:00
|
|
|
|
|
|
|
uint16 sound = vcReadNextWord();
|
|
|
|
int16 xoffs = vcReadNextWord();
|
2006-04-23 15:42:02 +00:00
|
|
|
int16 vol = vcReadNextWord();
|
2006-04-21 00:18:23 +00:00
|
|
|
|
|
|
|
pan = (vsp->x - _scrollX + xoffs) * 8 - 2560;
|
|
|
|
if (pan < -10000)
|
|
|
|
pan = -10000;
|
|
|
|
if (pan > 10000)
|
|
|
|
pan = 10000;
|
|
|
|
|
|
|
|
loadSound(sound, 0, vol, 1);
|
|
|
|
|
|
|
|
if (xoffs != 2)
|
|
|
|
xoffs |= 0x10;
|
|
|
|
|
|
|
|
addVgaEvent(10, NULL, _vgaCurSpriteId, _vgaCurZoneNum, xoffs); /* pan event */
|
|
|
|
debug(0, "vc53_panSFX: snd %d xoffs %d vol %d", sound, xoffs, vol);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc54_no_op() {
|
2003-07-30 11:16:09 +00:00
|
|
|
/* unused */
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr += 6;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc55_moveBox() {
|
2005-05-06 11:37:33 +00:00
|
|
|
HitArea *ha = _hitAreas;
|
|
|
|
uint count = ARRAYSIZE(_hitAreas);
|
2005-12-13 00:20:11 +00:00
|
|
|
uint16 id = vcReadNextWord();
|
|
|
|
int16 x = vcReadNextWord();
|
|
|
|
int16 y = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2002-07-07 19:06:48 +00:00
|
|
|
for (;;) {
|
2002-06-29 16:11:13 +00:00
|
|
|
if (ha->id == id) {
|
|
|
|
ha->x += x;
|
|
|
|
ha->y += y;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ha++;
|
|
|
|
if (!--count)
|
|
|
|
break;
|
|
|
|
}
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
_needHitAreaRecalc++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc56_delay() {
|
2006-09-19 12:46:34 +00:00
|
|
|
if (getGameType() == GType_WW) {
|
2006-09-19 11:59:13 +00:00
|
|
|
byte *src = _curVgaFile2 + 32;
|
|
|
|
byte *dst = getBackBuf();
|
|
|
|
|
|
|
|
uint8 palette[1024];
|
|
|
|
for (int i = 0; i < 256; i++) {
|
|
|
|
palette[i * 4 + 0] = *src++ * 4;
|
|
|
|
palette[i * 4 + 1] = *src++ * 4;
|
|
|
|
palette[i * 4 + 2] = *src++ * 4;
|
|
|
|
palette[i * 4 + 3] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
_system->setPalette(palette, 0, 256);
|
|
|
|
memcpy(dst, src, _screenHeight * _screenWidth);
|
2006-09-19 12:46:34 +00:00
|
|
|
} else {
|
|
|
|
uint16 num = vcReadVarOrWord() * _frameRate;
|
|
|
|
|
|
|
|
addVgaEvent(num + _vgaBaseDelay, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum);
|
|
|
|
_vcPtr = (byte *)&_vc_get_out_of_code;
|
2006-09-19 11:59:13 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc57_blackPalette() {
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_WW) {
|
2006-09-19 12:46:34 +00:00
|
|
|
uint8 palette[1024];
|
|
|
|
memset(palette, 0, sizeof(palette));
|
|
|
|
_system->setPalette(palette, 0, 256);
|
2006-09-19 11:59:13 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc58() {
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_WW)
|
|
|
|
return;
|
|
|
|
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 sprite = _vgaCurSpriteId;
|
|
|
|
uint16 file = _vgaCurZoneNum;
|
2006-05-05 05:53:36 +00:00
|
|
|
const byte *vcPtrOrg;
|
2002-06-29 16:11:13 +00:00
|
|
|
uint16 tmp;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-04-10 23:44:17 +00:00
|
|
|
_vgaCurZoneNum = vcReadNextWord();
|
2005-12-13 00:20:11 +00:00
|
|
|
_vgaCurSpriteId = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
tmp = to16Wrapper(vcReadNextWord());
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-05-05 05:53:36 +00:00
|
|
|
vcPtrOrg = _vcPtr;
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr = (byte *)&tmp;
|
2005-05-06 13:22:48 +00:00
|
|
|
vc23_setSpritePriority();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-05-05 05:53:36 +00:00
|
|
|
_vcPtr = vcPtrOrg;
|
2005-05-06 11:37:33 +00:00
|
|
|
_vgaCurSpriteId = sprite;
|
2006-04-10 23:44:17 +00:00
|
|
|
_vgaCurZoneNum = file;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc59() {
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) {
|
2006-09-18 12:01:18 +00:00
|
|
|
uint16 file = vcReadNextWord();
|
|
|
|
uint16 start = vcReadNextWord();
|
|
|
|
uint16 end = vcReadNextWord() + 1;
|
|
|
|
|
|
|
|
do {
|
|
|
|
vc_kill_sprite(file, start);
|
|
|
|
} while (++start != end);
|
2006-09-19 11:59:13 +00:00
|
|
|
} else if (getGameType() == GType_SIMON1) {
|
|
|
|
if (!_sound->isVoiceActive())
|
|
|
|
vcSkipNextInstruction();
|
|
|
|
} else {
|
|
|
|
// Skip if not EGA
|
|
|
|
vcSkipNextInstruction();
|
2006-09-18 12:01:18 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc_kill_sprite(uint file, uint sprite) {
|
2002-06-29 16:11:13 +00:00
|
|
|
uint16 old_sprite_id, old_cur_file_id;
|
|
|
|
VgaSleepStruct *vfs;
|
|
|
|
VgaSprite *vsp;
|
|
|
|
VgaTimerEntry *vte;
|
2006-05-05 05:53:36 +00:00
|
|
|
const byte *vcPtrOrg;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
old_sprite_id = _vgaCurSpriteId;
|
2006-04-10 23:44:17 +00:00
|
|
|
old_cur_file_id = _vgaCurZoneNum;
|
2006-05-05 05:53:36 +00:00
|
|
|
vcPtrOrg = _vcPtr;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2006-04-10 23:44:17 +00:00
|
|
|
_vgaCurZoneNum = file;
|
2005-05-06 11:37:33 +00:00
|
|
|
_vgaCurSpriteId = sprite;
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
vfs = _vgaSleepStructs;
|
2002-06-29 16:11:13 +00:00
|
|
|
while (vfs->ident != 0) {
|
2006-04-10 23:44:17 +00:00
|
|
|
if (vfs->sprite_id == _vgaCurSpriteId && ((getGameType() == GType_SIMON1) || vfs->cur_vga_file == _vgaCurZoneNum)) {
|
2002-07-07 19:06:48 +00:00
|
|
|
while (vfs->ident != 0) {
|
|
|
|
memcpy(vfs, vfs + 1, sizeof(VgaSleepStruct));
|
2002-06-29 16:11:13 +00:00
|
|
|
vfs++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
vfs++;
|
|
|
|
}
|
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
vsp = findCurSprite();
|
2002-06-29 16:11:13 +00:00
|
|
|
if (vsp->id) {
|
2005-05-06 13:22:48 +00:00
|
|
|
vc25_halt_sprite();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
vte = _vgaTimerList;
|
2002-06-29 16:11:13 +00:00
|
|
|
while (vte->delay != 0) {
|
2006-04-10 23:44:17 +00:00
|
|
|
if (vte->sprite_id == _vgaCurSpriteId && ((getGameType() == GType_SIMON1) || vte->cur_vga_file == _vgaCurZoneNum)) {
|
2006-04-21 00:18:23 +00:00
|
|
|
deleteVgaEvent(vte);
|
2002-06-29 16:11:13 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
vte++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-04-10 23:44:17 +00:00
|
|
|
_vgaCurZoneNum = old_cur_file_id;
|
2005-05-06 11:37:33 +00:00
|
|
|
_vgaCurSpriteId = old_sprite_id;
|
2006-05-05 05:53:36 +00:00
|
|
|
_vcPtr = vcPtrOrg;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc60_killSprite() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 zoneNum;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-11-12 08:04:10 +00:00
|
|
|
if (getGameType() == GType_SIMON1) {
|
2006-04-21 00:18:23 +00:00
|
|
|
zoneNum = _vgaCurZoneNum;
|
2005-11-12 08:04:10 +00:00
|
|
|
} else {
|
2006-04-21 00:18:23 +00:00
|
|
|
zoneNum = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 sprite = vcReadNextWord();
|
2006-04-21 00:18:23 +00:00
|
|
|
vc_kill_sprite(zoneNum, sprite);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc61_setMaskImage() {
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() == GType_WW) {
|
|
|
|
// FIXME
|
|
|
|
vcReadVarOrWord();
|
2006-09-28 23:22:07 +00:00
|
|
|
} else {
|
|
|
|
VgaSprite *vsp = findCurSprite();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
vsp->image = vcReadVarOrWord();
|
|
|
|
vsp->x += vcReadNextWord();
|
|
|
|
vsp->y += vcReadNextWord();
|
|
|
|
vsp->flags = kDFMasked | kDFUseFrontBuf;
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
_vgaSpriteChanged++;
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc62_fastFadeOut() {
|
2005-05-06 13:22:48 +00:00
|
|
|
vc29_stopAllSounds();
|
2002-07-07 19:06:48 +00:00
|
|
|
|
2005-11-15 04:07:05 +00:00
|
|
|
if (!_fastFadeOutFlag) {
|
2006-05-05 05:53:36 +00:00
|
|
|
uint i, fadeSize, fadeCount;
|
|
|
|
|
2006-09-19 11:59:13 +00:00
|
|
|
if (getGameType() != GType_WW)
|
|
|
|
_fastFadeOutFlag = true;
|
2002-11-24 13:05:44 +00:00
|
|
|
|
2006-05-05 05:53:36 +00:00
|
|
|
_fastFadeCount = 256;
|
2005-11-15 04:07:05 +00:00
|
|
|
if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
|
|
|
|
if (_windowNum == 4)
|
2006-05-05 05:53:36 +00:00
|
|
|
_fastFadeCount = 208;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(_videoBuf1, _currentPalette, _fastFadeCount * 4);
|
|
|
|
|
2006-09-28 23:22:07 +00:00
|
|
|
if ((getGameType() == GType_FF || getGameType() == GType_PP) && !getBitFlag(75)) {
|
2006-05-05 05:53:36 +00:00
|
|
|
fadeCount = 32;
|
|
|
|
fadeSize = 8;
|
|
|
|
} else {
|
|
|
|
fadeCount = 4;
|
|
|
|
fadeSize = 64;
|
2005-11-15 04:07:05 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2006-05-05 05:53:36 +00:00
|
|
|
for (i = fadeCount; i != 0; --i) {
|
|
|
|
paletteFadeOut(_videoBuf1, _fastFadeCount, fadeSize);
|
|
|
|
_system->setPalette(_videoBuf1, 0, _fastFadeCount);
|
2003-05-21 11:49:41 +00:00
|
|
|
delay(5);
|
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-11-12 06:01:24 +00:00
|
|
|
if (getGameType() == GType_SIMON1) {
|
2005-05-06 13:22:48 +00:00
|
|
|
uint16 params[5]; /* parameters to vc10_draw */
|
2003-05-21 11:49:41 +00:00
|
|
|
VgaSprite *vsp;
|
|
|
|
VgaPointersEntry *vpe;
|
2006-05-05 05:53:36 +00:00
|
|
|
const byte *vcPtrOrg = _vcPtr;
|
2003-05-21 11:49:41 +00:00
|
|
|
|
2005-05-06 11:37:33 +00:00
|
|
|
vsp = _vgaSprites;
|
2003-05-21 11:49:41 +00:00
|
|
|
while (vsp->id != 0) {
|
2005-11-13 07:04:56 +00:00
|
|
|
if (vsp->id == 128) {
|
2005-05-06 11:37:33 +00:00
|
|
|
byte *old_file_1 = _curVgaFile1;
|
|
|
|
byte *old_file_2 = _curVgaFile2;
|
2005-10-05 11:37:26 +00:00
|
|
|
uint palmode = _windowNum;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2006-04-10 23:44:17 +00:00
|
|
|
vpe = &_vgaBufferPointers[vsp->zoneNum];
|
2005-05-06 11:37:33 +00:00
|
|
|
_curVgaFile1 = vpe->vgaFile1;
|
|
|
|
_curVgaFile2 = vpe->vgaFile2;
|
2005-10-05 11:37:26 +00:00
|
|
|
_windowNum = vsp->windowNum;
|
2003-05-21 11:49:41 +00:00
|
|
|
|
2003-06-14 18:52:30 +00:00
|
|
|
params[0] = READ_BE_UINT16(&vsp->image);
|
2005-10-05 11:37:26 +00:00
|
|
|
params[1] = READ_BE_UINT16(&vsp->palette);
|
2003-06-14 18:52:30 +00:00
|
|
|
params[2] = READ_BE_UINT16(&vsp->x);
|
|
|
|
params[3] = READ_BE_UINT16(&vsp->y);
|
2005-05-06 12:23:19 +00:00
|
|
|
params[4] = READ_BE_UINT16(&vsp->flags);
|
2005-05-06 11:37:33 +00:00
|
|
|
_vcPtr = (byte *)params;
|
2005-05-06 13:22:48 +00:00
|
|
|
vc10_draw();
|
2003-05-21 11:49:41 +00:00
|
|
|
|
2005-10-05 11:37:26 +00:00
|
|
|
_windowNum = palmode;
|
2005-05-06 11:37:33 +00:00
|
|
|
_curVgaFile1 = old_file_1;
|
|
|
|
_curVgaFile2 = old_file_2;
|
2003-05-21 11:49:41 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
vsp++;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
2006-05-05 05:53:36 +00:00
|
|
|
_vcPtr = vcPtrOrg;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2003-12-23 08:59:30 +00:00
|
|
|
// Allow one section of Simon the Sorcerer 1 introduction to be displayed
|
|
|
|
// in lower half of screen
|
2005-11-13 11:53:57 +00:00
|
|
|
if ((getGameType() == GType_SIMON1) && (_subroutine == 2923 || _subroutine == 2926)) {
|
2003-12-23 08:59:30 +00:00
|
|
|
dx_clear_surfaces(200);
|
2006-09-28 23:22:07 +00:00
|
|
|
} else if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2005-11-13 11:53:57 +00:00
|
|
|
dx_clear_surfaces(480);
|
|
|
|
} else {
|
2005-10-05 11:37:26 +00:00
|
|
|
dx_clear_surfaces(_windowNum == 4 ? 134 : 200);
|
2005-11-13 11:53:57 +00:00
|
|
|
}
|
2003-05-21 11:49:41 +00:00
|
|
|
}
|
2005-11-12 06:01:24 +00:00
|
|
|
if (getGameType() == GType_SIMON2) {
|
2005-05-06 11:37:33 +00:00
|
|
|
if (_nextMusicToPlay != -1)
|
|
|
|
loadMusic(_nextMusicToPlay);
|
2003-05-21 11:49:41 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc63_fastFadeIn() {
|
2006-09-28 23:22:07 +00:00
|
|
|
if (getGameType() == GType_FF || getGameType() == GType_PP) {
|
2006-05-05 05:53:36 +00:00
|
|
|
_fastFadeInFlag = 256;
|
2005-11-15 04:07:05 +00:00
|
|
|
} else {
|
2006-05-05 05:53:36 +00:00
|
|
|
_fastFadeInFlag = 208;
|
2005-11-15 04:07:05 +00:00
|
|
|
if (_windowNum != 4) {
|
2006-05-05 05:53:36 +00:00
|
|
|
_fastFadeInFlag = 256;
|
2005-11-15 04:07:05 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
2005-11-15 04:07:05 +00:00
|
|
|
_fastFadeOutFlag = false;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc64_skipIfSpeechEnded() {
|
2006-04-15 05:24:44 +00:00
|
|
|
if ((getGameType() == GType_SIMON2 && _subtitles && _language != Common::HB_ISR) ||
|
|
|
|
!_sound->isVoiceActive()) {
|
2005-12-13 00:20:11 +00:00
|
|
|
vcSkipNextInstruction();
|
2006-04-15 05:24:44 +00:00
|
|
|
}
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc65_slowFadeIn() {
|
2006-05-05 05:53:36 +00:00
|
|
|
_fastFadeInFlag = 624;
|
|
|
|
_fastFadeCount = 208;
|
2005-10-05 11:37:26 +00:00
|
|
|
if (_windowNum != 4) {
|
2006-05-05 05:53:36 +00:00
|
|
|
_fastFadeInFlag = 768;
|
|
|
|
_fastFadeCount = 256;
|
2002-11-28 05:52:55 +00:00
|
|
|
}
|
2006-05-05 05:53:36 +00:00
|
|
|
_fastFadeInFlag |= 0x8000;
|
2005-11-15 04:07:05 +00:00
|
|
|
_fastFadeOutFlag = false;
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc66_skipIfNotEqual() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 a = vcReadNextWord();
|
|
|
|
uint16 b = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
if (vcReadVar(a) != vcReadVar(b))
|
|
|
|
vcSkipNextInstruction();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc67_skipIfGE() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 a = vcReadNextWord();
|
|
|
|
uint16 b = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
if (vcReadVar(a) >= vcReadVar(b))
|
|
|
|
vcSkipNextInstruction();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc68_skipIfLE() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 a = vcReadNextWord();
|
|
|
|
uint16 b = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
if (vcReadVar(a) <= vcReadVar(b))
|
|
|
|
vcSkipNextInstruction();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc69_playTrack() {
|
2005-12-13 00:20:11 +00:00
|
|
|
int16 track = vcReadNextWord();
|
|
|
|
int16 loop = vcReadNextWord();
|
2002-06-29 16:11:13 +00:00
|
|
|
|
2003-05-21 00:44:37 +00:00
|
|
|
// Jamieson630:
|
2003-05-21 04:36:09 +00:00
|
|
|
// This is a "play track". The original
|
2003-05-21 00:44:37 +00:00
|
|
|
// design stored the track to play if one was
|
|
|
|
// already in progress, so that the next time a
|
|
|
|
// "fill MIDI stream" event occured, the MIDI
|
|
|
|
// player would find the change and switch
|
|
|
|
// tracks. We use a different architecture that
|
|
|
|
// allows for an immediate response here, but
|
|
|
|
// we'll simulate the variable changes so other
|
|
|
|
// scripts don't get thrown off.
|
|
|
|
// NOTE: This opcode looks very similar in function
|
2005-05-06 13:22:48 +00:00
|
|
|
// to vc72(), except that vc72() may allow for
|
2003-05-21 00:44:37 +00:00
|
|
|
// specifying a non-valid track number (999 or -1)
|
|
|
|
// as a means of stopping what music is currently
|
|
|
|
// playing.
|
2003-09-24 06:33:59 +00:00
|
|
|
midi.setLoop(loop != 0);
|
|
|
|
midi.startTrack(track);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc70_queueMusic() {
|
2003-03-06 19:16:24 +00:00
|
|
|
// Simon2
|
2005-12-13 00:20:11 +00:00
|
|
|
uint16 track = vcReadNextWord();
|
|
|
|
uint16 loop = vcReadNextWord();
|
2003-05-21 04:36:09 +00:00
|
|
|
|
|
|
|
// Jamieson630:
|
|
|
|
// This sets the "on end of track" action.
|
|
|
|
// It specifies whether to loop the current
|
|
|
|
// track and, if not, whether to switch to
|
|
|
|
// a different track upon completion.
|
2003-05-21 11:23:53 +00:00
|
|
|
if (track != 0xFFFF && track != 999)
|
2003-09-24 06:33:59 +00:00
|
|
|
midi.queueTrack(track, loop != 0);
|
2003-07-13 06:29:49 +00:00
|
|
|
else
|
2003-09-24 06:33:59 +00:00
|
|
|
midi.setLoop(loop != 0);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc71_checkMusicQueue() {
|
2003-05-21 04:36:09 +00:00
|
|
|
// Jamieson630:
|
|
|
|
// This command skips the next instruction
|
|
|
|
// unless (1) there is a track playing, AND
|
|
|
|
// (2) there is a track queued to play after it.
|
|
|
|
if (!midi.isPlaying (true))
|
2005-12-13 00:20:11 +00:00
|
|
|
vcSkipNextInstruction();
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc72_play_track_2() {
|
2003-05-21 00:44:37 +00:00
|
|
|
// Jamieson630:
|
2003-05-21 05:12:04 +00:00
|
|
|
// This is a "play or stop track". Note that
|
|
|
|
// this opcode looks very similar in function
|
2005-05-06 13:22:48 +00:00
|
|
|
// to vc69(), except that this opcode may allow
|
2003-05-21 00:44:37 +00:00
|
|
|
// for specifying a track of 999 or -1 in order to
|
|
|
|
// stop the music. We'll code it that way for now.
|
2003-05-21 04:36:09 +00:00
|
|
|
|
|
|
|
// NOTE: It's possible that when "stopping" a track,
|
|
|
|
// we're supposed to just go on to the next queued
|
|
|
|
// track, if any. Must find out if there is ANY
|
|
|
|
// case where this is used to stop a track in the
|
|
|
|
// first place.
|
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
int16 track = vcReadNextWord();
|
|
|
|
int16 loop = vcReadNextWord();
|
2003-05-21 00:44:37 +00:00
|
|
|
|
2003-05-21 05:12:04 +00:00
|
|
|
if (track == -1 || track == 999) {
|
|
|
|
midi.stop();
|
|
|
|
} else {
|
|
|
|
midi.setLoop (loop != 0);
|
2003-05-21 06:13:47 +00:00
|
|
|
midi.startTrack (track);
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc73_setMark() {
|
2006-04-05 00:11:17 +00:00
|
|
|
_marks |= (1 << vcReadNextWord());
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc74_clearMark() {
|
2006-04-05 00:11:17 +00:00
|
|
|
_marks &= ~(1 << vcReadNextWord());
|
2002-06-29 16:11:13 +00:00
|
|
|
}
|
2003-10-03 19:42:27 +00:00
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
int AGOSEngine::getScale(int16 y, int16 x) {
|
2006-04-24 06:46:31 +00:00
|
|
|
int16 z;
|
2005-11-18 13:47:47 +00:00
|
|
|
|
|
|
|
if (y > _baseY) {
|
2006-04-24 06:46:31 +00:00
|
|
|
return((int16)(x * (1 + ((y - _baseY) * _scale))));
|
2005-11-18 13:47:47 +00:00
|
|
|
} else {
|
|
|
|
if (x == 0)
|
|
|
|
return(0);
|
|
|
|
if (x < 0) {
|
2006-04-24 06:46:31 +00:00
|
|
|
z = ((int16)((x * (1 - ((_baseY - y)* _scale))) - 0.5));
|
2005-11-18 13:47:47 +00:00
|
|
|
if (z >- 2)
|
|
|
|
return(-2);
|
|
|
|
return(z);
|
|
|
|
}
|
|
|
|
|
2006-04-24 06:46:31 +00:00
|
|
|
z = ((int16)((x * (1 - ((_baseY - y) * _scale))) + 0.5));
|
2005-11-18 13:47:47 +00:00
|
|
|
if (z < 2)
|
|
|
|
return(2);
|
|
|
|
|
|
|
|
return(z);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc75_setScale() {
|
2005-12-13 00:20:11 +00:00
|
|
|
_baseY = vcReadNextWord();
|
|
|
|
_scale = (float)vcReadNextWord() / 1000000.;
|
2005-10-09 09:03:37 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc76_setScaleXOffs() {
|
2005-12-13 00:20:11 +00:00
|
|
|
VgaSprite *vsp = findCurSprite();
|
2005-11-14 10:52:18 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
vsp->image = vcReadNextWord();
|
2006-01-11 04:06:51 +00:00
|
|
|
int16 x = vcReadNextWord();
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 var = vcReadNextWord();
|
2005-11-14 10:52:18 +00:00
|
|
|
|
2006-01-11 04:06:51 +00:00
|
|
|
vsp->x += getScale(vsp->y, x);
|
2006-04-15 22:14:39 +00:00
|
|
|
_variableArrayPtr[var] = vsp->x;
|
2005-11-18 12:40:03 +00:00
|
|
|
|
2006-04-07 09:04:36 +00:00
|
|
|
checkScrollX(x, vsp->x);
|
2005-11-18 13:47:47 +00:00
|
|
|
|
2006-03-23 04:49:03 +00:00
|
|
|
vsp->flags = kDFScaled;
|
2005-10-09 09:03:37 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc77_setScaleYOffs() {
|
2005-12-13 00:20:11 +00:00
|
|
|
VgaSprite *vsp = findCurSprite();
|
2005-11-14 10:52:18 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
vsp->image = vcReadNextWord();
|
2006-04-06 06:14:47 +00:00
|
|
|
int16 y = vcReadNextWord();
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 var = vcReadNextWord();
|
2005-11-14 10:52:18 +00:00
|
|
|
|
2006-04-06 06:14:47 +00:00
|
|
|
vsp->y += getScale(vsp->y, y);
|
2006-04-15 22:14:39 +00:00
|
|
|
_variableArrayPtr[var] = vsp->y;
|
2006-04-06 06:14:47 +00:00
|
|
|
|
2006-04-08 00:12:16 +00:00
|
|
|
if (y != 0)
|
|
|
|
checkScrollY(y, vsp->y);
|
2006-04-06 06:14:47 +00:00
|
|
|
|
2006-03-23 04:49:03 +00:00
|
|
|
vsp->flags = kDFScaled;
|
2005-10-09 09:03:37 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc78_computeXY() {
|
2005-12-13 00:20:11 +00:00
|
|
|
VgaSprite *vsp = findCurSprite();
|
2005-11-14 10:31:19 +00:00
|
|
|
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 a = (uint16)_variableArrayPtr[12];
|
|
|
|
uint16 b = (uint16)_variableArrayPtr[13];
|
2005-11-18 12:40:03 +00:00
|
|
|
|
2005-11-14 10:31:19 +00:00
|
|
|
const uint16 *p = _pathFindArray[a - 1];
|
|
|
|
p += b * 2;
|
|
|
|
|
2005-11-18 12:40:03 +00:00
|
|
|
uint16 posx = readUint16Wrapper(p);
|
2006-04-15 22:14:39 +00:00
|
|
|
_variableArrayPtr[15] = posx;
|
2005-11-14 10:31:19 +00:00
|
|
|
vsp->x = posx;
|
|
|
|
|
2005-11-18 12:40:03 +00:00
|
|
|
uint16 posy = readUint16Wrapper(p + 1);
|
2006-04-15 22:14:39 +00:00
|
|
|
_variableArrayPtr[16] = posy;
|
2005-11-14 10:31:19 +00:00
|
|
|
vsp->y = posy;
|
|
|
|
|
2006-04-04 10:12:22 +00:00
|
|
|
setBitFlag(85, false);
|
2006-04-09 04:53:31 +00:00
|
|
|
if (getBitFlag(74)) {
|
|
|
|
centreScroll();
|
2005-11-14 10:31:19 +00:00
|
|
|
}
|
2005-10-09 09:03:37 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc79_computePosNum() {
|
2006-04-15 22:14:39 +00:00
|
|
|
uint a = (uint16)_variableArrayPtr[12];
|
2005-11-18 12:40:03 +00:00
|
|
|
const uint16 *p = _pathFindArray[a - 1];
|
2006-01-11 04:06:51 +00:00
|
|
|
uint pos = 0;
|
2005-11-18 12:40:03 +00:00
|
|
|
|
2006-04-15 22:14:39 +00:00
|
|
|
int16 y = _variableArrayPtr[16];
|
2006-04-16 01:06:18 +00:00
|
|
|
while (y >= (int16)readUint16Wrapper(p + 1)) {
|
2005-11-18 12:40:03 +00:00
|
|
|
p += 2;
|
|
|
|
pos++;
|
|
|
|
}
|
|
|
|
|
2006-04-15 22:14:39 +00:00
|
|
|
_variableArrayPtr[13] = pos;
|
2005-10-09 09:03:37 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc80_setOverlayImage() {
|
2005-12-13 00:20:11 +00:00
|
|
|
VgaSprite *vsp = findCurSprite();
|
2005-10-09 09:03:37 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
vsp->image = vcReadVarOrWord();
|
2005-10-09 09:03:37 +00:00
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
vsp->x += vcReadNextWord();
|
|
|
|
vsp->y += vcReadNextWord();
|
2006-03-23 04:49:03 +00:00
|
|
|
vsp->flags = kDFOverlayed;
|
2005-10-09 09:03:37 +00:00
|
|
|
|
|
|
|
_vgaSpriteChanged++;
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc81_setRandom() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 var = vcReadNextWord();
|
|
|
|
uint16 value = vcReadNextWord();
|
2006-05-03 09:33:41 +00:00
|
|
|
|
|
|
|
_variableArray[var] = _rnd.getRandomNumber(value - 1);
|
2005-10-09 09:03:37 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc82_getPathValue() {
|
2005-11-18 14:15:03 +00:00
|
|
|
uint8 val;
|
|
|
|
|
2005-12-13 00:20:11 +00:00
|
|
|
uint16 var = vcReadNextWord();
|
2005-11-18 14:15:03 +00:00
|
|
|
|
2006-04-18 13:28:42 +00:00
|
|
|
if (getBitFlag(82)) {
|
2005-11-18 14:15:03 +00:00
|
|
|
val = _pathValues1[_GPVCount1++];
|
|
|
|
} else {
|
|
|
|
val = _pathValues[_GPVCount++];
|
|
|
|
}
|
2005-11-18 12:40:03 +00:00
|
|
|
|
2006-05-03 09:33:41 +00:00
|
|
|
vcWriteVar(var, val);
|
2005-10-09 09:03:37 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc83_playSoundLoop() {
|
2006-04-24 06:46:31 +00:00
|
|
|
uint16 sound = vcReadNextWord();
|
2006-04-23 15:42:02 +00:00
|
|
|
int16 vol = vcReadNextWord();
|
|
|
|
int16 pan = vcReadNextWord();
|
2006-04-17 12:05:45 +00:00
|
|
|
|
|
|
|
loadSound(sound, pan, vol, 3);
|
2005-10-09 09:03:37 +00:00
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::vc84_stopSoundLoop() {
|
2006-04-18 13:28:42 +00:00
|
|
|
_sound->stopSfx5();
|
2005-10-09 09:03:37 +00:00
|
|
|
}
|
|
|
|
|
2006-04-06 06:14:47 +00:00
|
|
|
// Scrolling functions for Feeble Files
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::checkScrollX(int16 x, int16 xpos) {
|
2006-04-06 06:14:47 +00:00
|
|
|
if (_scrollXMax == 0 || getBitFlag(80) || getBitFlag(82) || x == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int16 tmp;
|
|
|
|
if (x > 0) {
|
|
|
|
if (_scrollCount != 0) {
|
|
|
|
if (_scrollCount >= 0)
|
|
|
|
return;
|
|
|
|
_scrollCount = 0;
|
|
|
|
} else {
|
|
|
|
if (_scrollFlag != 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-04-07 09:04:36 +00:00
|
|
|
if (xpos - _scrollX >= 480) {
|
2006-04-06 06:14:47 +00:00
|
|
|
_scrollCount = 320;
|
|
|
|
tmp = _scrollXMax - _scrollX;
|
|
|
|
if (tmp < 320)
|
|
|
|
_scrollCount = tmp;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (_scrollCount != 0) {
|
|
|
|
if (_scrollCount < 0)
|
|
|
|
return;
|
|
|
|
_scrollCount = 0;
|
|
|
|
} else {
|
|
|
|
if (_scrollFlag != 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-04-18 00:15:25 +00:00
|
|
|
if (xpos - _scrollX < 161) {
|
2006-04-06 06:14:47 +00:00
|
|
|
_scrollCount = -320;
|
|
|
|
if (_scrollX < 320)
|
|
|
|
_scrollCount = -_scrollX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::checkScrollY(int16 y, int16 ypos) {
|
2006-04-06 06:14:47 +00:00
|
|
|
if (_scrollYMax == 0 || getBitFlag(80))
|
|
|
|
return;
|
|
|
|
|
|
|
|
int16 tmp;
|
2006-04-14 09:06:39 +00:00
|
|
|
if (y >= 0) {
|
2006-04-06 06:14:47 +00:00
|
|
|
if (_scrollCount != 0) {
|
|
|
|
if (_scrollCount >= 0)
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
if (_scrollFlag != 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-04-07 09:04:36 +00:00
|
|
|
if (ypos - _scrollY >= 440) {
|
2006-04-06 06:14:47 +00:00
|
|
|
_scrollCount = 240;
|
|
|
|
tmp = _scrollYMax - _scrollY;
|
|
|
|
if (tmp < 240)
|
|
|
|
_scrollCount = tmp;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (_scrollCount != 0) {
|
|
|
|
if (_scrollCount < 0)
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
if (_scrollFlag != 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-04-18 00:15:25 +00:00
|
|
|
if (ypos - _scrollY < 100) {
|
2006-04-06 06:14:47 +00:00
|
|
|
_scrollCount = -240;
|
|
|
|
if (_scrollY < 240)
|
|
|
|
_scrollCount = -_scrollY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
void AGOSEngine::centreScroll() {
|
2006-04-09 04:53:31 +00:00
|
|
|
int16 x, y, tmp;
|
|
|
|
|
|
|
|
if (_scrollXMax != 0) {
|
|
|
|
_scrollCount = 0;
|
|
|
|
x = _variableArray[15] - _scrollX;
|
2006-06-12 06:00:52 +00:00
|
|
|
if (x < 17 || (getBitFlag(85) && x < 320)) {
|
|
|
|
x -= 320;
|
|
|
|
if (_scrollX < -x)
|
|
|
|
x = -_scrollX;
|
|
|
|
_scrollCount = x;
|
|
|
|
} else if ((getBitFlag(85) && x >= 320) || x >= 624) {
|
2006-04-09 04:53:31 +00:00
|
|
|
x -= 320;
|
|
|
|
tmp = _scrollXMax - _scrollX;
|
|
|
|
if (tmp < x)
|
|
|
|
x = tmp;
|
|
|
|
_scrollCount = x;
|
|
|
|
}
|
|
|
|
} else if (_scrollYMax != 0) {
|
|
|
|
_scrollCount = 0;
|
|
|
|
y = _variableArray[16] - _scrollY;
|
2006-06-12 06:00:52 +00:00
|
|
|
if (y < 30) {
|
|
|
|
y -= 240;
|
|
|
|
if (_scrollY < -y)
|
|
|
|
y = -_scrollY;
|
|
|
|
_scrollCount = y;
|
|
|
|
} else if (y >= 460) {
|
2006-04-09 04:53:31 +00:00
|
|
|
y -= 240;
|
|
|
|
tmp = _scrollYMax - _scrollY;
|
|
|
|
if (tmp < y)
|
|
|
|
y = tmp;
|
|
|
|
_scrollCount = y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-29 09:44:30 +00:00
|
|
|
} // End of namespace AGOS
|