mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-30 14:14:43 +00:00
495 lines
9.8 KiB
C++
495 lines
9.8 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
#ifdef ENABLE_AGOS2
|
|
|
|
#include "agos/agos.h"
|
|
#include "agos/intern.h"
|
|
#include "agos/sound.h"
|
|
|
|
namespace AGOS {
|
|
|
|
void AGOSEngine_Feeble::setupVideoOpcodes(VgaOpcodeProc *op) {
|
|
AGOSEngine_Simon2::setupVideoOpcodes(op);
|
|
|
|
op[75] = &AGOSEngine::vc75_setScale;
|
|
op[76] = &AGOSEngine::vc76_setScaleXOffs;
|
|
op[77] = &AGOSEngine::vc77_setScaleYOffs;
|
|
op[78] = &AGOSEngine::vc78_computeXY;
|
|
op[79] = &AGOSEngine::vc79_computePosNum;
|
|
op[80] = &AGOSEngine::vc80_setOverlayImage;
|
|
op[81] = &AGOSEngine::vc81_setRandom;
|
|
op[82] = &AGOSEngine::vc82_getPathValue;
|
|
op[83] = &AGOSEngine::vc83_playSoundLoop;
|
|
op[84] = &AGOSEngine::vc84_stopSoundLoop;
|
|
}
|
|
|
|
int AGOSEngine::getScale(int16 y, int16 x) {
|
|
int16 z;
|
|
|
|
if (y > _baseY) {
|
|
return((int16)(x * (1 + ((y - _baseY) * _scale))));
|
|
} else {
|
|
if (x == 0)
|
|
return(0);
|
|
if (x < 0) {
|
|
z = ((int16)((x * (1 - ((_baseY - y)* _scale))) - 0.5));
|
|
if (z >- 2)
|
|
return(-2);
|
|
return(z);
|
|
}
|
|
|
|
z = ((int16)((x * (1 - ((_baseY - y) * _scale))) + 0.5));
|
|
if (z < 2)
|
|
return(2);
|
|
|
|
return(z);
|
|
}
|
|
}
|
|
|
|
void AGOSEngine_Feeble::vc36_setWindowImage() {
|
|
_displayFlag = 0;
|
|
vcReadNextWord();
|
|
vcReadNextWord();
|
|
fillBackGroundFromFront();
|
|
}
|
|
|
|
void AGOSEngine_Feeble::vc48_setPathFinder() {
|
|
uint16 a = (uint16)_variableArrayPtr[12];
|
|
const uint16 *p = _pathFindArray[a - 1];
|
|
|
|
VgaSprite *vsp = findCurSprite();
|
|
int16 x, y, ydiff;
|
|
int16 x1, y1, x2, y2;
|
|
uint pos = 0;
|
|
|
|
x = vsp->x;
|
|
while (x >= (int16)readUint16Wrapper(p + 2)) {
|
|
p += 2;
|
|
pos++;
|
|
}
|
|
|
|
x1 = readUint16Wrapper(p);
|
|
y1 = readUint16Wrapper(p + 1);
|
|
x2 = readUint16Wrapper(p + 2);
|
|
y2 = readUint16Wrapper(p + 3);
|
|
|
|
if (x2 != 9999) {
|
|
ydiff = y2 - y1;
|
|
if (ydiff < 0) {
|
|
ydiff = -ydiff;
|
|
x = vsp->x & 7;
|
|
ydiff *= x;
|
|
ydiff /= 8;
|
|
ydiff = -ydiff;
|
|
} else {
|
|
x = vsp->x & 7;
|
|
ydiff *= x;
|
|
ydiff /= 8;
|
|
}
|
|
y1 += ydiff;
|
|
}
|
|
|
|
y = vsp->y;
|
|
vsp->y = y1;
|
|
checkScrollY(y1 - y, y1);
|
|
|
|
_variableArrayPtr[11] = x1;
|
|
_variableArrayPtr[13] = pos;
|
|
}
|
|
|
|
void AGOSEngine::vc75_setScale() {
|
|
_baseY = vcReadNextWord();
|
|
_scale = vcReadNextWord() / 1000000.0f;
|
|
}
|
|
|
|
void AGOSEngine::vc76_setScaleXOffs() {
|
|
if (getGameType() == GType_PP && getBitFlag(120)) {
|
|
VgaSprite *vsp1, *vsp2;
|
|
uint16 old_file_1, tmp1, tmp2;
|
|
|
|
old_file_1 = _vgaCurSpriteId;
|
|
|
|
_vgaCurSpriteId = vcReadVar(vcReadNextWord());
|
|
vsp1 = findCurSprite();
|
|
_vgaCurSpriteId = vcReadVar(vcReadNextWord());
|
|
vsp2 = findCurSprite();
|
|
|
|
tmp1 = vsp1->x;
|
|
tmp2 = vsp2->x;
|
|
vsp1->x = tmp2;
|
|
vsp2->x = tmp1;
|
|
tmp1 = vsp1->y;
|
|
tmp2 = vsp2->y;
|
|
vsp1->y = tmp2;
|
|
vsp2->y = tmp1;
|
|
|
|
_vgaCurSpriteId = old_file_1;
|
|
_vcPtr += 2;
|
|
} else {
|
|
VgaSprite *vsp = findCurSprite();
|
|
|
|
vsp->image = vcReadNextWord();
|
|
int16 x = vcReadNextWord();
|
|
uint16 var = vcReadNextWord();
|
|
|
|
vsp->x += getScale(vsp->y, x);
|
|
_variableArrayPtr[var] = vsp->x;
|
|
|
|
checkScrollX(x, vsp->x);
|
|
|
|
vsp->flags = kDFScaled;
|
|
}
|
|
}
|
|
|
|
void AGOSEngine::vc77_setScaleYOffs() {
|
|
VgaSprite *vsp = findCurSprite();
|
|
|
|
vsp->image = vcReadNextWord();
|
|
int16 y = vcReadNextWord();
|
|
uint16 var = vcReadNextWord();
|
|
|
|
vsp->y += getScale(vsp->y, y);
|
|
_variableArrayPtr[var] = vsp->y;
|
|
|
|
if (y != 0)
|
|
checkScrollY(y, vsp->y);
|
|
|
|
vsp->flags = kDFScaled;
|
|
}
|
|
|
|
void AGOSEngine::vc78_computeXY() {
|
|
VgaSprite *vsp = findCurSprite();
|
|
|
|
uint16 a = (uint16)_variableArrayPtr[12];
|
|
uint16 b = (uint16)_variableArrayPtr[13];
|
|
|
|
const uint16 *p = _pathFindArray[a - 1];
|
|
p += b * 2;
|
|
|
|
uint16 posx = readUint16Wrapper(p);
|
|
_variableArrayPtr[15] = posx;
|
|
vsp->x = posx;
|
|
|
|
uint16 posy = readUint16Wrapper(p + 1);
|
|
_variableArrayPtr[16] = posy;
|
|
vsp->y = posy;
|
|
|
|
if (getGameType() == GType_FF) {
|
|
setBitFlag(85, false);
|
|
if (getBitFlag(74)) {
|
|
centerScroll();
|
|
}
|
|
}
|
|
}
|
|
|
|
void AGOSEngine::vc79_computePosNum() {
|
|
uint a = (uint16)_variableArrayPtr[12];
|
|
const uint16 *p = _pathFindArray[a - 1];
|
|
uint pos = 0;
|
|
|
|
int16 y = _variableArrayPtr[16];
|
|
while (y >= (int16)readUint16Wrapper(p + 1)) {
|
|
p += 2;
|
|
pos++;
|
|
}
|
|
|
|
_variableArrayPtr[13] = pos;
|
|
}
|
|
|
|
void AGOSEngine::vc80_setOverlayImage() {
|
|
VgaSprite *vsp = findCurSprite();
|
|
|
|
vsp->image = vcReadVarOrWord();
|
|
|
|
vsp->x += vcReadNextWord();
|
|
vsp->y += vcReadNextWord();
|
|
vsp->flags = kDFOverlayed;
|
|
|
|
_vgaSpriteChanged++;
|
|
}
|
|
|
|
void AGOSEngine::vc81_setRandom() {
|
|
uint16 var = vcReadNextWord();
|
|
uint16 value = vcReadNextWord();
|
|
|
|
_variableArray[var] = _rnd.getRandomNumber(value - 1);
|
|
}
|
|
|
|
void AGOSEngine::vc82_getPathValue() {
|
|
uint8 val;
|
|
|
|
uint16 var = vcReadNextWord();
|
|
|
|
if (getGameType() == GType_FF && getBitFlag(82)) {
|
|
val = _pathValues1[_GPVCount1++];
|
|
} else {
|
|
val = _pathValues[_GPVCount++];
|
|
}
|
|
|
|
vcWriteVar(var, val);
|
|
}
|
|
|
|
void AGOSEngine::vc83_playSoundLoop() {
|
|
uint16 sound = vcReadNextWord();
|
|
int16 vol = vcReadNextWord();
|
|
int16 pan = vcReadNextWord();
|
|
|
|
loadSound(sound, pan, vol, Sound::TYPE_SFX5);
|
|
}
|
|
|
|
void AGOSEngine::vc84_stopSoundLoop() {
|
|
_sound->stopSfx5();
|
|
}
|
|
|
|
// Scrolling functions for Feeble Files
|
|
void AGOSEngine::checkScrollX(int16 x, int16 xpos) {
|
|
if (_scrollXMax == 0 || x == 0)
|
|
return;
|
|
|
|
if (getGameType() == GType_FF && (getBitFlag(80) || getBitFlag(82)))
|
|
return;
|
|
|
|
int16 tmp;
|
|
if (x > 0) {
|
|
if (_scrollCount != 0) {
|
|
if (_scrollCount >= 0)
|
|
return;
|
|
_scrollCount = 0;
|
|
} else {
|
|
if (_scrollFlag != 0)
|
|
return;
|
|
}
|
|
|
|
if (xpos - _scrollX >= 480) {
|
|
_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;
|
|
}
|
|
|
|
if (xpos - _scrollX < 161) {
|
|
_scrollCount = -320;
|
|
if (_scrollX < 320)
|
|
_scrollCount = -_scrollX;
|
|
}
|
|
}
|
|
}
|
|
|
|
void AGOSEngine::checkScrollY(int16 y, int16 ypos) {
|
|
if (_scrollYMax == 0)
|
|
return;
|
|
|
|
if (getGameType() == GType_FF && getBitFlag(80))
|
|
return;
|
|
|
|
int16 tmp;
|
|
if (y >= 0) {
|
|
if (_scrollCount != 0) {
|
|
if (_scrollCount >= 0)
|
|
return;
|
|
} else {
|
|
if (_scrollFlag != 0)
|
|
return;
|
|
}
|
|
|
|
if (ypos - _scrollY >= 440) {
|
|
_scrollCount = 240;
|
|
tmp = _scrollYMax - _scrollY;
|
|
if (tmp < 240)
|
|
_scrollCount = tmp;
|
|
}
|
|
} else {
|
|
if (_scrollCount != 0) {
|
|
if (_scrollCount < 0)
|
|
return;
|
|
} else {
|
|
if (_scrollFlag != 0)
|
|
return;
|
|
}
|
|
|
|
if (ypos - _scrollY < 100) {
|
|
_scrollCount = -240;
|
|
if (_scrollY < 240)
|
|
_scrollCount = -_scrollY;
|
|
}
|
|
}
|
|
}
|
|
|
|
void AGOSEngine::centerScroll() {
|
|
int16 x, y, tmp;
|
|
|
|
if (_scrollXMax != 0) {
|
|
_scrollCount = 0;
|
|
x = _variableArray[15] - _scrollX;
|
|
if (x < 17 || (getBitFlag(85) && x < 320)) {
|
|
x -= 320;
|
|
if (_scrollX < -x)
|
|
x = -_scrollX;
|
|
_scrollCount = x;
|
|
} else if ((getBitFlag(85) && x >= 320) || x >= 624) {
|
|
x -= 320;
|
|
tmp = _scrollXMax - _scrollX;
|
|
if (tmp < x)
|
|
x = tmp;
|
|
_scrollCount = x;
|
|
}
|
|
} else if (_scrollYMax != 0) {
|
|
_scrollCount = 0;
|
|
y = _variableArray[16] - _scrollY;
|
|
if (y < 30) {
|
|
y -= 240;
|
|
if (_scrollY < -y)
|
|
y = -_scrollY;
|
|
_scrollCount = y;
|
|
} else if (y >= 460) {
|
|
y -= 240;
|
|
tmp = _scrollYMax - _scrollY;
|
|
if (tmp < y)
|
|
y = tmp;
|
|
_scrollCount = y;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Puzzle Pack specific code
|
|
|
|
void AGOSEngine_PuzzlePack::vc3_loadSprite() {
|
|
if (getGameId() != GID_DIMP && getBitFlag(100)) {
|
|
startAnOverlayAnim();
|
|
return;
|
|
}
|
|
|
|
AGOSEngine::vc3_loadSprite();
|
|
}
|
|
|
|
void AGOSEngine_PuzzlePack::vc63_fastFadeIn() {
|
|
_fastFadeInFlag = 256;
|
|
_fastFadeOutFlag = false;
|
|
|
|
if (getGameId() == GID_DIMP)
|
|
return;
|
|
|
|
if (getBitFlag(100)) {
|
|
startOverlayAnims();
|
|
} else if (getBitFlag(103)) {
|
|
debug("vc63_fastFadeIn: NameAndTime");
|
|
} else if (getBitFlag(104)) {
|
|
debug("vc63_fastFadeIn: HiScoreTable");
|
|
}
|
|
}
|
|
|
|
void AGOSEngine_PuzzlePack::startOverlayAnims() {
|
|
VgaSprite *vsp = _vgaSprites;
|
|
uint16 zoneNum;
|
|
int i;
|
|
|
|
zoneNum = _variableArray[999];
|
|
|
|
for (i = 0; i < 600; i++) {
|
|
if (_variableArray[1000 + i] < 100)
|
|
continue;
|
|
|
|
while (vsp->id)
|
|
vsp++;
|
|
|
|
vsp->windowNum = 4;
|
|
vsp->priority = 4;
|
|
vsp->flags = 0;
|
|
vsp->palette = 0;
|
|
vsp->image = _variableArray[1000 + i];
|
|
if (i >= 300) {
|
|
vsp->y = ((i - 300) / 20) * 32;
|
|
vsp->x = ((i - 300) % 20) * 32;
|
|
} else {
|
|
vsp->y = (i / 20) * 32;
|
|
vsp->x = (i % 20) * 32;
|
|
}
|
|
vsp->id = 1000 + i;
|
|
vsp->zoneNum = zoneNum;
|
|
}
|
|
}
|
|
|
|
void AGOSEngine_PuzzlePack::startAnOverlayAnim() {
|
|
VgaSprite *vsp = _vgaSprites;
|
|
const byte *vcPtrOrg;
|
|
uint16 a, sprite, file, tmp, zoneNum;
|
|
int16 x;
|
|
|
|
zoneNum = _variableArray[999];
|
|
|
|
_vcPtr += 4;
|
|
a = vcReadNextWord();
|
|
_vcPtr += 6;
|
|
|
|
while (vsp->id)
|
|
vsp++;
|
|
|
|
vsp->windowNum = 4;
|
|
vsp->priority = 20;
|
|
vsp->flags = 0;
|
|
vsp->palette = 0;
|
|
vsp->image = vcReadVar(vcReadVar(a));
|
|
|
|
x = vcReadVar(a) - 1300;
|
|
if (x < 0) {
|
|
x += 300;
|
|
vsp->priority = 10;
|
|
}
|
|
|
|
vsp->y = x / 20 * 32;
|
|
vsp->x = x % 20 * 32;
|
|
vsp->id = vcReadVar(a);
|
|
vsp->zoneNum = zoneNum;
|
|
|
|
sprite = _vgaCurSpriteId;
|
|
file = _vgaCurZoneNum;
|
|
|
|
_vgaCurZoneNum = vsp->zoneNum;
|
|
_vgaCurSpriteId = vsp->id;
|
|
|
|
tmp = to16Wrapper(vsp->priority);
|
|
|
|
vcPtrOrg = _vcPtr;
|
|
_vcPtr = (byte *)&tmp;
|
|
vc23_setPriority();
|
|
|
|
_vcPtr = vcPtrOrg;
|
|
_vgaCurSpriteId = sprite;
|
|
_vgaCurZoneNum = file;
|
|
}
|
|
|
|
} // End of namespace AGOS
|
|
|
|
#endif // ENABLE_AGOS2
|