aboutsummaryrefslogtreecommitdiff
path: root/engines/agos
diff options
context:
space:
mode:
authorTravis Howell2006-10-20 02:10:51 +0000
committerTravis Howell2006-10-20 02:10:51 +0000
commitff574a63ee368cdb4889dd0e17966b4a1ae1f117 (patch)
tree40f477be1667843709f794e9628870ac3e3258cc /engines/agos
parente26954bcdb0a0277b5c6df4e785d1909d9865c7f (diff)
downloadscummvm-rg350-ff574a63ee368cdb4889dd0e17966b4a1ae1f117.tar.gz
scummvm-rg350-ff574a63ee368cdb4889dd0e17966b4a1ae1f117.tar.bz2
scummvm-rg350-ff574a63ee368cdb4889dd0e17966b4a1ae1f117.zip
Split code into more specific files and cleanup
svn-id: r24394
Diffstat (limited to 'engines/agos')
-rw-r--r--engines/agos/agos.cpp1549
-rw-r--r--engines/agos/agos.h2
-rw-r--r--engines/agos/gfx.cpp743
-rw-r--r--engines/agos/icons.cpp2
-rw-r--r--engines/agos/input.cpp518
-rw-r--r--engines/agos/items.cpp418
-rw-r--r--engines/agos/module.mk9
-rw-r--r--engines/agos/script.cpp81
-rw-r--r--engines/agos/script_ff.cpp1
-rw-r--r--engines/agos/script_pp.cpp1
-rw-r--r--engines/agos/script_s1.cpp21
-rw-r--r--engines/agos/script_s2.cpp7
-rw-r--r--engines/agos/string.cpp24
-rw-r--r--engines/agos/subroutine.cpp20
-rw-r--r--engines/agos/verb.cpp12
-rw-r--r--engines/agos/vga.cpp1812
-rw-r--r--engines/agos/vga_ff.cpp437
-rw-r--r--engines/agos/vga_s1.cpp215
-rw-r--r--engines/agos/vga_s2.cpp211
-rw-r--r--engines/agos/zones.cpp196
20 files changed, 3217 insertions, 3062 deletions
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
index e2775c542e..40f099d57d 100644
--- a/engines/agos/agos.cpp
+++ b/engines/agos/agos.cpp
@@ -791,1416 +791,6 @@ void AGOSEngine::paletteFadeOut(byte *palPtr, uint num, uint size) {
} while (--num);
}
-byte *AGOSEngine::allocateItem(uint size) {
- byte *org = _itemHeapPtr;
- size = (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
-
- _itemHeapPtr += size;
- _itemHeapCurPos += size;
-
- if (_itemHeapCurPos > _itemHeapSize)
- error("allocateItem: Itemheap overflow");
-
- return org;
-}
-
-int AGOSEngine::getUserFlag(Item *item, int a) {
- SubUserFlag *subUserFlag;
-
- subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
- if (subUserFlag == NULL)
- return 0;
-
- if (a < 0 || a > 7)
- return 0;
-
- return subUserFlag->userFlags[a];
-}
-
-void AGOSEngine::setUserFlag(Item *item, int a, int b) {
- SubUserFlag *subUserFlag;
-
- subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
- if (subUserFlag == NULL) {
- subUserFlag = (SubUserFlag *) allocateChildBlock(item, 9, sizeof(SubUserFlag));
- }
-
- if (a < 0 || a > 7)
- return;
-
- subUserFlag->userFlags[a] = b;
-}
-
-int AGOSEngine::getUserItem(Item *item, int n) {
- SubUserFlag *subUserFlag;
-
- subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
- if (subUserFlag == NULL)
- return 0;
-
- if (n < 0 || n > 0)
- return 0;
-
- return subUserFlag->userItems[n];
-}
-
-void AGOSEngine::setUserItem(Item *item, int n, int m) {
- SubUserFlag *subUserFlag;
-
- subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
- if (subUserFlag == NULL) {
- subUserFlag = (SubUserFlag *) allocateChildBlock(item, 9, sizeof(SubUserFlag));
- }
-
- if (n == 0)
- subUserFlag->userItems[n] = m;
-}
-
-void AGOSEngine::createPlayer() {
- SubPlayer *p;
-
- _currentPlayer = _itemArrayPtr[1];
- _currentPlayer->adjective = -1;
- _currentPlayer->noun = 10000;
-
- p = (SubPlayer *)allocateChildBlock(_currentPlayer, 3, sizeof(SubPlayer));
- if (p == NULL)
- error("createPlayer: player create failure");
-
- p->size = 0;
- p->weight = 0;
- p->strength = 6000;
- //p->flag = xxx;
- p->level = 1;
- p->score = 0;
-
- setUserFlag(_currentPlayer, 0, 0);
-}
-
-Child *AGOSEngine::findChildOfType(Item *i, uint type) {
- Child *child = i->children;
- for (; child; child = child->next)
- if (child->type == type)
- return child;
- return NULL;
-}
-
-bool AGOSEngine::isRoom(Item *item) {
- return findChildOfType(item, 1) != NULL;
-}
-
-bool AGOSEngine::isObject(Item *item) {
- return findChildOfType(item, 2) != NULL;
-}
-
-bool AGOSEngine::isPlayer(Item *item) {
- return findChildOfType(item, 3) != NULL;
-}
-
-uint AGOSEngine::getOffsetOfChild2Param(SubObject *child, uint prop) {
- uint m = 1;
- uint offset = 0;
- while (m != prop) {
- if (child->objectFlags & m)
- offset++;
- m *= 2;
- }
- return offset;
-}
-
-Child *AGOSEngine::allocateChildBlock(Item *i, uint type, uint size) {
- Child *child = (Child *)allocateItem(size);
- child->next = i->children;
- i->children = child;
- child->type = type;
- return child;
-}
-
-void AGOSEngine::allocItemHeap() {
- _itemHeapSize = _itemMemSize;
- _itemHeapCurPos = 0;
- _itemHeapPtr = (byte *)calloc(_itemMemSize, 1);
- if (!_itemHeapPtr)
- error("Out Of Memory - Items");
-}
-
-void AGOSEngine::allocTablesHeap() {
- _tablesHeapSize = _tableMemSize;
- _tablesHeapCurPos = 0;
- _tablesHeapPtr = (byte *)calloc(_tableMemSize, 1);
- if (!_tablesHeapPtr)
- error("Out Of Memory - Tables");
-}
-
-void AGOSEngine::setItemState(Item *item, int value) {
- item->state = value;
-}
-
-byte AGOSEngine::getByte() {
- return *_codePtr++;
-}
-
-int AGOSEngine::getNextWord() {
- int16 a = (int16)READ_BE_UINT16(_codePtr);
- _codePtr += 2;
- return a;
-}
-
-uint AGOSEngine::getNextStringID() {
- return (uint16)getNextWord();
-}
-
-uint AGOSEngine::getVarOrByte() {
- if (getGameType() == GType_ELVIRA1) {
- return getVarOrWord();
- } else {
- uint a = *_codePtr++;
- if (a != 255)
- return a;
- return readVariable(*_codePtr++);
- }
-}
-
-uint AGOSEngine::getVarOrWord() {
- uint a = READ_BE_UINT16(_codePtr);
- _codePtr += 2;
- if (getGameType() == GType_PP) {
- if (a >= 60000 && a < 62048) {
- return readVariable(a - 60000);
- }
- } else {
- if (a >= 30000 && a < 30512) {
- return readVariable(a - 30000);
- }
- }
- return a;
-}
-
-uint AGOSEngine::getVarWrapper() {
- if (getGameType() == GType_ELVIRA1 || getGameType() == GType_PP)
- return getVarOrWord();
- else
- return getVarOrByte();
-}
-
-Item *AGOSEngine::getNextItemPtr() {
- int a = getNextWord();
- switch (a) {
- case -1:
- return _subjectItem;
- case -3:
- return _objectItem;
- case -5:
- return me();
- case -7:
- return actor();
- case -9:
- return derefItem(me()->parent);
- default:
- return derefItem(a);
- }
-}
-
-Item *AGOSEngine::getNextItemPtrStrange() {
- int a = getNextWord();
- switch (a) {
- case -1:
- return _subjectItem;
- case -3:
- return _objectItem;
- case -5:
- return _dummyItem2;
- case -7:
- return NULL;
- case -9:
- return _dummyItem3;
- default:
- return derefItem(a);
- }
-}
-
-uint AGOSEngine::getNextItemID() {
- int a = getNextWord();
- switch (a) {
- case -1:
- return itemPtrToID(_subjectItem);
- case -3:
- return itemPtrToID(_objectItem);
- case -5:
- return getItem1ID();
- case -7:
- return 0;
- case -9:
- return me()->parent;
- default:
- return a;
- }
-}
-
-Item *AGOSEngine::me() {
- if (_currentPlayer)
- return _currentPlayer;
- return _dummyItem1;
-}
-
-Item *AGOSEngine::actor() {
- error("actor: is this code ever used?");
- //if (_actorPlayer)
- // return _actorPlayer;
- return _dummyItem1;
-}
-
-uint AGOSEngine::getNextVarContents() {
- return (uint16)readVariable(getVarWrapper());
-}
-
-uint AGOSEngine::readVariable(uint variable) {
- if (variable >= _numVars)
- error("readVariable: Variable %d out of range", variable);
-
- if (getGameType() == GType_PP) {
- return (uint16)_variableArray[variable];
- } else if (getGameType() == GType_FF) {
- if (getBitFlag(83))
- return (uint16)_variableArray2[variable];
- else
- return (uint16)_variableArray[variable];
- } else {
- return _variableArray[variable];
- }
-}
-
-void AGOSEngine::writeNextVarContents(uint16 contents) {
- writeVariable(getVarWrapper(), contents);
-}
-
-void AGOSEngine::writeVariable(uint variable, uint16 contents) {
- if (variable >= _numVars)
- error("writeVariable: Variable %d out of range", variable);
-
- if (getGameType() == GType_FF && getBitFlag(83))
- _variableArray2[variable] = contents;
- else
- _variableArray[variable] = contents;
-}
-
-void AGOSEngine::setItemParent(Item *item, Item *parent) {
- Item *old_parent = derefItem(item->parent);
-
- if (item == parent)
- error("setItemParent: Trying to set item as its own parent");
-
- // unlink it if it has a parent
- if (old_parent)
- unlinkItem(item);
- itemChildrenChanged(old_parent);
- linkItem(item, parent);
- itemChildrenChanged(parent);
-}
-
-void AGOSEngine::itemChildrenChanged(Item *item) {
- int i;
- WindowBlock *window;
-
- if (_noParentNotify)
- return;
-
- mouseOff();
-
- for (i = 0; i != 8; i++) {
- window = _windowArray[i];
- if (window && window->iconPtr && window->iconPtr->itemRef == item) {
- if (_fcsData1[i]) {
- _fcsData2[i] = true;
- } else {
- _fcsData2[i] = false;
- drawIconArray(i, item, window->iconPtr->line, window->iconPtr->classMask);
- }
- }
- }
-
- mouseOn();
-}
-
-void AGOSEngine::unlinkItem(Item *item) {
- Item *first, *parent, *next;
-
- // can't unlink item without parent
- if (item->parent == 0)
- return;
-
- // get parent and first child of parent
- parent = derefItem(item->parent);
- first = derefItem(parent->child);
-
- // the node to remove is first in the parent's children?
- if (first == item) {
- parent->child = item->next;
- item->parent = 0;
- item->next = 0;
- return;
- }
-
- for (;;) {
- if (!first)
- error("unlinkItem: parent empty");
- if (first->next == 0)
- error("unlinkItem: parent does not contain child");
-
- next = derefItem(first->next);
- if (next == item) {
- first->next = next->next;
- item->parent = 0;
- item->next = 0;
- return;
- }
- first = next;
- }
-}
-
-void AGOSEngine::linkItem(Item *item, Item *parent) {
- uint id;
- // Don't allow that an item that is already linked is relinked
- if (item->parent)
- return;
-
- id = itemPtrToID(parent);
- item->parent = id;
-
- if (parent != 0) {
- item->next = parent->child;
- parent->child = itemPtrToID(item);
- } else {
- item->next = 0;
- }
-}
-
-void AGOSEngine::setup_cond_c_helper() {
- HitArea *last;
- uint id;
-
- _noRightClick = 1;
-
- if (getGameType() == GType_WW)
- clearMenuStrip();
-
- if (getGameType() == GType_FF) {
- int cursor = 5;
- int animMax = 16;
-
- if (getBitFlag(200)) {
- cursor = 11;
- animMax = 5;
- } else if (getBitFlag(201)) {
- cursor = 12;
- animMax = 5;
- } else if (getBitFlag(202)) {
- cursor = 13;
- animMax = 5;
- } else if (getBitFlag(203)) {
- cursor = 14;
- animMax = 9;
- } else if (getBitFlag(205)) {
- cursor = 17;
- animMax = 11;
- } else if (getBitFlag(206)) {
- cursor = 16;
- animMax = 2;
- } else if (getBitFlag(208)) {
- cursor = 26;
- animMax = 2;
- } else if (getBitFlag(209)) {
- cursor = 27;
- animMax = 9;
- } else if (getBitFlag(210)) {
- cursor = 28;
- animMax = 9;
- }
-
- _animatePointer = 0;
- _mouseCursor = cursor;
- _mouseAnimMax = animMax;
- _mouseAnim = 1;
- _needHitAreaRecalc++;
- }
-
- if (getGameType() == GType_SIMON2) {
- _mouseCursor = 0;
- if (_defaultVerb != 999) {
- _mouseCursor = 9;
- _needHitAreaRecalc++;
- _defaultVerb = 0;
- }
- }
-
- _lastHitArea = 0;
- _hitAreaObjectItem = NULL;
- _nameLocked = 0;
-
- last = _lastNameOn;
- clearName();
- _lastNameOn = last;
-
- for (;;) {
- _lastHitArea = NULL;
- _lastHitArea3 = 0;
- _leftButtonDown = 0;
-
- do {
- if (_exitCutscene && getBitFlag(9)) {
- endCutscene();
- goto out_of_here;
- }
-
- if (getGameType() == GType_FF) {
- if (_variableArray[254] == 63) {
- hitarea_stuff_helper_2();
- } else if (_variableArray[254] == 75) {
- hitarea_stuff_helper_2();
- _variableArray[60] = 9999;
- goto out_of_here;
- }
- }
-
- delay(100);
- } while (_lastHitArea3 == (HitArea *) -1 || _lastHitArea3 == 0);
-
- if (_lastHitArea == NULL) {
- } else if (_lastHitArea->id == 0x7FFB) {
- inventoryUp(_lastHitArea->window);
- } else if (_lastHitArea->id == 0x7FFC) {
- inventoryDown(_lastHitArea->window);
- } else if (_lastHitArea->item_ptr != NULL) {
- _hitAreaObjectItem = _lastHitArea->item_ptr;
- id = 0xFFFF;
- if (_lastHitArea->flags & kBFTextBox) {
- if (getGameType() == GType_PP)
- id = _lastHitArea->id;
- else if (getGameType() == GType_FF && (_lastHitArea->flags & kBFHyperBox))
- id = _lastHitArea->data;
- else
- id = _lastHitArea->flags / 256;
- }
- if (getGameType() == GType_PP)
- _variableArray[199] = id;
- else if (getGameType() == GType_WW)
- _variableArray[10] = id;
- else
- _variableArray[60] = id;
- break;
- }
- }
-
-out_of_here:
- _lastHitArea3 = 0;
- _lastHitArea = 0;
- _lastNameOn = NULL;
- _mouseCursor = 0;
- _noRightClick = 0;
-}
-
-void AGOSEngine::endCutscene() {
- Subroutine *sub;
-
- _sound->stopVoice();
-
- sub = getSubroutineByID(170);
- if (sub != NULL)
- startSubroutineEx(sub);
-
- _runScriptReturn1 = true;
-}
-
-bool AGOSEngine::has_item_childflag_0x10(Item *item) {
- SubObject *child = (SubObject *)findChildOfType(item, 2);
- return child && (child->objectFlags & kOFIcon) != 0;
-}
-
-uint AGOSEngine::itemGetIconNumber(Item *item) {
- if (getGameType() == GType_ELVIRA1) {
- return getUserFlag(item, 7);
- } else {
- SubObject *child = (SubObject *)findChildOfType(item, 2);
- uint offs;
-
- if (child == NULL || !(child->objectFlags & kOFIcon))
- return 0;
-
- offs = getOffsetOfChild2Param(child, 0x10);
- return child->objectFlagValue[offs];
- }
-}
-
-void AGOSEngine::waitForInput() {
- HitArea *ha;
- uint id;
-
- _leftButtonDown = 0;
- _lastHitArea = 0;
- _verbHitArea = 0;
- _hitAreaSubjectItem = NULL;
- _hitAreaObjectItem = NULL;
- _nameLocked = 0;
-
- if (getGameType() == GType_WW) {
- _mouseCursor = 0;
- _needHitAreaRecalc++;
- clearMenuStrip();
- } else {
- resetVerbs();
- }
-
-startOver:
- for (;;) {
- _lastHitArea = NULL;
- _lastHitArea3 = NULL;
-
- for (;;) {
- if (getGameType() != GType_FF && getGameType() != GType_PP && _keyPressed == 35)
- displayBoxStars();
- if (processSpecialKeys() != 0) {
- goto out_of_here;
- }
- if (_lastHitArea3 == (HitArea *) -1)
- goto startOver;
- if (_lastHitArea3 != 0)
- break;
- hitarea_stuff_helper();
- delay(100);
- }
-
- ha = _lastHitArea;
-
- if (ha == NULL) {
- } else if (ha->id == 0x7FFB) {
- inventoryUp(ha->window);
- } else if (ha->id == 0x7FFC) {
- inventoryDown(ha->window);
- } else if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
- (ha->id >= 101 && ha->id < 113)) {
- _verbHitArea = ha->verb;
- setVerb(ha);
- _defaultVerb = 0;
- } else {
- if (getGameType() == GType_WW) {
- if (_mouseCursor == 3)
- _verbHitArea = 236;
-
- if (ha->id == 98) {
- loadSprite(2, 0, 110, 0, 0, 0);
- waitForSync(34);
- } else if (ha->id == 108) {
- loadSprite(2, 0, 106, 0, 0, 0);
- waitForSync(34);
- } else if (ha->id == 109) {
- loadSprite(2, 0, 107, 0, 0, 0);
- waitForSync(34);
- } else if (ha->id == 115) {
- loadSprite(2, 0, 109, 0, 0, 0);
- waitForSync(34);
- } else if (ha->id == 116) {
- loadSprite(2, 0, 113, 0, 0, 0);
- waitForSync(34);
- } else if (ha->id == 117) {
- loadSprite(2, 0, 112, 0, 0, 0);
- waitForSync(34);
- } else if (ha->id == 118) {
- loadSprite(2, 0, 108, 0, 0, 0);
- waitForSync(34);
- } else if (ha->id == 119) {
- loadSprite(2, 0, 111, 0, 0, 0);
- waitForSync(34);
- }
- }
- if ((_verbHitArea != 0 || _hitAreaSubjectItem != ha->item_ptr && ha->flags & kBFBoxItem) &&
- ha->item_ptr) {
- if_1:;
- _hitAreaSubjectItem = ha->item_ptr;
- id = 0xFFFF;
- if (ha->flags & kBFTextBox) {
- if (getGameType() == GType_PP)
- id = _lastHitArea->id;
- else if (getGameType() == GType_FF && (ha->flags & kBFHyperBox))
- id = ha->data;
- else
- id = ha->flags / 256;
- }
- if (getGameType() == GType_PP)
- _variableArray[199] = id;
- else if (getGameType() == GType_WW)
- _variableArray[10] = id;
- else
- _variableArray[60] = id;
-
- _nameLocked = 2;
- displayName(ha);
- _nameLocked = 1;
-
- if (_verbHitArea != 0) {
- break;
- }
-
- if (getGameType() == GType_ELVIRA2)
- doMenuStrip(menuFor_e2(ha->item_ptr, id));
- else if (getGameType() == GType_WW)
- doMenuStrip(menuFor_ww(ha->item_ptr, id));
- } else {
- // else 1
- if (ha->verb == 0) {
- if (ha->item_ptr)
- goto if_1;
- } else {
- if (getGameType() == GType_WW && _mouseCursor != 0 && _mouseCursor < 4) {
- _hitAreaSubjectItem = ha->item_ptr;
- break;
- }
-
- _verbHitArea = ha->verb & 0xBFFF;
- if (ha->verb & 0x4000) {
- _hitAreaSubjectItem = ha->item_ptr;
- break;
- }
- if (_hitAreaSubjectItem != NULL)
- break;
-
- if (getGameType() == GType_WW) {
- if (ha->id == 109) {
- _mouseCursor = 2;
- _needHitAreaRecalc++;
- } else if (ha->id == 117) {
- _mouseCursor = 3;
- _needHitAreaRecalc++;
- }
- }
- }
- }
- }
- }
-
-out_of_here:
- if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
- clearMenuStrip();
-
- _nameLocked = 0;
- _needHitAreaRecalc++;
-}
-
-void AGOSEngine::hitarea_stuff_helper() {
- time_t cur_time;
-
- if (getGameType() == GType_SIMON2 || getGameType() == GType_FF ||
- getGameType() == GType_PP) {
- if (_variableArray[254] || _variableArray[249]) {
- hitarea_stuff_helper_2();
- }
- } else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW ||
- getGameType() == GType_SIMON1) {
- uint subr_id = (uint16)_variableArray[254];
- if (subr_id != 0) {
- Subroutine *sub = getSubroutineByID(subr_id);
- if (sub != NULL) {
- startSubroutineEx(sub);
- permitInput();
- }
- _variableArray[254] = 0;
- _runScriptReturn1 = false;
- }
- }
-
- time(&cur_time);
- if ((uint) cur_time != _lastTime) {
- _lastTime = cur_time;
- if (kickoffTimeEvents())
- permitInput();
- }
-}
-
-void AGOSEngine::hitarea_stuff_helper_2() {
- uint subr_id;
- Subroutine *sub;
-
- subr_id = (uint16)_variableArray[249];
- if (subr_id != 0) {
- sub = getSubroutineByID(subr_id);
- if (sub != NULL) {
- _variableArray[249] = 0;
- startSubroutineEx(sub);
- permitInput();
- }
- _variableArray[249] = 0;
- }
-
- subr_id = (uint16)_variableArray[254];
- if (subr_id != 0) {
- sub = getSubroutineByID(subr_id);
- if (sub != NULL) {
- _variableArray[254] = 0;
- startSubroutineEx(sub);
- permitInput();
- }
- _variableArray[254] = 0;
- }
-
- _runScriptReturn1 = false;
-}
-
-void AGOSEngine::permitInput() {
- if (!_mortalFlag) {
- _mortalFlag = true;
- showmessage_print_char(0);
- _curWindow = 0;
- if (_windowArray[0] != 0) {
- _textWindow = _windowArray[0];
- if (getGameType() == GType_FF || getGameType() == GType_PP)
- showmessage_helper_3(_textWindow->textColumn, _textWindow->width);
- else
- showmessage_helper_3(_textWindow->textLength, _textWindow->textMaxLength);
- }
- _mortalFlag = false;
- }
-}
-
-TextLocation *AGOSEngine::getTextLocation(uint a) {
- switch (a) {
- case 1:
- return &_textLocation1;
- case 2:
- return &_textLocation2;
- case 101:
- return &_textLocation3;
- case 102:
- return &_textLocation4;
- default:
- error("getTextLocation: Invalid text location %d", a);
- }
- return NULL;
-}
-
-void AGOSEngine::loadZone(uint zoneNum) {
- VgaPointersEntry *vpe;
-
- CHECK_BOUNDS(zoneNum, _vgaBufferPointers);
-
- vpe = _vgaBufferPointers + zoneNum;
- if (vpe->vgaFile1 != NULL)
- return;
-
- // Loading order is important
- // due to resource managment
-
- loadVGAVideoFile(zoneNum, 2);
- vpe->vgaFile2 = _block;
- vpe->vgaFile2End = _blockEnd;
-
- loadVGAVideoFile(zoneNum, 1);
- vpe->vgaFile1 = _block;
- vpe->vgaFile1End = _blockEnd;
-
- vpe->sfxFile = NULL;
- if (!(getFeatures() & GF_ZLIBCOMP)) {
- if (loadVGASoundFile(zoneNum, 3)) {
- vpe->sfxFile = _block;
- vpe->sfxFileEnd = _blockEnd;
- }
- }
-}
-
-void AGOSEngine::setZoneBuffers() {
- _zoneBuffers = (byte *)malloc(_vgaMemSize);
-
- _vgaMemPtr = _zoneBuffers;
- _vgaMemBase = _zoneBuffers;
- _vgaFrozenBase = _zoneBuffers;
- _vgaRealBase = _zoneBuffers;
- _vgaMemEnd = _zoneBuffers + _vgaMemSize;
-}
-
-byte *AGOSEngine::allocBlock(uint32 size) {
- for (;;) {
- _block = _vgaMemPtr;
- _blockEnd = _block + size;
-
- if (_blockEnd >= _vgaMemEnd) {
- _vgaMemPtr = _vgaMemBase;
- } else {
- _rejectBlock = false;
- checkNoOverWrite();
- if (_rejectBlock)
- continue;
- checkRunningAnims();
- if (_rejectBlock)
- continue;
- checkZonePtrs();
- _vgaMemPtr = _blockEnd;
- return _block;
- }
- }
-}
-
-void AGOSEngine::checkNoOverWrite() {
- VgaPointersEntry *vpe;
-
- if (_noOverWrite == 0xFFFF)
- return;
-
- vpe = &_vgaBufferPointers[_noOverWrite];
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block) {
- _rejectBlock = true;
- _vgaMemPtr = vpe->vgaFile1End;
- } else if (vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block) {
- _rejectBlock = true;
- _vgaMemPtr = vpe->vgaFile2End;
- } else if (vpe->sfxFile && vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) {
- _rejectBlock = true;
- _vgaMemPtr = vpe->sfxFileEnd;
- } else {
- _rejectBlock = false;
- }
- } else {
- if (_block <= vpe->vgaFile1 && _blockEnd >= vpe->vgaFile1 ||
- _vgaMemPtr <= vpe->vgaFile2 && _blockEnd >= vpe->vgaFile2) {
- _rejectBlock = true;
- _vgaMemPtr = vpe->vgaFile1 + 0x5000;
- } else {
- _rejectBlock = false;
- }
- }
-}
-
-void AGOSEngine::checkRunningAnims() {
- VgaSprite *vsp;
- if (getGameType() != GType_FF && getGameType() != GType_PP && (_lockWord & 0x20)) {
- return;
- }
-
- for (vsp = _vgaSprites; vsp->id; vsp++) {
- checkAnims(vsp->zoneNum);
- if (_rejectBlock == true)
- return;
- }
-}
-
-void AGOSEngine::checkAnims(uint a) {
- VgaPointersEntry *vpe;
-
- vpe = &_vgaBufferPointers[a];
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block) {
- _rejectBlock = true;
- _vgaMemPtr = vpe->vgaFile1End;
- } else if (vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block) {
- _rejectBlock = true;
- _vgaMemPtr = vpe->vgaFile2End;
- } else if (vpe->sfxFile && vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) {
- _rejectBlock = true;
- _vgaMemPtr = vpe->sfxFileEnd;
- } else {
- _rejectBlock = false;
- }
- } else {
- if (_block <= vpe->vgaFile1 && _blockEnd >= vpe->vgaFile1 ||
- _block <= vpe->vgaFile2 && _blockEnd >= vpe->vgaFile2) {
- _rejectBlock = true;
- _vgaMemPtr = vpe->vgaFile1 + 0x5000;
- } else {
- _rejectBlock = false;
- }
- }
-}
-
-void AGOSEngine::checkZonePtrs() {
- uint count = ARRAYSIZE(_vgaBufferPointers);
- VgaPointersEntry *vpe = _vgaBufferPointers;
- do {
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block ||
- vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block ||
- vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) {
- vpe->vgaFile1 = NULL;
- vpe->vgaFile1End = NULL;
- vpe->vgaFile2 = NULL;
- vpe->vgaFile2End = NULL;
- vpe->sfxFile = NULL;
- vpe->sfxFileEnd = NULL;
- }
- } else {
- if (_block <= vpe->vgaFile1 && _blockEnd >= vpe->vgaFile1 ||
- _block <= vpe->vgaFile2 && _blockEnd >= vpe->vgaFile2) {
- vpe->vgaFile1 = NULL;
- vpe->vgaFile2 = NULL;
- }
- }
- } while (++vpe, --count);
-}
-
-void AGOSEngine::set_video_mode_internal(uint16 mode, uint16 vga_res_id) {
- uint num, num_lines;
- VgaPointersEntry *vpe;
- byte *bb, *b;
- uint16 count, updateWindow;
- const byte *vc_ptr_org;
-
- _windowNum = updateWindow = mode;
- _lockWord |= 0x20;
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- vc27_resetSprite();
- }
-
- if (vga_res_id == 0) {
- if (getGameType() == GType_SIMON1) {
- _unkPalFlag = true;
- } else if (getGameType() == GType_SIMON2) {
- _useBackGround = true;
- _restoreWindow6 = true;
- }
- }
-
- _zoneNumber = num = vga_res_id / 100;
-
- for (;;) {
- vpe = &_vgaBufferPointers[num];
-
- _curVgaFile1 = vpe->vgaFile1;
- _curVgaFile2 = vpe->vgaFile2;
- _curSfxFile = vpe->sfxFile;
-
- if (vpe->vgaFile1 != NULL)
- break;
-
- loadZone(num);
- }
-
- // ensure flipping complete
-
- bb = _curVgaFile1;
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- b = bb + READ_LE_UINT16(bb + 2);
- count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageCount);
- b = bb + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageTable);
-
- while (count--) {
- if (READ_LE_UINT16(&((ImageHeader_Feeble *) b)->id) == vga_res_id)
- break;
- b += sizeof(ImageHeader_Feeble);
- }
- assert(READ_LE_UINT16(&((ImageHeader_Feeble *) b)->id) == vga_res_id);
-
- } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
- b = bb + READ_BE_UINT16(bb + 4);
- count = READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageCount);
- b = bb + READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageTable);
-
- while (count--) {
- if (READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == vga_res_id)
- break;
- b += sizeof(ImageHeader_Simon);
- }
- assert(READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == vga_res_id);
- } else {
- b = bb + READ_BE_UINT16(bb + 10);
- b += 20;
-
- count = READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageCount);
- b = bb + READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageTable);
-
- while (count--) {
- if (READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == vga_res_id)
- break;
- b += sizeof(ImageHeader_WW);
- }
- assert(READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == vga_res_id);
-
- clearWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_WW *) b)->color));
- }
-
- if (_startVgaScript) {
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- dump_vga_script(_curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble*)b)->scriptOffs), num, vga_res_id);
- } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
- dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon*)b)->scriptOffs), num, vga_res_id);
- } else {
- dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((ImageHeader_WW*)b)->scriptOffs), num, vga_res_id);
- }
- }
-
- if (getGameType() == GType_SIMON1) {
- if (vga_res_id == 16300) {
- clearBackFromTop(134);
- _usePaletteDelay = true;
- }
- } else if (getGameType() == GType_SIMON2 || getGameType() == GType_FF) {
- _scrollX = 0;
- _scrollY = 0;
- _scrollXMax = 0;
- _scrollYMax = 0;
- _scrollCount = 0;
- _scrollFlag = 0;
- _scrollHeight = 134;
- _variableArrayPtr = _variableArray;
- if (_variableArray[34] >= 0) {
- if (getGameType() == GType_FF)
- _variableArray[250] = 0;
- _variableArray[251] = 0;
- }
- }
-
- vc_ptr_org = _vcPtr;
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- _vcPtr = _curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble *) b)->scriptOffs);
- } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
- _vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon *) b)->scriptOffs);
- } else {
- _vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_WW *) b)->scriptOffs);
- }
-
- runVgaScript();
- _vcPtr = vc_ptr_org;
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- fillFrontFromBack(0, 0, _screenWidth, _screenHeight);
- fillBackGroundFromBack(_screenHeight);
- _syncFlag2 = 1;
- } else if (getGameType() == GType_SIMON2) {
- if (!_useBackGround) {
- num_lines = _windowNum == 4 ? 134 : 200;
- _boxStarHeight = num_lines;
- fillFrontFromBack(0, 0, _screenWidth, num_lines);
- fillBackGroundFromBack(num_lines);
- _syncFlag2 = 1;
- }
- _useBackGround = false;
- } else {
- // Allow one section of Simon the Sorcerer 1 introduction to be displayed
- // in lower half of screen
- if (_subroutine == 2923 || _subroutine == 2926)
- num_lines = 200;
- else
- num_lines = _windowNum == 4 ? 134 : 200;
-
- fillFrontFromBack(0, 0, _screenWidth, num_lines);
- fillBackGroundFromBack(num_lines);
-
- _syncFlag2 = 1;
- _timer5 = 0;
- }
-
- if (getGameType() == GType_ELVIRA1 && updateWindow == 3 && _bottomPalette != 0) {
- byte *dst = getBackBuf() + 42560;
- int size = 21440;
-
- while (size--) {
- *dst += 0x10;
- dst++;
- }
- }
-
- _lockWord &= ~0x20;
-
- if (getGameType() == GType_SIMON1) {
- if (_unkPalFlag) {
- _unkPalFlag = false;
- while (_fastFadeInFlag != 0) {
- delay(10);
- }
- }
- }
-}
-
-void AGOSEngine::waitForSync(uint a) {
- const uint maxCount = (getGameType() == GType_SIMON1) ? 500 : 1000;
-
- if (getGameType() == GType_SIMON1 && (getFeatures() & GF_TALKIE)) {
- if (a != 200) {
- uint16 tmp = _lastVgaWaitFor;
- _lastVgaWaitFor = 0;
- if (tmp == a)
- return;
- }
- }
-
- _vgaWaitFor = a;
- _syncCount = 0;
- _exitCutscene = false;
- _rightButtonDown = false;
-
- while (_vgaWaitFor != 0) {
- if (_rightButtonDown) {
- if (_vgaWaitFor == 200 && (getGameType() == GType_FF || !getBitFlag(14))) {
- skipSpeech();
- break;
- }
- }
- if (_exitCutscene) {
- if (getGameType() == GType_ELVIRA1) {
- if (_variableArray[105] == 0) {
- _variableArray[105] = 255;
- break;
- }
- } else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
- if (_vgaWaitFor == 51) {
- setBitFlag(244, 1);
- break;
- }
- } else {
- if (getBitFlag(9)) {
- endCutscene();
- break;
- }
- }
- }
- processSpecialKeys();
-
- if (_syncCount >= maxCount) {
- warning("waitForSync: wait timed out");
- break;
- }
-
- delay(1);
- }
-}
-
-void AGOSEngine::skipSpeech() {
- _sound->stopVoice();
- if (!getBitFlag(28)) {
- setBitFlag(14, true);
- if (getGameType() == GType_FF) {
- _variableArray[103] = 5;
- loadSprite(4, 2, 13, 0, 0, 0);
- waitForSync(213);
- stopAnimateSimon2(2, 1);
- } else if (getGameType() == GType_SIMON2) {
- _variableArray[100] = 5;
- loadSprite(4, 1, 30, 0, 0, 0);
- waitForSync(130);
- stopAnimateSimon2(2, 1);
- } else {
- _variableArray[100] = 15;
- loadSprite(4, 1, 130, 0, 0, 0);
- waitForSync(130);
- stopAnimateSimon1(1);
- }
- }
-}
-
-int AGOSEngine::wordMatch(Item *item, int16 a, int16 n) {
- if ((a == -1) && (n == item->noun))
- return 1;
- if ((a == item->adjective) && (n == item->noun))
- return 1 ;
-
- return 0;
-}
-
-Item *AGOSEngine::derefItem(uint item) {
- if (item >= _itemArraySize) {
- debug(1, "derefItem: invalid item %d", item);
- return 0;
- }
- return _itemArrayPtr[item];
-}
-
-Item *AGOSEngine::findInByClass(Item *i, int16 m) {
- i = derefItem(i->child);
-
- while (i) {
- if (i->classFlags & m) {
- //_findNextPtr = derefItem(i->next);
- return i;
- }
- if (m == 0) {
- //_findNextPtr = derefItem(i->next);
- return i;
- }
- i = derefItem(i->next);
- }
-
- return NULL;
-}
-
-Item *AGOSEngine::findMaster(int16 a, int16 n) {
- uint j;
-
- for (j = 1; j < _itemArraySize; j++) {
- Item *item = derefItem(j);
- if (wordMatch(item, a, n))
- return item;
- }
-
- return NULL;
-}
-
-Item *AGOSEngine::nextMaster(Item *i, int16 a, int16 n) {
- uint j;
- uint first = itemPtrToID(i) + 1;
-
- for (j = first; j < _itemArraySize; j++) {
- Item *item = derefItem(j);
- if (wordMatch(item, a, n))
- return item;
- }
-
- return NULL;
-}
-
-uint AGOSEngine::itemPtrToID(Item *id) {
- uint i;
- for (i = 0; i != _itemArraySize; i++)
- if (_itemArrayPtr[i] == id)
- return i;
- error("itemPtrToID: not found");
- return 0;
-}
-
-bool AGOSEngine::isSpriteLoaded(uint16 id, uint16 zoneNum) {
- VgaSprite *vsp = _vgaSprites;
- while (vsp->id) {
- if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) {
- if (vsp->id == id && vsp->zoneNum == zoneNum)
- return true;
- } else {
- if (vsp->id == id)
- return true;
- }
- vsp++;
- }
- return false;
-}
-
-bool AGOSEngine::processSpecialKeys() {
- switch (_keyPressed) {
- case 17: // Up
- if (getGameType() == GType_PP)
- _verbHitArea = 302;
- else if (getGameType() == GType_WW)
- _verbHitArea = 239;
- break;
- case 18: // Down
- if (getGameType() == GType_PP)
- _verbHitArea = 304;
- else if (getGameType() == GType_WW)
- _verbHitArea = 241;
- break;
- case 19: // Right
- if (getGameType() == GType_PP)
- _verbHitArea = 303;
- else if (getGameType() == GType_WW)
- _verbHitArea = 240;
- break;
- case 20: // Left
- if (getGameType() == GType_PP)
- _verbHitArea = 301;
- else if (getGameType() == GType_WW)
- _verbHitArea = 242;
- break;
- case 27: // escape
- _exitCutscene = true;
- break;
- case 59: // F1
- if (getGameType() == GType_SIMON1) {
- vcWriteVar(5, 40);
- } else {
- vcWriteVar(5, 50);
- }
- vcWriteVar(86, 0);
- break;
- case 60: // F2
- if (getGameType() == GType_SIMON1) {
- vcWriteVar(5, 60);
- } else {
- vcWriteVar(5, 75);
- }
- vcWriteVar(86, 1);
- break;
- case 61: // F3
- if (getGameType() == GType_SIMON1) {
- vcWriteVar(5, 100);
- } else {
- vcWriteVar(5, 125);
- }
- vcWriteVar(86, 2);
- break;
- case 63: // F5
- if (getGameType() == GType_SIMON2 || getGameType() == GType_FF)
- _exitCutscene = true;
- break;
- case 65: // F7
- if (getGameType() == GType_FF && getBitFlag(76))
- _variableArray[254] = 70;
- break;
- case 67: // F9
- if (getGameType() == GType_FF)
- setBitFlag(73, !getBitFlag(73));
- break;
- case 'p':
- pause();
- break;
- case 't':
- if (getGameType() == GType_FF || (getGameType() == GType_SIMON2 && (getFeatures() & GF_TALKIE)) ||
- ((getFeatures() & GF_TALKIE) && _language != Common::EN_ANY && _language != Common::DE_DEU)) {
- if (_speech)
- _subtitles ^= 1;
- }
- break;
- case 'v':
- if (getGameType() == GType_FF || (getGameType() == GType_SIMON2 && (getFeatures() & GF_TALKIE))) {
- if (_subtitles)
- _speech ^= 1;
- }
- case '+':
- midi.set_volume(midi.get_volume() + 16);
- break;
- case '-':
- midi.set_volume(midi.get_volume() - 16);
- break;
- case 'm':
- midi.pause(_musicPaused ^= 1);
- break;
- case 's':
- if (getGameId() == GID_SIMON1DOS)
- midi._enable_sfx ^= 1;
- else
- _sound->effectsPause(_effectsPaused ^= 1);
- break;
- case 'b':
- _sound->ambientPause(_ambientPaused ^= 1);
- break;
- case 'r':
- if (_debugMode)
- _startMainScript ^= 1;
- break;
- case 'o':
- if (_debugMode)
- _continousMainScript ^= 1;
- break;
- case 'a':
- if (_debugMode)
- _startVgaScript ^= 1;
- break;
- case 'g':
- if (_debugMode)
- _continousVgaScript ^= 1;
- break;
- case 'i':
- if (_debugMode)
- _drawImagesDebug ^= 1;
- break;
- case 'd':
- if (_debugMode)
- _dumpImages ^=1;
- break;
- }
-
- bool result = (_keyPressed != 0);
- _keyPressed = 0;
- return result;
-}
-
void AGOSEngine::pause() {
_keyPressed = 1;
_pause = 1;
@@ -2219,110 +809,6 @@ void AGOSEngine::pause() {
}
-void AGOSEngine::loadSprite(uint windowNum, uint zoneNum, uint vgaSpriteId, uint x, uint y, uint palette) {
- VgaSprite *vsp;
- VgaPointersEntry *vpe;
- byte *p, *pp;
- uint count;
-
- if (getGameType() == GType_SIMON1 && (getFeatures() & GF_TALKIE) && vgaSpriteId >= 400) {
- _lastVgaWaitFor = 0;
- }
-
- _lockWord |= 0x40;
-
- if (isSpriteLoaded(vgaSpriteId, zoneNum)) {
- _lockWord &= ~0x40;
- return;
- }
-
- vsp = _vgaSprites;
- while (vsp->id != 0)
- vsp++;
-
- vsp->windowNum = windowNum;
- vsp->priority = 0;
- vsp->flags = 0;
-
- vsp->y = y;
- vsp->x = x;
- vsp->image = 0;
- if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
- vsp->palette = 0;
- else
- vsp->palette = palette;
- vsp->id = vgaSpriteId;
-
- if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP)
- vsp->zoneNum = zoneNum;
- else
- vsp->zoneNum = zoneNum = vgaSpriteId / 100;
-
- for (;;) {
- vpe = &_vgaBufferPointers[zoneNum];
- _zoneNumber = zoneNum;
- _curVgaFile1 = vpe->vgaFile1;
- if (vpe->vgaFile1 != NULL)
- break;
- loadZone(zoneNum);
- }
-
- pp = _curVgaFile1;
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- p = pp + READ_LE_UINT16(pp + 2);
- count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationCount);
- p = pp + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationTable);
- } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
- p = pp + READ_BE_UINT16(pp + 4);
- count = READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationCount);
- p = pp + READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationTable);
- } else {
- p = pp + READ_BE_UINT16(pp + 10);
- p += 20;
-
- count = READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationCount);
- p = pp + READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationTable);
- }
-
- for (;;) {
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- if (READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->id) == vgaSpriteId) {
- if (_startVgaScript)
- dump_vga_script(pp + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), zoneNum, vgaSpriteId);
-
- addVgaEvent(_vgaBaseDelay, pp + READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->scriptOffs), vgaSpriteId, zoneNum);
- break;
- }
- p += sizeof(AnimationHeader_Feeble);
- } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
- if (READ_BE_UINT16(&((AnimationHeader_Simon *) p)->id) == vgaSpriteId) {
- if (_startVgaScript)
- dump_vga_script(pp + READ_BE_UINT16(&((AnimationHeader_Simon*)p)->scriptOffs), zoneNum, vgaSpriteId);
-
- addVgaEvent(_vgaBaseDelay, pp + READ_BE_UINT16(&((AnimationHeader_Simon *) p)->scriptOffs), vgaSpriteId, zoneNum);
- break;
- }
- p += sizeof(AnimationHeader_Simon);
- } else {
- if (READ_BE_UINT16(&((AnimationHeader_WW *) p)->id) == vgaSpriteId) {
- if (_startVgaScript)
- dump_vga_script(pp + READ_BE_UINT16(&((AnimationHeader_WW *)p)->scriptOffs), zoneNum, vgaSpriteId);
-
- addVgaEvent(_vgaBaseDelay, pp + READ_BE_UINT16(&((AnimationHeader_WW *) p)->scriptOffs), vgaSpriteId, zoneNum);
- break;
- }
- p += sizeof(AnimationHeader_WW);
- }
-
- if (!--count) {
- vsp->id = 0;
- break;
- }
- }
-
- _lockWord &= ~0x40;
-}
-
void AGOSEngine::playSpeech(uint speech_id, uint vgaSpriteId) {
if (getGameType() == GType_SIMON1) {
if (speech_id == 9999) {
@@ -2331,19 +817,19 @@ void AGOSEngine::playSpeech(uint speech_id, uint vgaSpriteId) {
if (!getBitFlag(14) && !getBitFlag(28)) {
setBitFlag(14, true);
_variableArray[100] = 15;
- loadSprite(4, 1, 130, 0, 0, 0);
+ animate(4, 1, 130, 0, 0, 0);
waitForSync(130);
}
_skipVgaWait = true;
} else {
if (_subtitles && _scriptVar2) {
- loadSprite(4, 2, 204, 0, 0, 0);
+ animate(4, 2, 204, 0, 0, 0);
waitForSync(204);
stopAnimateSimon1(204);
}
stopAnimateSimon1(vgaSpriteId + 201);
loadVoice(speech_id);
- loadSprite(4, 2, vgaSpriteId + 201, 0, 0, 0);
+ animate(4, 2, vgaSpriteId + 201, 0, 0, 0);
}
} else {
if (speech_id == 0xFFFF) {
@@ -2352,7 +838,7 @@ void AGOSEngine::playSpeech(uint speech_id, uint vgaSpriteId) {
if (!getBitFlag(14) && !getBitFlag(28)) {
setBitFlag(14, true);
_variableArray[100] = 5;
- loadSprite(4, 1, 30, 0, 0, 0);
+ animate(4, 1, 30, 0, 0, 0);
waitForSync(130);
}
_skipVgaWait = true;
@@ -2363,14 +849,37 @@ void AGOSEngine::playSpeech(uint speech_id, uint vgaSpriteId) {
}
if (_subtitles && _scriptVar2) {
- loadSprite(4, 2, 5, 0, 0, 0);
+ animate(4, 2, 5, 0, 0, 0);
waitForSync(205);
stopAnimateSimon2(2,5);
}
stopAnimateSimon2(2, vgaSpriteId + 2);
loadVoice(speech_id);
- loadSprite(4, 2, vgaSpriteId + 2, 0, 0, 0);
+ animate(4, 2, vgaSpriteId + 2, 0, 0, 0);
+ }
+ }
+}
+
+void AGOSEngine::skipSpeech() {
+ _sound->stopVoice();
+ if (!getBitFlag(28)) {
+ setBitFlag(14, true);
+ if (getGameType() == GType_FF) {
+ _variableArray[103] = 5;
+ animate(4, 2, 13, 0, 0, 0);
+ waitForSync(213);
+ stopAnimateSimon2(2, 1);
+ } else if (getGameType() == GType_SIMON2) {
+ _variableArray[100] = 5;
+ animate(4, 1, 30, 0, 0, 0);
+ waitForSync(130);
+ stopAnimateSimon2(2, 1);
+ } else {
+ _variableArray[100] = 15;
+ animate(4, 1, 130, 0, 0, 0);
+ waitForSync(130);
+ stopAnimateSimon1(1);
}
}
}
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index cfe744e53e..1f7688c76d 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -771,7 +771,7 @@ protected:
void loadZone(uint zoneNum);
- void loadSprite(uint windowNum, uint vga_res, uint vga_sprite_id, uint x, uint y, uint palette);
+ void animate(uint windowNum, uint zoneNum, uint vgaSpriteId, uint x, uint y, uint palette, bool setZone = true);
void playSpeech(uint speech_id, uint vga_sprite_id);
void skipSpeech();
diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp
new file mode 100644
index 0000000000..e3f81b4038
--- /dev/null
+++ b/engines/agos/gfx.cpp
@@ -0,0 +1,743 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "agos/agos.h"
+#include "agos/intern.h"
+#include "agos/vga.h"
+
+namespace AGOS {
+
+byte *vc10_depackColumn(VC10_state * vs) {
+ int8 a = vs->depack_cont;
+ const byte *src = vs->depack_src;
+ byte *dst = vs->depack_dest;
+ uint16 dh = vs->dh;
+ byte color;
+
+ if (a == -0x80)
+ a = *src++;
+
+ for (;;) {
+ if (a >= 0) {
+ color = *src++;
+ do {
+ *dst++ = color;
+ if (!--dh) {
+ if (--a < 0)
+ a = -0x80;
+ else
+ src--;
+ goto get_out;
+ }
+ } while (--a >= 0);
+ } else {
+ do {
+ *dst++ = *src++;
+ if (!--dh) {
+ if (++a == 0)
+ a = -0x80;
+ goto get_out;
+ }
+ } while (++a != 0);
+ }
+ a = *src++;
+ }
+
+get_out:;
+ vs->depack_src = src;
+ vs->depack_cont = a;
+ return vs->depack_dest + vs->y_skip;
+}
+
+void vc10_skip_cols(VC10_state *vs) {
+ while (vs->x_skip) {
+ vc10_depackColumn(vs);
+ vs->x_skip--;
+ }
+}
+
+void AGOSEngine::decodeColumn(byte *dst, const byte *src, int height) {
+ const uint pitch = _dxSurfacePitch;
+ int8 reps = (int8)0x80;
+ byte color;
+ byte *dstPtr = dst;
+ uint h = height, w = 8;
+
+ for (;;) {
+ reps = *src++;
+ if (reps >= 0) {
+ color = *src++;
+
+ do {
+ *dst = color;
+ dst += pitch;
+
+ /* reached bottom? */
+ if (--h == 0) {
+ /* reached right edge? */
+ if (--w == 0)
+ return;
+ dst = ++dstPtr;
+ h = height;
+ }
+ } while (--reps >= 0);
+ } else {
+
+ do {
+ *dst = *src++;
+ dst += pitch;
+
+ /* reached bottom? */
+ if (--h == 0) {
+ /* reached right edge? */
+ if (--w == 0)
+ return;
+ dst = ++dstPtr;
+ h = height;
+ }
+ } while (++reps != 0);
+ }
+ }
+}
+
+void AGOSEngine::decodeRow(byte *dst, const byte *src, int width) {
+ const uint pitch = _dxSurfacePitch;
+ int8 reps = (int8)0x80;
+ byte color;
+ byte *dstPtr = 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;
+ dstPtr += pitch;
+ dst = dstPtr;
+ w = width;
+ }
+ } while (--reps >= 0);
+ } else {
+
+ do {
+ *dst++ = *src++;
+
+ /* reached right edge? */
+ if (--w == 0) {
+ /* reached bottom? */
+ if (--h == 0)
+ return;
+ dstPtr += pitch;
+ dst = dstPtr;
+ w = width;
+ }
+ } while (++reps != 0);
+ }
+ }
+}
+
+bool AGOSEngine::drawImages_clip(VC10_state *state) {
+ const uint16 *vlut;
+ uint maxWidth, maxHeight;
+ int cur;
+
+ vlut = &_videoWindows[_windowNum * 4];
+
+ if (getGameType() != GType_FF && getGameType() != GType_PP) {
+ state->draw_width = state->width * 2;
+ }
+
+ cur = state->x;
+ if (cur < 0) {
+ do {
+ if (!--state->draw_width)
+ return 0;
+ state->x_skip++;
+ } while (++cur);
+ }
+ state->x = cur;
+
+ maxWidth = (getGameType() == GType_FF || getGameType() == GType_PP) ? _screenWidth : (vlut[2] * 2);
+ cur += state->draw_width - maxWidth;
+ if (cur > 0) {
+ do {
+ if (!--state->draw_width)
+ return 0;
+ } while (--cur);
+ }
+
+ cur = state->y;
+ if (cur < 0) {
+ do {
+ if (!--state->draw_height)
+ return 0;
+ state->y_skip++;
+ } while (++cur);
+ }
+ state->y = cur;
+
+ maxHeight = (getGameType() == GType_FF || getGameType() == GType_PP) ? _screenHeight : vlut[3];
+ cur += state->draw_height - maxHeight;
+ if (cur > 0) {
+ do {
+ if (!--state->draw_height)
+ return 0;
+ } while (--cur);
+ }
+
+ assert(state->draw_width != 0 && state->draw_height != 0);
+
+ if (getGameType() != GType_FF && getGameType() != GType_PP) {
+ state->draw_width *= 4;
+ }
+
+ return 1;
+}
+
+void AGOSEngine::drawImages_Feeble(VC10_state *state) {
+ if (state->flags & kDFCompressed) {
+ if (state->flags & kDFScaled) {
+ state->surf_addr = getScaleBuf();
+ state->surf_pitch = _dxSurfacePitch;
+
+ uint w, h;
+ byte *src, *dst, *dstPtr;
+
+ state->dl = state->width;
+ state->dh = state->height;
+
+ dstPtr = state->surf_addr;
+ w = 0;
+ do {
+ src = vc10_depackColumn(state);
+ dst = dstPtr;
+
+ h = 0;
+ do {
+ *dst = *src;
+ dst += _screenWidth;
+ src++;
+ } while (++h != state->draw_height);
+ dstPtr++;
+ } while (++w != state->draw_width);
+
+ if (_vgaCurSpritePriority % 10 != 9) {
+ _scaleX = state->x;
+ _scaleY = state->y;
+ _scaleWidth = state->width;
+ _scaleHeight = state->height;
+ } else {
+ scaleClip(state->height, state->width, state->y, state->x, state->y + _scrollY);
+ }
+ } else if (state->flags & kDFOverlayed) {
+ state->surf_addr = getScaleBuf();
+ state->surf_pitch = _dxSurfacePitch;
+ state->surf_addr += (state->x + _scrollX) + (state->y + _scrollY) * state->surf_pitch;
+
+ uint w, h;
+ byte *src, *dst, *dstPtr;
+
+ state->dl = state->width;
+ state->dh = state->height;
+
+ dstPtr = state->surf_addr;
+ w = 0;
+ do {
+ byte color;
+
+ src = vc10_depackColumn(state);
+ dst = dstPtr;
+
+ h = 0;
+ do {
+ color = *src;
+ if (color != 0)
+ *dst = color;
+ dst += _screenWidth;
+ src++;
+ } while (++h != state->draw_height);
+ dstPtr++;
+ } while (++w != state->draw_width);
+
+ if (_vgaCurSpritePriority % 10 == 9) {
+ scaleClip(_scaleHeight, _scaleWidth, _scaleY, _scaleX, _scaleY + _scrollY);
+ }
+ } else {
+ if (drawImages_clip(state) == 0)
+ return;
+
+ state->surf_addr += state->x + state->y * state->surf_pitch;
+
+ uint w, h;
+ byte *src, *dst, *dstPtr;
+
+ state->dl = state->width;
+ state->dh = state->height;
+
+ vc10_skip_cols(state);
+
+
+ if (state->flags & kDFMasked) {
+ if (getGameType() == GType_FF && !getBitFlag(81)) {
+ 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;
+ }
+
+ dstPtr = state->surf_addr;
+ w = 0;
+ do {
+ byte color;
+
+ src = vc10_depackColumn(state);
+ dst = dstPtr;
+
+ h = 0;
+ do {
+ color = *src;
+ if (color)
+ *dst = color;
+ dst += _screenWidth;
+ src++;
+ } while (++h != state->draw_height);
+ dstPtr++;
+ } while (++w != state->draw_width);
+ } else {
+ dstPtr = state->surf_addr;
+ w = 0;
+ do {
+ byte color;
+
+ src = vc10_depackColumn(state);
+ dst = dstPtr;
+
+ h = 0;
+ do {
+ color = *src;
+ if ((state->flags & kDFNonTrans) || color != 0)
+ *dst = color;
+ dst += _screenWidth;
+ src++;
+ } while (++h != state->draw_height);
+ dstPtr++;
+ } while (++w != state->draw_width);
+ }
+ }
+ } else {
+ if (drawImages_clip(state) == 0)
+ return;
+
+ state->surf_addr += state->x + state->y * state->surf_pitch;
+
+ const byte *src;
+ byte *dst;
+ uint count;
+
+ src = state->depack_src + state->width * state->y_skip;
+ dst = state->surf_addr;
+ do {
+ for (count = 0; count != state->draw_width; count++) {
+ byte color;
+ color = src[count + state->x_skip];
+ if (color) {
+ if ((state->flags & kDFShaded) && color == 220)
+ color = 244;
+
+ dst[count] = color;
+ }
+ }
+ dst += _screenWidth;
+ src += state->width;
+ } while (--state->draw_height);
+ }
+}
+
+void AGOSEngine::drawImages(VC10_state *state) {
+ const uint16 *vlut = &_videoWindows[_windowNum * 4];
+
+ if (drawImages_clip(state) == 0)
+ return;
+
+ uint xoffs, yoffs;
+ if (getGameType() == GType_ELVIRA1) {
+ //if (_windowNum != 2 && _windowNum != 3 && _windowNum != 6) {
+ // xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+ // yoffs = (vlut[1] - _videoWindows[17] + state->y);
+ //} else {
+ xoffs = (vlut[0] * 2 + state->x) * 8;
+ yoffs = vlut[1] + state->y;
+ //}
+ } else if (getGameType() == GType_ELVIRA2) {
+ //if (_windowNum == 4 || _windowNum >= 10) {
+ // xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+ // yoffs = (vlut[1] - _videoWindows[17] + state->y);
+ //} else {
+ xoffs = (vlut[0] * 2 + state->x) * 8;
+ yoffs = vlut[1] + state->y;
+ //}
+ } else if (getGameType() == GType_WW) {
+ //if (_windowNum == 4 || (_windowNum >= 10 && _windowNum < 28)) {
+ // xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+ // yoffs = (vlut[1] - _videoWindows[17] + state->y);
+ //} else {
+ xoffs = (vlut[0] * 2 + state->x) * 8;
+ yoffs = vlut[1] + state->y;
+ //}
+ } else if (getGameType() == GType_SIMON1 && (_subroutine == 2923 || _subroutine == 2926)) {
+ // Allow one section of Simon the Sorcerer 1 introduction to be displayed
+ // in lower half of screen
+ xoffs = state->x * 8;
+ yoffs = state->y;
+ } else {
+ xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+ yoffs = (vlut[1] - _videoWindows[17] + state->y);
+ }
+
+ state->surf2_addr += xoffs + yoffs * state->surf_pitch;
+ state->surf_addr += xoffs + yoffs * state->surf2_pitch;
+
+ if (state->flags & kDFMasked) {
+ byte *mask, *src, *dst;
+ byte h;
+ uint w;
+
+ state->x_skip *= 4;
+ state->dl = state->width;
+ state->dh = state->height;
+
+ vc10_skip_cols(state);
+
+ w = 0;
+ do {
+ mask = vc10_depackColumn(state); /* esi */
+ src = state->surf2_addr + w * 2; /* ebx */
+ dst = state->surf_addr + w * 2; /* edi */
+
+ h = state->draw_height;
+ if ((getGameType() == GType_SIMON1) && getBitFlag(88)) {
+ /* 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++;
+ dst += state->surf_pitch;
+ src += state->surf2_pitch;
+ } while (--h);
+ } else {
+ /* no transparency */
+ do {
+ if (mask[0] & 0xF0)
+ dst[0] = src[0];
+ if (mask[0] & 0x0F)
+ dst[1] = src[1];
+ mask++;
+ dst += state->surf_pitch;
+ src += state->surf2_pitch;
+ } while (--h);
+ }
+ } while (++w != state->draw_width);
+ } else if ((((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) &&
+ (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
+ getPlatform() != Common::kPlatformAmiga) {
+ const byte *src;
+ byte *dst;
+ uint h, i;
+
+ if (state->flags & kDFCompressed) {
+ byte *dstPtr = state->surf_addr;
+ src = state->depack_src;
+ /* AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE
+ * aaaaabbb bbcccccd ddddeeee efffffgg ggghhhhh
+ */
+
+ do {
+ uint count = state->draw_width / 4;
+
+ dst = dstPtr;
+ do {
+ uint32 bits = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | (src[3]);
+ byte color;
+
+ 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);
+ dstPtr += _screenWidth;
+ } while (--state->draw_height);
+ } else {
+ src = state->depack_src + (state->width * state->y_skip * 16) + (state->x_skip * 8);
+ dst = state->surf_addr;
+
+ state->draw_width *= 2;
+
+ 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);
+ }
+ } else {
+ if (getGameType() == GType_SIMON2 && state->flags & kDFUseFrontBuf && getBitFlag(171)) {
+ state->surf_addr = state->surf2_addr;
+ state->surf_pitch = state->surf2_pitch;
+ }
+
+ if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
+ state->palette = state->surf_addr[0] & 0xF0;
+
+ if (state->flags & kDFCompressed) {
+ uint w, h;
+ byte *src, *dst, *dstPtr;
+
+ state->x_skip *= 4; /* reached */
+
+ state->dl = state->width;
+ state->dh = state->height;
+
+ vc10_skip_cols(state);
+
+ dstPtr = state->surf_addr;
+ if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */
+ dstPtr += vcReadVar(252);
+ }
+ w = 0;
+ do {
+ byte color;
+
+ src = vc10_depackColumn(state);
+ dst = dstPtr;
+
+ 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);
+ dstPtr += 2;
+ } while (++w != state->draw_width);
+ } else {
+ const byte *src;
+ byte *dst;
+ uint count;
+
+ src = state->depack_src + (state->width * state->y_skip) * 8;
+ dst = state->surf_addr;
+ state->x_skip *= 4;
+
+ 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);
+ }
+ }
+}
+
+void AGOSEngine::horizontalScroll(VC10_state *state) {
+ 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;
+ if (_variableArrayPtr[34] < 0)
+ state->x = _variableArrayPtr[251];
+
+ _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) {
+ decodeColumn(dst, src + readUint32Wrapper(src), state->height);
+ dst += 8;
+ src += 4;
+ }
+}
+
+void AGOSEngine::verticalScroll(VC10_state *state) {
+ const byte *src;
+ byte *dst;
+ int h;
+
+ _scrollXMax = 0;
+ _scrollYMax = state->height - 480;
+ _scrollImage = state->depack_src;
+ _scrollWidth = state->width;
+ if (_variableArrayPtr[34] < 0)
+ state->y = _variableArrayPtr[250];
+
+ _scrollY = state->y;
+
+ vcWriteVar(250, _scrollY);
+
+ dst = getBackBuf();
+ src = state->depack_src + _scrollY / 2;
+
+ for (h = 0; h < _screenHeight; h += 8) {
+ decodeRow(dst, src + READ_LE_UINT32(src), state->width);
+ dst += 8 * state->width;
+ src += 4;
+ }
+}
+
+void AGOSEngine::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) {
+ 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;
+
+ debug(5, "Left %d Right %d Top %d Bottom %d", dstRect.left, dstRect.right, dstRect.top, dstRect.bottom);
+
+ // 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;
+
+ for (int dstY = 0; dstY < scaledH; dstY++) {
+ if (dstRect.top + dstY >= 0 && dstRect.top + dstY < _screenHeight) {
+ int srcY = (dstY * h) / scaledH;
+ byte *srcPtr = src + _dxSurfacePitch * srcY;
+ byte *dstPtr = dst + _dxSurfacePitch * dstY;
+ for (int dstX = 0; dstX < scaledW; dstX++) {
+ if (dstRect.left + dstX >= 0 && dstRect.left + dstX < _screenWidth) {
+ int srcX = (dstX * w) / scaledW;
+ if (srcPtr[srcX])
+ dstPtr[dstX] = srcPtr[srcX];
+ }
+ }
+ }
+ }
+}
+
+} // End of namespace AGOS
diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp
index c673ea00fb..225e1956db 100644
--- a/engines/agos/icons.cpp
+++ b/engines/agos/icons.cpp
@@ -557,7 +557,7 @@ void AGOSEngine::defineArrowBoxes(WindowBlock *window) {
ha->verb = 1;
stopAnimateSimon1(128);
- loadSprite(0, 1, 128, 0, 0, 14);
+ animate(0, 1, 128, 0, 0, 14);
} else if (getGameType() == GType_WW) {
ha->x = 255;
ha->y = 170;
diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp
new file mode 100644
index 0000000000..c20d963c92
--- /dev/null
+++ b/engines/agos/input.cpp
@@ -0,0 +1,518 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "common/file.h"
+
+#include "agos/intern.h"
+#include "agos/agos.h"
+#include "agos/vga.h"
+
+namespace AGOS {
+
+void AGOSEngine::setup_cond_c_helper() {
+ HitArea *last;
+ uint id;
+
+ _noRightClick = 1;
+
+ if (getGameType() == GType_WW)
+ clearMenuStrip();
+
+ if (getGameType() == GType_FF) {
+ int cursor = 5;
+ int animMax = 16;
+
+ if (getBitFlag(200)) {
+ cursor = 11;
+ animMax = 5;
+ } else if (getBitFlag(201)) {
+ cursor = 12;
+ animMax = 5;
+ } else if (getBitFlag(202)) {
+ cursor = 13;
+ animMax = 5;
+ } else if (getBitFlag(203)) {
+ cursor = 14;
+ animMax = 9;
+ } else if (getBitFlag(205)) {
+ cursor = 17;
+ animMax = 11;
+ } else if (getBitFlag(206)) {
+ cursor = 16;
+ animMax = 2;
+ } else if (getBitFlag(208)) {
+ cursor = 26;
+ animMax = 2;
+ } else if (getBitFlag(209)) {
+ cursor = 27;
+ animMax = 9;
+ } else if (getBitFlag(210)) {
+ cursor = 28;
+ animMax = 9;
+ }
+
+ _animatePointer = 0;
+ _mouseCursor = cursor;
+ _mouseAnimMax = animMax;
+ _mouseAnim = 1;
+ _needHitAreaRecalc++;
+ }
+
+ if (getGameType() == GType_SIMON2) {
+ _mouseCursor = 0;
+ if (_defaultVerb != 999) {
+ _mouseCursor = 9;
+ _needHitAreaRecalc++;
+ _defaultVerb = 0;
+ }
+ }
+
+ _lastHitArea = 0;
+ _hitAreaObjectItem = NULL;
+ _nameLocked = 0;
+
+ last = _lastNameOn;
+ clearName();
+ _lastNameOn = last;
+
+ for (;;) {
+ _lastHitArea = NULL;
+ _lastHitArea3 = 0;
+ _leftButtonDown = 0;
+
+ do {
+ if (_exitCutscene && getBitFlag(9)) {
+ endCutscene();
+ goto out_of_here;
+ }
+
+ if (getGameType() == GType_FF) {
+ if (_variableArray[254] == 63) {
+ hitarea_stuff_helper_2();
+ } else if (_variableArray[254] == 75) {
+ hitarea_stuff_helper_2();
+ _variableArray[60] = 9999;
+ goto out_of_here;
+ }
+ }
+
+ delay(100);
+ } while (_lastHitArea3 == (HitArea *) -1 || _lastHitArea3 == 0);
+
+ if (_lastHitArea == NULL) {
+ } else if (_lastHitArea->id == 0x7FFB) {
+ inventoryUp(_lastHitArea->window);
+ } else if (_lastHitArea->id == 0x7FFC) {
+ inventoryDown(_lastHitArea->window);
+ } else if (_lastHitArea->item_ptr != NULL) {
+ _hitAreaObjectItem = _lastHitArea->item_ptr;
+ id = 0xFFFF;
+ if (_lastHitArea->flags & kBFTextBox) {
+ if (getGameType() == GType_PP)
+ id = _lastHitArea->id;
+ else if (getGameType() == GType_FF && (_lastHitArea->flags & kBFHyperBox))
+ id = _lastHitArea->data;
+ else
+ id = _lastHitArea->flags / 256;
+ }
+ if (getGameType() == GType_PP)
+ _variableArray[199] = id;
+ else if (getGameType() == GType_WW)
+ _variableArray[10] = id;
+ else
+ _variableArray[60] = id;
+ break;
+ }
+ }
+
+out_of_here:
+ _lastHitArea3 = 0;
+ _lastHitArea = 0;
+ _lastNameOn = NULL;
+ _mouseCursor = 0;
+ _noRightClick = 0;
+}
+
+void AGOSEngine::waitForInput() {
+ HitArea *ha;
+ uint id;
+
+ _leftButtonDown = 0;
+ _lastHitArea = 0;
+ _verbHitArea = 0;
+ _hitAreaSubjectItem = NULL;
+ _hitAreaObjectItem = NULL;
+ _nameLocked = 0;
+
+ if (getGameType() == GType_WW) {
+ _mouseCursor = 0;
+ _needHitAreaRecalc++;
+ clearMenuStrip();
+ } else {
+ resetVerbs();
+ }
+
+startOver:
+ for (;;) {
+ _lastHitArea = NULL;
+ _lastHitArea3 = NULL;
+
+ for (;;) {
+ if (getGameType() != GType_FF && getGameType() != GType_PP && _keyPressed == 35)
+ displayBoxStars();
+ if (processSpecialKeys() != 0) {
+ goto out_of_here;
+ }
+ if (_lastHitArea3 == (HitArea *) -1)
+ goto startOver;
+ if (_lastHitArea3 != 0)
+ break;
+ hitarea_stuff_helper();
+ delay(100);
+ }
+
+ ha = _lastHitArea;
+
+ if (ha == NULL) {
+ } else if (ha->id == 0x7FFB) {
+ inventoryUp(ha->window);
+ } else if (ha->id == 0x7FFC) {
+ inventoryDown(ha->window);
+ } else if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
+ (ha->id >= 101 && ha->id < 113)) {
+ _verbHitArea = ha->verb;
+ setVerb(ha);
+ _defaultVerb = 0;
+ } else {
+ if (getGameType() == GType_WW) {
+ if (_mouseCursor == 3)
+ _verbHitArea = 236;
+
+ if (ha->id == 98) {
+ animate(2, 0, 110, 0, 0, 0);
+ waitForSync(34);
+ } else if (ha->id == 108) {
+ animate(2, 0, 106, 0, 0, 0);
+ waitForSync(34);
+ } else if (ha->id == 109) {
+ animate(2, 0, 107, 0, 0, 0);
+ waitForSync(34);
+ } else if (ha->id == 115) {
+ animate(2, 0, 109, 0, 0, 0);
+ waitForSync(34);
+ } else if (ha->id == 116) {
+ animate(2, 0, 113, 0, 0, 0);
+ waitForSync(34);
+ } else if (ha->id == 117) {
+ animate(2, 0, 112, 0, 0, 0);
+ waitForSync(34);
+ } else if (ha->id == 118) {
+ animate(2, 0, 108, 0, 0, 0);
+ waitForSync(34);
+ } else if (ha->id == 119) {
+ animate(2, 0, 111, 0, 0, 0);
+ waitForSync(34);
+ }
+ }
+ if ((_verbHitArea != 0 || _hitAreaSubjectItem != ha->item_ptr && ha->flags & kBFBoxItem) &&
+ ha->item_ptr) {
+ if_1:;
+ _hitAreaSubjectItem = ha->item_ptr;
+ id = 0xFFFF;
+ if (ha->flags & kBFTextBox) {
+ if (getGameType() == GType_PP)
+ id = _lastHitArea->id;
+ else if (getGameType() == GType_FF && (ha->flags & kBFHyperBox))
+ id = ha->data;
+ else
+ id = ha->flags / 256;
+ }
+ if (getGameType() == GType_PP)
+ _variableArray[199] = id;
+ else if (getGameType() == GType_WW)
+ _variableArray[10] = id;
+ else
+ _variableArray[60] = id;
+
+ _nameLocked = 2;
+ displayName(ha);
+ _nameLocked = 1;
+
+ if (_verbHitArea != 0) {
+ break;
+ }
+
+ if (getGameType() == GType_ELVIRA2)
+ doMenuStrip(menuFor_e2(ha->item_ptr, id));
+ else if (getGameType() == GType_WW)
+ doMenuStrip(menuFor_ww(ha->item_ptr, id));
+ } else {
+ // else 1
+ if (ha->verb == 0) {
+ if (ha->item_ptr)
+ goto if_1;
+ } else {
+ if (getGameType() == GType_WW && _mouseCursor != 0 && _mouseCursor < 4) {
+ _hitAreaSubjectItem = ha->item_ptr;
+ break;
+ }
+
+ _verbHitArea = ha->verb & 0xBFFF;
+ if (ha->verb & 0x4000) {
+ _hitAreaSubjectItem = ha->item_ptr;
+ break;
+ }
+ if (_hitAreaSubjectItem != NULL)
+ break;
+
+ if (getGameType() == GType_WW) {
+ if (ha->id == 109) {
+ _mouseCursor = 2;
+ _needHitAreaRecalc++;
+ } else if (ha->id == 117) {
+ _mouseCursor = 3;
+ _needHitAreaRecalc++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+out_of_here:
+ if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
+ clearMenuStrip();
+
+ _nameLocked = 0;
+ _needHitAreaRecalc++;
+}
+
+void AGOSEngine::hitarea_stuff_helper() {
+ time_t cur_time;
+
+ if (getGameType() == GType_SIMON2 || getGameType() == GType_FF ||
+ getGameType() == GType_PP) {
+ if (_variableArray[254] || _variableArray[249]) {
+ hitarea_stuff_helper_2();
+ }
+ } else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW ||
+ getGameType() == GType_SIMON1) {
+ uint subr_id = (uint16)_variableArray[254];
+ if (subr_id != 0) {
+ Subroutine *sub = getSubroutineByID(subr_id);
+ if (sub != NULL) {
+ startSubroutineEx(sub);
+ permitInput();
+ }
+ _variableArray[254] = 0;
+ _runScriptReturn1 = false;
+ }
+ }
+
+ time(&cur_time);
+ if ((uint) cur_time != _lastTime) {
+ _lastTime = cur_time;
+ if (kickoffTimeEvents())
+ permitInput();
+ }
+}
+
+void AGOSEngine::hitarea_stuff_helper_2() {
+ uint subr_id;
+ Subroutine *sub;
+
+ subr_id = (uint16)_variableArray[249];
+ if (subr_id != 0) {
+ sub = getSubroutineByID(subr_id);
+ if (sub != NULL) {
+ _variableArray[249] = 0;
+ startSubroutineEx(sub);
+ permitInput();
+ }
+ _variableArray[249] = 0;
+ }
+
+ subr_id = (uint16)_variableArray[254];
+ if (subr_id != 0) {
+ sub = getSubroutineByID(subr_id);
+ if (sub != NULL) {
+ _variableArray[254] = 0;
+ startSubroutineEx(sub);
+ permitInput();
+ }
+ _variableArray[254] = 0;
+ }
+
+ _runScriptReturn1 = false;
+}
+
+void AGOSEngine::permitInput() {
+ if (!_mortalFlag) {
+ _mortalFlag = true;
+ showmessage_print_char(0);
+ _curWindow = 0;
+ if (_windowArray[0] != 0) {
+ _textWindow = _windowArray[0];
+ if (getGameType() == GType_FF || getGameType() == GType_PP)
+ showmessage_helper_3(_textWindow->textColumn, _textWindow->width);
+ else
+ showmessage_helper_3(_textWindow->textLength, _textWindow->textMaxLength);
+ }
+ _mortalFlag = false;
+ }
+}
+
+bool AGOSEngine::processSpecialKeys() {
+ switch (_keyPressed) {
+ case 17: // Up
+ if (getGameType() == GType_PP)
+ _verbHitArea = 302;
+ else if (getGameType() == GType_WW)
+ _verbHitArea = 239;
+ break;
+ case 18: // Down
+ if (getGameType() == GType_PP)
+ _verbHitArea = 304;
+ else if (getGameType() == GType_WW)
+ _verbHitArea = 241;
+ break;
+ case 19: // Right
+ if (getGameType() == GType_PP)
+ _verbHitArea = 303;
+ else if (getGameType() == GType_WW)
+ _verbHitArea = 240;
+ break;
+ case 20: // Left
+ if (getGameType() == GType_PP)
+ _verbHitArea = 301;
+ else if (getGameType() == GType_WW)
+ _verbHitArea = 242;
+ break;
+ case 27: // escape
+ _exitCutscene = true;
+ break;
+ case 59: // F1
+ if (getGameType() == GType_SIMON1) {
+ vcWriteVar(5, 40);
+ } else {
+ vcWriteVar(5, 50);
+ }
+ vcWriteVar(86, 0);
+ break;
+ case 60: // F2
+ if (getGameType() == GType_SIMON1) {
+ vcWriteVar(5, 60);
+ } else {
+ vcWriteVar(5, 75);
+ }
+ vcWriteVar(86, 1);
+ break;
+ case 61: // F3
+ if (getGameType() == GType_SIMON1) {
+ vcWriteVar(5, 100);
+ } else {
+ vcWriteVar(5, 125);
+ }
+ vcWriteVar(86, 2);
+ break;
+ case 63: // F5
+ if (getGameType() == GType_SIMON2 || getGameType() == GType_FF)
+ _exitCutscene = true;
+ break;
+ case 65: // F7
+ if (getGameType() == GType_FF && getBitFlag(76))
+ _variableArray[254] = 70;
+ break;
+ case 67: // F9
+ if (getGameType() == GType_FF)
+ setBitFlag(73, !getBitFlag(73));
+ break;
+ case 'p':
+ pause();
+ break;
+ case 't':
+ if (getGameType() == GType_FF || (getGameType() == GType_SIMON2 && (getFeatures() & GF_TALKIE)) ||
+ ((getFeatures() & GF_TALKIE) && _language != Common::EN_ANY && _language != Common::DE_DEU)) {
+ if (_speech)
+ _subtitles ^= 1;
+ }
+ break;
+ case 'v':
+ if (getGameType() == GType_FF || (getGameType() == GType_SIMON2 && (getFeatures() & GF_TALKIE))) {
+ if (_subtitles)
+ _speech ^= 1;
+ }
+ case '+':
+ midi.set_volume(midi.get_volume() + 16);
+ break;
+ case '-':
+ midi.set_volume(midi.get_volume() - 16);
+ break;
+ case 'm':
+ midi.pause(_musicPaused ^= 1);
+ break;
+ case 's':
+ if (getGameId() == GID_SIMON1DOS)
+ midi._enable_sfx ^= 1;
+ else
+ _sound->effectsPause(_effectsPaused ^= 1);
+ break;
+ case 'b':
+ _sound->ambientPause(_ambientPaused ^= 1);
+ break;
+ case 'r':
+ if (_debugMode)
+ _startMainScript ^= 1;
+ break;
+ case 'o':
+ if (_debugMode)
+ _continousMainScript ^= 1;
+ break;
+ case 'a':
+ if (_debugMode)
+ _startVgaScript ^= 1;
+ break;
+ case 'g':
+ if (_debugMode)
+ _continousVgaScript ^= 1;
+ break;
+ case 'i':
+ if (_debugMode)
+ _drawImagesDebug ^= 1;
+ break;
+ case 'd':
+ if (_debugMode)
+ _dumpImages ^=1;
+ break;
+ }
+
+ bool result = (_keyPressed != 0);
+ _keyPressed = 0;
+ return result;
+}
+
+} // End of namespace AGOS
+
+
diff --git a/engines/agos/items.cpp b/engines/agos/items.cpp
new file mode 100644
index 0000000000..b0ebabe0ae
--- /dev/null
+++ b/engines/agos/items.cpp
@@ -0,0 +1,418 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "common/file.h"
+
+#include "agos/intern.h"
+#include "agos/agos.h"
+#include "agos/vga.h"
+
+namespace AGOS {
+
+Child *AGOSEngine::allocateChildBlock(Item *i, uint type, uint size) {
+ Child *child = (Child *)allocateItem(size);
+ child->next = i->children;
+ i->children = child;
+ child->type = type;
+ return child;
+}
+
+byte *AGOSEngine::allocateItem(uint size) {
+ byte *org = _itemHeapPtr;
+ size = (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
+
+ _itemHeapPtr += size;
+ _itemHeapCurPos += size;
+
+ if (_itemHeapCurPos > _itemHeapSize)
+ error("allocateItem: Itemheap overflow");
+
+ return org;
+}
+
+void AGOSEngine::allocItemHeap() {
+ _itemHeapSize = _itemMemSize;
+ _itemHeapCurPos = 0;
+ _itemHeapPtr = (byte *)calloc(_itemMemSize, 1);
+ if (!_itemHeapPtr)
+ error("Out Of Memory - Items");
+}
+
+uint AGOSEngine::itemGetIconNumber(Item *item) {
+ if (getGameType() == GType_ELVIRA1) {
+ return getUserFlag(item, 7);
+ } else {
+ SubObject *child = (SubObject *)findChildOfType(item, 2);
+ uint offs;
+
+ if (child == NULL || !(child->objectFlags & kOFIcon))
+ return 0;
+
+ offs = getOffsetOfChild2Param(child, 0x10);
+ return child->objectFlagValue[offs];
+ }
+}
+
+void AGOSEngine::setItemState(Item *item, int value) {
+ item->state = value;
+}
+
+void AGOSEngine::createPlayer() {
+ SubPlayer *p;
+
+ _currentPlayer = _itemArrayPtr[1];
+ _currentPlayer->adjective = -1;
+ _currentPlayer->noun = 10000;
+
+ p = (SubPlayer *)allocateChildBlock(_currentPlayer, 3, sizeof(SubPlayer));
+ if (p == NULL)
+ error("createPlayer: player create failure");
+
+ p->size = 0;
+ p->weight = 0;
+ p->strength = 6000;
+ //p->flag = xxx;
+ p->level = 1;
+ p->score = 0;
+
+ setUserFlag(_currentPlayer, 0, 0);
+}
+
+Child *AGOSEngine::findChildOfType(Item *i, uint type) {
+ Child *child = i->children;
+ for (; child; child = child->next)
+ if (child->type == type)
+ return child;
+ return NULL;
+}
+
+int AGOSEngine::getUserFlag(Item *item, int a) {
+ SubUserFlag *subUserFlag;
+
+ subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
+ if (subUserFlag == NULL)
+ return 0;
+
+ if (a < 0 || a > 7)
+ return 0;
+
+ return subUserFlag->userFlags[a];
+}
+
+void AGOSEngine::setUserFlag(Item *item, int a, int b) {
+ SubUserFlag *subUserFlag;
+
+ subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
+ if (subUserFlag == NULL) {
+ subUserFlag = (SubUserFlag *) allocateChildBlock(item, 9, sizeof(SubUserFlag));
+ }
+
+ if (a < 0 || a > 7)
+ return;
+
+ subUserFlag->userFlags[a] = b;
+}
+
+int AGOSEngine::getUserItem(Item *item, int n) {
+ SubUserFlag *subUserFlag;
+
+ subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
+ if (subUserFlag == NULL)
+ return 0;
+
+ if (n < 0 || n > 0)
+ return 0;
+
+ return subUserFlag->userItems[n];
+}
+
+void AGOSEngine::setUserItem(Item *item, int n, int m) {
+ SubUserFlag *subUserFlag;
+
+ subUserFlag = (SubUserFlag *) findChildOfType(item, 9);
+ if (subUserFlag == NULL) {
+ subUserFlag = (SubUserFlag *) allocateChildBlock(item, 9, sizeof(SubUserFlag));
+ }
+
+ if (n == 0)
+ subUserFlag->userItems[n] = m;
+}
+
+bool AGOSEngine::isRoom(Item *item) {
+ return findChildOfType(item, 1) != NULL;
+}
+
+bool AGOSEngine::isObject(Item *item) {
+ return findChildOfType(item, 2) != NULL;
+}
+
+bool AGOSEngine::isPlayer(Item *item) {
+ return findChildOfType(item, 3) != NULL;
+}
+
+uint AGOSEngine::getOffsetOfChild2Param(SubObject *child, uint prop) {
+ uint m = 1;
+ uint offset = 0;
+ while (m != prop) {
+ if (child->objectFlags & m)
+ offset++;
+ m *= 2;
+ }
+ return offset;
+}
+
+Item *AGOSEngine::me() {
+ if (_currentPlayer)
+ return _currentPlayer;
+ return _dummyItem1;
+}
+
+Item *AGOSEngine::actor() {
+ error("actor: is this code ever used?");
+ //if (_actorPlayer)
+ // return _actorPlayer;
+ return _dummyItem1;
+}
+
+Item *AGOSEngine::getNextItemPtr() {
+ int a = getNextWord();
+ switch (a) {
+ case -1:
+ return _subjectItem;
+ case -3:
+ return _objectItem;
+ case -5:
+ return me();
+ case -7:
+ return actor();
+ case -9:
+ return derefItem(me()->parent);
+ default:
+ return derefItem(a);
+ }
+}
+
+Item *AGOSEngine::getNextItemPtrStrange() {
+ int a = getNextWord();
+ switch (a) {
+ case -1:
+ return _subjectItem;
+ case -3:
+ return _objectItem;
+ case -5:
+ return _dummyItem2;
+ case -7:
+ return NULL;
+ case -9:
+ return _dummyItem3;
+ default:
+ return derefItem(a);
+ }
+}
+
+uint AGOSEngine::getNextItemID() {
+ int a = getNextWord();
+ switch (a) {
+ case -1:
+ return itemPtrToID(_subjectItem);
+ case -3:
+ return itemPtrToID(_objectItem);
+ case -5:
+ return getItem1ID();
+ case -7:
+ return 0;
+ case -9:
+ return me()->parent;
+ default:
+ return a;
+ }
+}
+
+void AGOSEngine::setItemParent(Item *item, Item *parent) {
+ Item *old_parent = derefItem(item->parent);
+
+ if (item == parent)
+ error("setItemParent: Trying to set item as its own parent");
+
+ // unlink it if it has a parent
+ if (old_parent)
+ unlinkItem(item);
+ itemChildrenChanged(old_parent);
+ linkItem(item, parent);
+ itemChildrenChanged(parent);
+}
+
+void AGOSEngine::itemChildrenChanged(Item *item) {
+ int i;
+ WindowBlock *window;
+
+ if (_noParentNotify)
+ return;
+
+ mouseOff();
+
+ for (i = 0; i != 8; i++) {
+ window = _windowArray[i];
+ if (window && window->iconPtr && window->iconPtr->itemRef == item) {
+ if (_fcsData1[i]) {
+ _fcsData2[i] = true;
+ } else {
+ _fcsData2[i] = false;
+ drawIconArray(i, item, window->iconPtr->line, window->iconPtr->classMask);
+ }
+ }
+ }
+
+ mouseOn();
+}
+
+void AGOSEngine::unlinkItem(Item *item) {
+ Item *first, *parent, *next;
+
+ // can't unlink item without parent
+ if (item->parent == 0)
+ return;
+
+ // get parent and first child of parent
+ parent = derefItem(item->parent);
+ first = derefItem(parent->child);
+
+ // the node to remove is first in the parent's children?
+ if (first == item) {
+ parent->child = item->next;
+ item->parent = 0;
+ item->next = 0;
+ return;
+ }
+
+ for (;;) {
+ if (!first)
+ error("unlinkItem: parent empty");
+ if (first->next == 0)
+ error("unlinkItem: parent does not contain child");
+
+ next = derefItem(first->next);
+ if (next == item) {
+ first->next = next->next;
+ item->parent = 0;
+ item->next = 0;
+ return;
+ }
+ first = next;
+ }
+}
+
+void AGOSEngine::linkItem(Item *item, Item *parent) {
+ uint id;
+ // Don't allow that an item that is already linked is relinked
+ if (item->parent)
+ return;
+
+ id = itemPtrToID(parent);
+ item->parent = id;
+
+ if (parent != 0) {
+ item->next = parent->child;
+ parent->child = itemPtrToID(item);
+ } else {
+ item->next = 0;
+ }
+}
+
+bool AGOSEngine::has_item_childflag_0x10(Item *item) {
+ SubObject *child = (SubObject *)findChildOfType(item, 2);
+ return child && (child->objectFlags & kOFIcon) != 0;
+}
+
+int AGOSEngine::wordMatch(Item *item, int16 a, int16 n) {
+ if ((a == -1) && (n == item->noun))
+ return 1;
+ if ((a == item->adjective) && (n == item->noun))
+ return 1 ;
+
+ return 0;
+}
+
+Item *AGOSEngine::derefItem(uint item) {
+ if (item >= _itemArraySize) {
+ debug(1, "derefItem: invalid item %d", item);
+ return 0;
+ }
+ return _itemArrayPtr[item];
+}
+
+Item *AGOSEngine::findInByClass(Item *i, int16 m) {
+ i = derefItem(i->child);
+
+ while (i) {
+ if (i->classFlags & m) {
+ //_findNextPtr = derefItem(i->next);
+ return i;
+ }
+ if (m == 0) {
+ //_findNextPtr = derefItem(i->next);
+ return i;
+ }
+ i = derefItem(i->next);
+ }
+
+ return NULL;
+}
+
+Item *AGOSEngine::findMaster(int16 a, int16 n) {
+ uint j;
+
+ for (j = 1; j < _itemArraySize; j++) {
+ Item *item = derefItem(j);
+ if (wordMatch(item, a, n))
+ return item;
+ }
+
+ return NULL;
+}
+
+Item *AGOSEngine::nextMaster(Item *i, int16 a, int16 n) {
+ uint j;
+ uint first = itemPtrToID(i) + 1;
+
+ for (j = first; j < _itemArraySize; j++) {
+ Item *item = derefItem(j);
+ if (wordMatch(item, a, n))
+ return item;
+ }
+
+ return NULL;
+}
+
+uint AGOSEngine::itemPtrToID(Item *id) {
+ uint i;
+ for (i = 0; i != _itemArraySize; i++)
+ if (_itemArrayPtr[i] == id)
+ return i;
+ error("itemPtrToID: not found");
+ return 0;
+}
+
+} // End of namespace AGOS
diff --git a/engines/agos/module.mk b/engines/agos/module.mk
index 15d5042e8a..3fc03a21e3 100644
--- a/engines/agos/module.mk
+++ b/engines/agos/module.mk
@@ -11,7 +11,10 @@ MODULE_OBJS := \
draw.o \
event.o \
game.o \
+ gfx.o \
icons.o \
+ input.o \
+ items.o \
menus.o \
midi.o \
midiparser_s1d.o \
@@ -33,7 +36,11 @@ MODULE_OBJS := \
subroutine.o \
verb.o \
vga.o \
- window.o
+ vga_s1.o \
+ vga_s2.o \
+ vga_ff.o \
+ window.o \
+ zones.o
# This module can be built as a plugin
ifdef BUILD_PLUGINS
diff --git a/engines/agos/script.cpp b/engines/agos/script.cpp
index 3a03444a74..5ebdadfdbe 100644
--- a/engines/agos/script.cpp
+++ b/engines/agos/script.cpp
@@ -1333,6 +1333,87 @@ void AGOSEngine::o_unfreezeZones() {
// -----------------------------------------------------------------------
+byte AGOSEngine::getByte() {
+ return *_codePtr++;
+}
+
+int AGOSEngine::getNextWord() {
+ int16 a = (int16)READ_BE_UINT16(_codePtr);
+ _codePtr += 2;
+ return a;
+}
+
+uint AGOSEngine::getNextStringID() {
+ return (uint16)getNextWord();
+}
+
+uint AGOSEngine::getVarOrByte() {
+ if (getGameType() == GType_ELVIRA1) {
+ return getVarOrWord();
+ } else {
+ uint a = *_codePtr++;
+ if (a != 255)
+ return a;
+ return readVariable(*_codePtr++);
+ }
+}
+
+uint AGOSEngine::getVarOrWord() {
+ uint a = READ_BE_UINT16(_codePtr);
+ _codePtr += 2;
+ if (getGameType() == GType_PP) {
+ if (a >= 60000 && a < 62048) {
+ return readVariable(a - 60000);
+ }
+ } else {
+ if (a >= 30000 && a < 30512) {
+ return readVariable(a - 30000);
+ }
+ }
+ return a;
+}
+
+uint AGOSEngine::getVarWrapper() {
+ if (getGameType() == GType_ELVIRA1 || getGameType() == GType_PP)
+ return getVarOrWord();
+ else
+ return getVarOrByte();
+}
+
+uint AGOSEngine::getNextVarContents() {
+ return (uint16)readVariable(getVarWrapper());
+}
+
+uint AGOSEngine::readVariable(uint variable) {
+ if (variable >= _numVars)
+ error("readVariable: Variable %d out of range", variable);
+
+ if (getGameType() == GType_PP) {
+ return (uint16)_variableArray[variable];
+ } else if (getGameType() == GType_FF) {
+ if (getBitFlag(83))
+ return (uint16)_variableArray2[variable];
+ else
+ return (uint16)_variableArray[variable];
+ } else {
+ return _variableArray[variable];
+ }
+}
+
+void AGOSEngine::writeNextVarContents(uint16 contents) {
+ writeVariable(getVarWrapper(), contents);
+}
+
+void AGOSEngine::writeVariable(uint variable, uint16 contents) {
+ if (variable >= _numVars)
+ error("writeVariable: Variable %d out of range", variable);
+
+ if (getGameType() == GType_FF && getBitFlag(83))
+ _variableArray2[variable] = contents;
+ else
+ _variableArray[variable] = contents;
+}
+
int AGOSEngine::runScript() {
int opcode;
bool flag;
diff --git a/engines/agos/script_ff.cpp b/engines/agos/script_ff.cpp
index 39f684fbd0..0c6d7ac00c 100644
--- a/engines/agos/script_ff.cpp
+++ b/engines/agos/script_ff.cpp
@@ -46,7 +46,6 @@ void AGOSEngine::setupFeebleOpcodes(OpcodeProc *op) {
op[122] = &AGOSEngine::o3_oracleTextDown;
op[123] = &AGOSEngine::o3_oracleTextUp;
op[124] = &AGOSEngine::o3_ifTime;
- op[127] = NULL;
op[131] = &AGOSEngine::o3_setTime;
op[132] = &AGOSEngine::o3_saveUserGame;
op[133] = &AGOSEngine::o3_loadUserGame;
diff --git a/engines/agos/script_pp.cpp b/engines/agos/script_pp.cpp
index 70792a36b2..698cbdfd51 100644
--- a/engines/agos/script_pp.cpp
+++ b/engines/agos/script_pp.cpp
@@ -49,7 +49,6 @@ void AGOSEngine::setupPuzzleOpcodes(OpcodeProc *op) {
op[122] = &AGOSEngine::o3_oracleTextDown;
op[123] = &AGOSEngine::o3_oracleTextUp;
op[124] = &AGOSEngine::o3_ifTime;
- op[127] = NULL;
op[131] = &AGOSEngine::o3_setTime;
op[132] = &AGOSEngine::o4_saveUserGame;
op[133] = &AGOSEngine::o4_loadUserGame;
diff --git a/engines/agos/script_s1.cpp b/engines/agos/script_s1.cpp
index 61a4614971..61017586f8 100644
--- a/engines/agos/script_s1.cpp
+++ b/engines/agos/script_s1.cpp
@@ -79,14 +79,19 @@ void AGOSEngine::o1_rescan() {
void AGOSEngine::o1_animate() {
// 98: start vga
- uint vga_res, vgaSpriteId, windowNum, x, y, palette;
- vgaSpriteId = getVarOrWord();
- vga_res = vgaSpriteId / 100;
- windowNum = getVarOrByte();
- x = getVarOrWord();
- y = getVarOrWord();
- palette = getVarOrWord();
- loadSprite(windowNum, vga_res, vgaSpriteId, x, y, palette);
+ uint vgaSpriteId = getVarOrWord();
+ uint windowNum = getVarOrByte();
+ uint x = getVarOrWord();
+ uint y = getVarOrWord();
+ uint palette = getVarOrWord();
+
+ if (getGameType() == GType_SIMON1 && (getFeatures() & GF_TALKIE) && vgaSpriteId >= 400) {
+ _lastVgaWaitFor = 0;
+ }
+
+ _lockWord |= 0x40;
+ animate(windowNum, vgaSpriteId / 100, vgaSpriteId, x, y, palette);
+ _lockWord &= ~0x40;
}
void AGOSEngine::o1_stopAnimate() {
diff --git a/engines/agos/script_s2.cpp b/engines/agos/script_s2.cpp
index 186795885d..04fdca01b1 100644
--- a/engines/agos/script_s2.cpp
+++ b/engines/agos/script_s2.cpp
@@ -87,13 +87,16 @@ void AGOSEngine::o2_rescan() {
void AGOSEngine::o2_animate() {
// 98: start vga
- uint vga_res = getVarOrWord();
+ uint zoneNum = getVarOrWord();
uint vgaSpriteId = getVarOrWord();
uint windowNum = getVarOrByte();
uint x = getVarOrWord();
uint y = getVarOrWord();
uint palette = getVarOrWord();
- loadSprite(windowNum, vga_res, vgaSpriteId, x, y, palette);
+
+ _lockWord |= 0x40;
+ animate(windowNum, zoneNum, vgaSpriteId, x, y, palette);
+ _lockWord &= ~0x40;
}
void AGOSEngine::o2_stopAnimate() {
diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp
index 5eb6f1f510..9ab4d4c07a 100644
--- a/engines/agos/string.cpp
+++ b/engines/agos/string.cpp
@@ -54,6 +54,22 @@ const byte *AGOSEngine::getLocalStringByID(uint stringId) {
return _localStringtable[stringId - _stringIdLocalMin];
}
+TextLocation *AGOSEngine::getTextLocation(uint a) {
+ switch (a) {
+ case 1:
+ return &_textLocation1;
+ case 2:
+ return &_textLocation2;
+ case 101:
+ return &_textLocation3;
+ case 102:
+ return &_textLocation4;
+ default:
+ error("getTextLocation: Invalid text location %d", a);
+ }
+ return NULL;
+}
+
void AGOSEngine::allocateStringTable(int num) {
_stringTabPtr = (byte **)calloc(num, sizeof(byte *));
_stringTabPos = 0;
@@ -319,7 +335,7 @@ void AGOSEngine::printInteractText(uint16 num, const char *string) {
stopAnimateSimon2(2, num + 6);
renderString(num, 0, w, height, convertedString);
- loadSprite(4, 2, num + 6, x, _interactY, 12);
+ animate(4, 2, num + 6, x, _interactY, 12);
_interactY += height;
}
@@ -463,9 +479,9 @@ void AGOSEngine::printScreenText(uint vgaSpriteId, uint color, const char *strin
}
if (getGameType() == GType_SIMON1)
- loadSprite(b, 2, vgaSpriteId + 199, x, y, 12);
+ animate(b, 2, vgaSpriteId + 199, x, y, 12);
else
- loadSprite(b, 2, vgaSpriteId, x, y, 12);
+ animate(b, 2, vgaSpriteId, x, y, 12);
}
// String code for boxes in Waxworks
@@ -665,7 +681,7 @@ void AGOSEngine::printBox() {
stopAnimateSimon1(105);
BoxSize = getBoxSize();
_variableArray[53] = BoxSize;
- loadSprite(3, 1, 100, 0, 0, 0);
+ animate(3, 1, 100, 0, 0, 0);
changeWindow(5);
switch (BoxSize) {
diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp
index 3cd05a5b31..517f33b3fb 100644
--- a/engines/agos/subroutine.cpp
+++ b/engines/agos/subroutine.cpp
@@ -241,6 +241,26 @@ byte *AGOSEngine::allocateTable(uint size) {
return org;
}
+void AGOSEngine::allocTablesHeap() {
+ _tablesHeapSize = _tableMemSize;
+ _tablesHeapCurPos = 0;
+ _tablesHeapPtr = (byte *)calloc(_tableMemSize, 1);
+ if (!_tablesHeapPtr)
+ error("Out Of Memory - Tables");
+}
+
+void AGOSEngine::endCutscene() {
+ Subroutine *sub;
+
+ _sound->stopVoice();
+
+ sub = getSubroutineByID(170);
+ if (sub != NULL)
+ startSubroutineEx(sub);
+
+ _runScriptReturn1 = true;
+}
+
File *AGOSEngine::openTablesFile(const char *filename) {
if (getFeatures() & GF_OLD_BUNDLE)
return openTablesFile_simon1(filename);
diff --git a/engines/agos/verb.cpp b/engines/agos/verb.cpp
index 87c9164dcb..28231bd2f6 100644
--- a/engines/agos/verb.cpp
+++ b/engines/agos/verb.cpp
@@ -606,14 +606,14 @@ void AGOSEngine::checkUp(WindowBlock *window) {
if (!isBoxDead(j + 201)) {
uint index = getWindowNum(window);
drawIconArray(index, window->iconPtr->itemRef, 0, window->iconPtr->classMask);
- loadSprite(4, 9, k + 34, 0, 0, 0);
+ animate(4, 9, k + 34, 0, 0, 0);
}
}
if ((_variableArray[31] - _variableArray[30]) == 76) {
k = ((_variableArray[31] / 52) % 3);
j = k * 6;
if (isBoxDead(j + 201)) {
- loadSprite(4, 9, k + 31, 0, 0, 0);
+ animate(4, 9, k + 31, 0, 0, 0);
undefineBox(j + 201);
undefineBox(j + 202);
undefineBox(j + 203);
@@ -633,14 +633,14 @@ void AGOSEngine::checkDown(WindowBlock *window) {
uint index = getWindowNum(window);
drawIconArray(index, window->iconPtr->itemRef, 0, window->iconPtr->classMask);
k = ((_variableArray[31] / 52) % 3);
- loadSprite(4, 9, k + 25, 0, 0, 0);
+ animate(4, 9, k + 25, 0, 0, 0);
_variableArray[31] += 52;
}
if (((_variableArray[31] - _variableArray[30]) == 40) && (_variableArray[30] > 52)) {
k = (((_variableArray[31] / 52) + 1) % 3);
j = k * 6;
if (isBoxDead(j + 201)) {
- loadSprite(4, 9, k + 28, 0, 0, 0);
+ animate(4, 9, k + 28, 0, 0, 0);
undefineBox(j + 201);
undefineBox(j + 202);
undefineBox(j + 203);
@@ -655,7 +655,7 @@ void AGOSEngine::inventoryUp(WindowBlock *window) {
if (getGameType() == GType_FF) {
_marks = 0;
checkUp(window);
- loadSprite(4, 9, 21, 0 ,0, 0);
+ animate(4, 9, 21, 0 ,0, 0);
while (1) {
if (_currentBoxNumber != 0x7FFB || !getBitFlag(89))
break;
@@ -682,7 +682,7 @@ void AGOSEngine::inventoryDown(WindowBlock *window) {
if (getGameType() == GType_FF) {
_marks = 0;
checkDown(window);
- loadSprite(4, 9, 23, 0, 0, 0);
+ animate(4, 9, 23, 0, 0, 0);
while (1) {
if (_currentBoxNumber != 0x7FFC || !getBitFlag(89))
break;
diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp
index e9dce8f07c..c612e6c1ce 100644
--- a/engines/agos/vga.cpp
+++ b/engines/agos/vga.cpp
@@ -159,57 +159,6 @@ void AGOSEngine::setupWaxworksVideoOpcodes(VgaOpcodeProc *op) {
op[63] = &AGOSEngine::vc63_fastFadeIn;
}
-void AGOSEngine::setupSimon1VideoOpcodes(VgaOpcodeProc *op) {
- setupCommonVideoOpcodes(op);
-
- op[11] = &AGOSEngine::vc11_clearPathFinder;
- op[17] = &AGOSEngine::vc17_setPathfinderItem;
- op[22] = &AGOSEngine::vc22_setPaletteNew;
- op[32] = &AGOSEngine::vc32_copyVar;
- op[37] = &AGOSEngine::vc37_addToSpriteY;
- op[48] = &AGOSEngine::vc48_setPathFinder;
- op[59] = &AGOSEngine::vc59_skipIfSpeechEnded;
- op[60] = &AGOSEngine::vc60_stopAnimation;
- op[61] = &AGOSEngine::vc61_setMaskImage;
- op[62] = &AGOSEngine::vc62_fastFadeOut;
- op[63] = &AGOSEngine::vc63_fastFadeIn;
-}
-
-void AGOSEngine::setupSimon2VideoOpcodes(VgaOpcodeProc *op) {
- setupSimon1VideoOpcodes(op);
-
- op[56] = &AGOSEngine::vc56_delayLong;
- op[58] = &AGOSEngine::vc58_changePriority;
- op[59] = &AGOSEngine::vc59_stopAnimations;
- op[64] = &AGOSEngine::vc64_skipIfSpeechEnded;
- op[65] = &AGOSEngine::vc65_slowFadeIn;
- op[66] = &AGOSEngine::vc66_skipIfNotEqual;
- op[67] = &AGOSEngine::vc67_skipIfGE;
- op[68] = &AGOSEngine::vc68_skipIfLE;
- op[69] = &AGOSEngine::vc69_playTrack;
- op[70] = &AGOSEngine::vc70_queueMusic;
- op[71] = &AGOSEngine::vc71_checkMusicQueue;
- op[72] = &AGOSEngine::vc72_play_track_2;
- op[73] = &AGOSEngine::vc73_setMark;
- op[74] = &AGOSEngine::vc74_clearMark;
-}
-
-void AGOSEngine::setupFeebleVideoOpcodes(VgaOpcodeProc *op) {
- setupSimon2VideoOpcodes(op);
-
- op[53] = &AGOSEngine::vc53_panSFX;
- 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;
-}
-
void AGOSEngine::setupVgaOpcodes() {
memset(_vga_opcode_table, 0, sizeof(_vga_opcode_table));
@@ -295,6 +244,21 @@ bool AGOSEngine::itemIsParentOf(uint16 a, uint16 b) {
return derefItem(item_a->parent) == item_b;
}
+bool AGOSEngine::isSpriteLoaded(uint16 id, uint16 zoneNum) {
+ VgaSprite *vsp = _vgaSprites;
+ while (vsp->id) {
+ if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) {
+ if (vsp->id == id && vsp->zoneNum == zoneNum)
+ return true;
+ } else {
+ if (vsp->id == id)
+ return true;
+ }
+ vsp++;
+ }
+ return false;
+}
+
bool AGOSEngine::vc_maybe_skip_proc_1(uint16 a, int16 b) {
Item *item;
@@ -543,10 +507,6 @@ void AGOSEngine::vc2_call() {
void AGOSEngine::vc3_loadSprite() {
uint16 windowNum, zoneNum, palette, x, y, vgaSpriteId;
- uint16 count, res;
- VgaSprite *vsp;
- VgaPointersEntry *vpe;
- byte *p, *pp;
byte *old_file_1;
if (getGameType() == GType_PP && getBitFlag(100)) {
@@ -568,115 +528,7 @@ void AGOSEngine::vc3_loadSprite() {
y = vcReadNextWord(); /* 6 */
palette = vcReadNextWord(); /* 8 */
- if (isSpriteLoaded(vgaSpriteId, zoneNum))
- return;
-
- vsp = _vgaSprites;
- while (vsp->id)
- vsp++;
-
- if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
- vsp->palette = 0;
- else
- vsp->palette = palette;
- vsp->windowNum = windowNum;
- vsp->priority = 0;
- vsp->flags = 0;
- vsp->image = 0;
- vsp->x = x;
- vsp->y = y;
- vsp->id = vgaSpriteId;
- vsp->zoneNum = res = zoneNum;
-
- old_file_1 = _curVgaFile1;
- for (;;) {
- vpe = &_vgaBufferPointers[res];
- _curVgaFile1 = vpe->vgaFile1;
-
- if (vpe->vgaFile1 != NULL)
- break;
- if (_zoneNumber != res)
- _noOverWrite = _zoneNumber;
-
- loadZone(res);
- _noOverWrite = 0xFFFF;
- }
-
- pp = _curVgaFile1;
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- p = pp + READ_LE_UINT16(pp + 2);
- count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationCount);
- p = pp + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationTable);
-
- while (count--) {
- if (READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->id) == vgaSpriteId)
- break;
- p += sizeof(AnimationHeader_Feeble);
- }
- assert(READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->id) == vgaSpriteId);
- } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
- p = pp + READ_BE_UINT16(pp + 4);
- count = READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationCount);
- p = pp + READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationTable);
-
- while (count--) {
- if (READ_BE_UINT16(&((AnimationHeader_Simon *) p)->id) == vgaSpriteId)
- break;
- p += sizeof(AnimationHeader_Simon);
- }
- assert(READ_BE_UINT16(&((AnimationHeader_Simon *) p)->id) == vgaSpriteId);
- } else {
- p = pp + READ_BE_UINT16(pp + 10);
- p += 20;
-
- count = READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationCount);
- p = pp + READ_BE_UINT16(&((VgaFileHeader2_Common *) 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);
- }
-
-#ifdef DUMP_FILE_NR
- {
- static bool dumped = false;
- if (res == DUMP_FILE_NR && !dumped) {
- dumped = true;
- dump_vga_file(_curVgaFile1);
- }
- }
-#endif
-
-#ifdef DUMP_BITMAPS_FILE_NR
- {
- static bool dumped = false;
- if (res == DUMP_BITMAPS_FILE_NR && !dumped) {
- dumped = true;
- dump_vga_bitmaps(_curVgaFile2, _curVgaFile1, res);
- }
- }
-#endif
-
- if (_startVgaScript) {
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- dump_vga_script(_curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), res, vgaSpriteId);
- } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
- dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon*)p)->scriptOffs), res, vgaSpriteId);
- } else {
- dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW*)p)->scriptOffs), res, vgaSpriteId);
- }
- }
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->scriptOffs), vgaSpriteId, res);
- } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
- addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon *) p)->scriptOffs), vgaSpriteId, res);
- } else {
- addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW *) p)->scriptOffs), vgaSpriteId, res);
- }
+ animate(windowNum, zoneNum, vgaSpriteId, x, y, palette, false);
_curVgaFile1 = old_file_1;
}
@@ -723,55 +575,6 @@ void AGOSEngine::vc9_skip_if_unk3_is() {
vcSkipNextInstruction();
}
-byte *vc10_depackColumn(VC10_state * vs) {
- int8 a = vs->depack_cont;
- const byte *src = vs->depack_src;
- byte *dst = vs->depack_dest;
- uint16 dh = vs->dh;
- byte color;
-
- if (a == -0x80)
- a = *src++;
-
- for (;;) {
- if (a >= 0) {
- color = *src++;
- do {
- *dst++ = color;
- if (!--dh) {
- if (--a < 0)
- a = -0x80;
- else
- src--;
- goto get_out;
- }
- } while (--a >= 0);
- } else {
- do {
- *dst++ = *src++;
- if (!--dh) {
- if (++a == 0)
- a = -0x80;
- goto get_out;
- }
- } while (++a != 0);
- }
- a = *src++;
- }
-
-get_out:;
- vs->depack_src = src;
- vs->depack_cont = a;
- return vs->depack_dest + vs->y_skip;
-}
-
-void vc10_skip_cols(VC10_state *vs) {
- while (vs->x_skip) {
- vc10_depackColumn(vs);
- vs->x_skip--;
- }
-}
-
byte *AGOSEngine::vc10_uncompressFlip(const byte *src, uint w, uint h) {
w *= 8;
@@ -862,94 +665,6 @@ byte *AGOSEngine::vc10_flip(const byte *src, uint w, uint h) {
return _videoBuf1;
}
-void AGOSEngine::decodeColumn(byte *dst, const byte *src, int height) {
- const uint pitch = _dxSurfacePitch;
- int8 reps = (int8)0x80;
- byte color;
- byte *dstPtr = dst;
- uint h = height, w = 8;
-
- for (;;) {
- reps = *src++;
- if (reps >= 0) {
- color = *src++;
-
- do {
- *dst = color;
- dst += pitch;
-
- /* reached bottom? */
- if (--h == 0) {
- /* reached right edge? */
- if (--w == 0)
- return;
- dst = ++dstPtr;
- h = height;
- }
- } while (--reps >= 0);
- } else {
-
- do {
- *dst = *src++;
- dst += pitch;
-
- /* reached bottom? */
- if (--h == 0) {
- /* reached right edge? */
- if (--w == 0)
- return;
- dst = ++dstPtr;
- h = height;
- }
- } while (++reps != 0);
- }
- }
-}
-
-void AGOSEngine::decodeRow(byte *dst, const byte *src, int width) {
- const uint pitch = _dxSurfacePitch;
- int8 reps = (int8)0x80;
- byte color;
- byte *dstPtr = 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;
- dstPtr += pitch;
- dst = dstPtr;
- w = width;
- }
- } while (--reps >= 0);
- } else {
-
- do {
- *dst++ = *src++;
-
- /* reached right edge? */
- if (--w == 0) {
- /* reached bottom? */
- if (--h == 0)
- return;
- dstPtr += pitch;
- dst = dstPtr;
- w = width;
- }
- } while (++reps != 0);
- }
- }
-}
-
void AGOSEngine::vc10_draw() {
byte *p2;
uint width, height;
@@ -1062,589 +777,11 @@ void AGOSEngine::vc10_draw() {
}
}
-bool AGOSEngine::drawImages_clip(VC10_state *state) {
- const uint16 *vlut;
- uint maxWidth, maxHeight;
- int cur;
-
- vlut = &_videoWindows[_windowNum * 4];
-
- if (getGameType() != GType_FF && getGameType() != GType_PP) {
- state->draw_width = state->width * 2;
- }
-
- cur = state->x;
- if (cur < 0) {
- do {
- if (!--state->draw_width)
- return 0;
- state->x_skip++;
- } while (++cur);
- }
- state->x = cur;
-
- maxWidth = (getGameType() == GType_FF || getGameType() == GType_PP) ? _screenWidth : (vlut[2] * 2);
- cur += state->draw_width - maxWidth;
- if (cur > 0) {
- do {
- if (!--state->draw_width)
- return 0;
- } while (--cur);
- }
-
- cur = state->y;
- if (cur < 0) {
- do {
- if (!--state->draw_height)
- return 0;
- state->y_skip++;
- } while (++cur);
- }
- state->y = cur;
-
- maxHeight = (getGameType() == GType_FF || getGameType() == GType_PP) ? _screenHeight : vlut[3];
- cur += state->draw_height - maxHeight;
- if (cur > 0) {
- do {
- if (!--state->draw_height)
- return 0;
- } while (--cur);
- }
-
- assert(state->draw_width != 0 && state->draw_height != 0);
-
- if (getGameType() != GType_FF && getGameType() != GType_PP) {
- state->draw_width *= 4;
- }
-
- return 1;
-}
-
-void AGOSEngine::drawImages_Feeble(VC10_state *state) {
- if (state->flags & kDFCompressed) {
- if (state->flags & kDFScaled) {
- state->surf_addr = getScaleBuf();
- state->surf_pitch = _dxSurfacePitch;
-
- uint w, h;
- byte *src, *dst, *dstPtr;
-
- state->dl = state->width;
- state->dh = state->height;
-
- dstPtr = state->surf_addr;
- w = 0;
- do {
- src = vc10_depackColumn(state);
- dst = dstPtr;
-
- h = 0;
- do {
- *dst = *src;
- dst += _screenWidth;
- src++;
- } while (++h != state->draw_height);
- dstPtr++;
- } while (++w != state->draw_width);
-
- if (_vgaCurSpritePriority % 10 != 9) {
- _scaleX = state->x;
- _scaleY = state->y;
- _scaleWidth = state->width;
- _scaleHeight = state->height;
- } else {
- scaleClip(state->height, state->width, state->y, state->x, state->y + _scrollY);
- }
- } else if (state->flags & kDFOverlayed) {
- state->surf_addr = getScaleBuf();
- state->surf_pitch = _dxSurfacePitch;
- state->surf_addr += (state->x + _scrollX) + (state->y + _scrollY) * state->surf_pitch;
-
- uint w, h;
- byte *src, *dst, *dstPtr;
-
- state->dl = state->width;
- state->dh = state->height;
-
- dstPtr = state->surf_addr;
- w = 0;
- do {
- byte color;
-
- src = vc10_depackColumn(state);
- dst = dstPtr;
-
- h = 0;
- do {
- color = *src;
- if (color != 0)
- *dst = color;
- dst += _screenWidth;
- src++;
- } while (++h != state->draw_height);
- dstPtr++;
- } while (++w != state->draw_width);
-
- if (_vgaCurSpritePriority % 10 == 9) {
- scaleClip(_scaleHeight, _scaleWidth, _scaleY, _scaleX, _scaleY + _scrollY);
- }
- } else {
- if (drawImages_clip(state) == 0)
- return;
-
- state->surf_addr += state->x + state->y * state->surf_pitch;
-
- uint w, h;
- byte *src, *dst, *dstPtr;
-
- state->dl = state->width;
- state->dh = state->height;
-
- vc10_skip_cols(state);
-
-
- if (state->flags & kDFMasked) {
- if (getGameType() == GType_FF && !getBitFlag(81)) {
- 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;
- }
-
- dstPtr = state->surf_addr;
- w = 0;
- do {
- byte color;
-
- src = vc10_depackColumn(state);
- dst = dstPtr;
-
- h = 0;
- do {
- color = *src;
- if (color)
- *dst = color;
- dst += _screenWidth;
- src++;
- } while (++h != state->draw_height);
- dstPtr++;
- } while (++w != state->draw_width);
- } else {
- dstPtr = state->surf_addr;
- w = 0;
- do {
- byte color;
-
- src = vc10_depackColumn(state);
- dst = dstPtr;
-
- h = 0;
- do {
- color = *src;
- if ((state->flags & kDFNonTrans) || color != 0)
- *dst = color;
- dst += _screenWidth;
- src++;
- } while (++h != state->draw_height);
- dstPtr++;
- } while (++w != state->draw_width);
- }
- }
- } else {
- if (drawImages_clip(state) == 0)
- return;
-
- state->surf_addr += state->x + state->y * state->surf_pitch;
-
- const byte *src;
- byte *dst;
- uint count;
-
- src = state->depack_src + state->width * state->y_skip;
- dst = state->surf_addr;
- do {
- for (count = 0; count != state->draw_width; count++) {
- byte color;
- color = src[count + state->x_skip];
- if (color) {
- if ((state->flags & kDFShaded) && color == 220)
- color = 244;
-
- dst[count] = color;
- }
- }
- dst += _screenWidth;
- src += state->width;
- } while (--state->draw_height);
- }
-}
-
-void AGOSEngine::drawImages(VC10_state *state) {
- const uint16 *vlut = &_videoWindows[_windowNum * 4];
-
- if (drawImages_clip(state) == 0)
- return;
-
- uint xoffs, yoffs;
- if (getGameType() == GType_ELVIRA1) {
- //if (_windowNum != 2 && _windowNum != 3 && _windowNum != 6) {
- // xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
- // yoffs = (vlut[1] - _videoWindows[17] + state->y);
- //} else {
- xoffs = (vlut[0] * 2 + state->x) * 8;
- yoffs = vlut[1] + state->y;
- //}
- } else if (getGameType() == GType_ELVIRA2) {
- //if (_windowNum == 4 || _windowNum >= 10) {
- // xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
- // yoffs = (vlut[1] - _videoWindows[17] + state->y);
- //} else {
- xoffs = (vlut[0] * 2 + state->x) * 8;
- yoffs = vlut[1] + state->y;
- //}
- } else if (getGameType() == GType_WW) {
- //if (_windowNum == 4 || (_windowNum >= 10 && _windowNum < 28)) {
- // xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
- // yoffs = (vlut[1] - _videoWindows[17] + state->y);
- //} else {
- xoffs = (vlut[0] * 2 + state->x) * 8;
- yoffs = vlut[1] + state->y;
- //}
- } else if (getGameType() == GType_SIMON1 && (_subroutine == 2923 || _subroutine == 2926)) {
- // Allow one section of Simon the Sorcerer 1 introduction to be displayed
- // in lower half of screen
- xoffs = state->x * 8;
- yoffs = state->y;
- } else {
- xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
- yoffs = (vlut[1] - _videoWindows[17] + state->y);
- }
-
- state->surf2_addr += xoffs + yoffs * state->surf_pitch;
- state->surf_addr += xoffs + yoffs * state->surf2_pitch;
-
- if (state->flags & kDFMasked) {
- byte *mask, *src, *dst;
- byte h;
- uint w;
-
- state->x_skip *= 4;
- state->dl = state->width;
- state->dh = state->height;
-
- vc10_skip_cols(state);
-
- w = 0;
- do {
- mask = vc10_depackColumn(state); /* esi */
- src = state->surf2_addr + w * 2; /* ebx */
- dst = state->surf_addr + w * 2; /* edi */
-
- h = state->draw_height;
- if ((getGameType() == GType_SIMON1) && getBitFlag(88)) {
- /* 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++;
- dst += state->surf_pitch;
- src += state->surf2_pitch;
- } while (--h);
- } else {
- /* no transparency */
- do {
- if (mask[0] & 0xF0)
- dst[0] = src[0];
- if (mask[0] & 0x0F)
- dst[1] = src[1];
- mask++;
- dst += state->surf_pitch;
- src += state->surf2_pitch;
- } while (--h);
- }
- } while (++w != state->draw_width);
- } else if ((((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) &&
- (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
- getPlatform() != Common::kPlatformAmiga) {
- const byte *src;
- byte *dst;
- uint h, i;
-
- if (state->flags & kDFCompressed) {
- byte *dstPtr = state->surf_addr;
- src = state->depack_src;
- /* AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE
- * aaaaabbb bbcccccd ddddeeee efffffgg ggghhhhh
- */
-
- do {
- uint count = state->draw_width / 4;
-
- dst = dstPtr;
- do {
- uint32 bits = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | (src[3]);
- byte color;
-
- 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);
- dstPtr += _screenWidth;
- } while (--state->draw_height);
- } else {
- src = state->depack_src + (state->width * state->y_skip * 16) + (state->x_skip * 8);
- dst = state->surf_addr;
-
- state->draw_width *= 2;
-
- 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);
- }
- } else {
- if (getGameType() == GType_SIMON2 && state->flags & kDFUseFrontBuf && getBitFlag(171)) {
- state->surf_addr = state->surf2_addr;
- state->surf_pitch = state->surf2_pitch;
- }
-
- if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
- state->palette = state->surf_addr[0] & 0xF0;
-
- if (state->flags & kDFCompressed) {
- uint w, h;
- byte *src, *dst, *dstPtr;
-
- state->x_skip *= 4; /* reached */
-
- state->dl = state->width;
- state->dh = state->height;
-
- vc10_skip_cols(state);
-
- dstPtr = state->surf_addr;
- if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */
- dstPtr += vcReadVar(252);
- }
- w = 0;
- do {
- byte color;
-
- src = vc10_depackColumn(state);
- dst = dstPtr;
-
- 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);
- dstPtr += 2;
- } while (++w != state->draw_width);
- } else {
- const byte *src;
- byte *dst;
- uint count;
-
- src = state->depack_src + (state->width * state->y_skip) * 8;
- dst = state->surf_addr;
- state->x_skip *= 4;
-
- 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);
- }
- }
-}
-
-void AGOSEngine::horizontalScroll(VC10_state *state) {
- 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;
- if (_variableArrayPtr[34] < 0)
- state->x = _variableArrayPtr[251];
-
- _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) {
- decodeColumn(dst, src + readUint32Wrapper(src), state->height);
- dst += 8;
- src += 4;
- }
-}
-
-void AGOSEngine::verticalScroll(VC10_state *state) {
- const byte *src;
- byte *dst;
- int h;
-
- _scrollXMax = 0;
- _scrollYMax = state->height - 480;
- _scrollImage = state->depack_src;
- _scrollWidth = state->width;
- if (_variableArrayPtr[34] < 0)
- state->y = _variableArrayPtr[250];
-
- _scrollY = state->y;
-
- vcWriteVar(250, _scrollY);
-
- dst = getBackBuf();
- src = state->depack_src + _scrollY / 2;
-
- for (h = 0; h < _screenHeight; h += 8) {
- decodeRow(dst, src + READ_LE_UINT32(src), state->width);
- dst += 8 * state->width;
- src += 4;
- }
-}
-
-void AGOSEngine::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) {
- 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;
-
- debug(5, "Left %d Right %d Top %d Bottom %d", dstRect.left, dstRect.right, dstRect.top, dstRect.bottom);
-
- // 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;
-
- for (int dstY = 0; dstY < scaledH; dstY++) {
- if (dstRect.top + dstY >= 0 && dstRect.top + dstY < _screenHeight) {
- int srcY = (dstY * h) / scaledH;
- byte *srcPtr = src + _dxSurfacePitch * srcY;
- byte *dstPtr = dst + _dxSurfacePitch * dstY;
- for (int dstX = 0; dstX < scaledW; dstX++) {
- if (dstRect.left + dstX >= 0 && dstRect.left + dstX < _screenWidth) {
- int srcX = (dstX * w) / scaledW;
- if (srcPtr[srcX])
- dstPtr[dstX] = srcPtr[srcX];
- }
- }
- }
- }
-}
-
void AGOSEngine::vc11() {
uint a = vcReadNextWord();
debug(0, "vc11: stub (%d)", a);
}
-void AGOSEngine::vc11_clearPathFinder() {
- memset(&_pathFindArray, 0, sizeof(_pathFindArray));
-}
-
void AGOSEngine::vc12_delay() {
VgaSprite *vsp = findCurSprite();
uint16 num;
@@ -1744,16 +881,6 @@ void AGOSEngine::vc17_waitEnd() {
_vcPtr = (byte *)&_vc_get_out_of_code;
}
-void AGOSEngine::vc17_setPathfinderItem() {
- uint16 a = vcReadNextWord();
- _pathFindArray[a - 1] = (const uint16 *)_vcPtr;
-
- int end = (getGameType() == GType_FF || getGameType() == GType_PP) ? 9999 : 999;
- while (readUint16Wrapper(_vcPtr) != end)
- _vcPtr += 4;
- _vcPtr += 2;
-}
-
void AGOSEngine::vc18_jump() {
int16 offs = vcReadNextWord();
_vcPtr += offs;
@@ -1861,42 +988,6 @@ void AGOSEngine::vc22_setPaletteOld() {
_vgaSpriteChanged++;
}
-void AGOSEngine::vc22_setPaletteNew() {
- byte *offs, *palptr, *src;
- uint16 a = 0, b, num, palSize;
-
- a = vcReadNextWord();
- b = vcReadNextWord();
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- num = 256;
- palSize = 768;
-
- palptr = _displayPalette;
- } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
- num = a == 0 ? 32 : 16;
- palSize = 96;
-
- palptr = &_displayPalette[(a * 64)];
- }
-
- offs = _curVgaFile1 + 6;
- src = offs + b * palSize;
-
- do {
- palptr[0] = src[0] * 4;
- palptr[1] = src[1] * 4;
- palptr[2] = src[2] * 4;
- palptr[3] = 0;
-
- palptr += 4;
- src += 3;
- } while (--num);
-
- _paletteFlag = 2;
- _vgaSpriteChanged++;
-}
-
void AGOSEngine::vc23_setPriority() {
VgaSprite *vsp = findCurSprite(), *vus2;
uint16 pri = vcReadNextWord();
@@ -2083,11 +1174,6 @@ void AGOSEngine::vc32_saveScreen() {
debug(0, "vc32_saveScreen: stub");
}
-void AGOSEngine::vc32_copyVar() {
- uint16 a = vcReadVar(vcReadNextWord());
- vcWriteVar(vcReadNextWord(), a);
-}
-
void AGOSEngine::vc33_setMouseOn() {
if (_mouseHideCount != 0) {
_mouseHideCount = 1;
@@ -2154,12 +1240,6 @@ void AGOSEngine::vc37_pokePalette() {
debug(0, "vc37_pokePalette: stub (%d, %d)", a, b);
}
-void AGOSEngine::vc37_addToSpriteY() {
- VgaSprite *vsp = findCurSprite();
- vsp->y += vcReadVar(vcReadNextWord());
- _vgaSpriteChanged++;
-}
-
void AGOSEngine::vc38_skipIfVarZero() {
uint16 var;
if (getGameType() == GType_PP)
@@ -2275,12 +1355,6 @@ void AGOSEngine::vc45_setWindowPalette() {
}
}
-void AGOSEngine::vc45_setSpriteX() {
- VgaSprite *vsp = findCurSprite();
- vsp->x = vcReadVar(vcReadNextWord());
- _vgaSpriteChanged++;
-}
-
void AGOSEngine::setPaletteSlot(uint srcOffs, uint dstOffs) {
byte *offs, *palptr, *src;
uint16 num;
@@ -2309,100 +1383,16 @@ void AGOSEngine::vc46_setPaletteSlot1() {
setPaletteSlot(srcOffs, 1);
}
-void AGOSEngine::vc46_setSpriteY() {
- VgaSprite *vsp = findCurSprite();
- vsp->y = vcReadVar(vcReadNextWord());
- _vgaSpriteChanged++;
-}
-
void AGOSEngine::vc47_setPaletteSlot2() {
uint srcOffs = vcReadNextWord();
setPaletteSlot(srcOffs, 2);
}
-void AGOSEngine::vc47_addToVar() {
- uint16 var = vcReadNextWord();
- vcWriteVar(var, vcReadVar(var) + vcReadVar(vcReadNextWord()));
-}
-
void AGOSEngine::vc48_setPaletteSlot3() {
uint srcOffs = vcReadNextWord();
setPaletteSlot(srcOffs, 3);
}
-void AGOSEngine::vc48_setPathFinder() {
- uint16 a = (uint16)_variableArrayPtr[12];
- const uint16 *p = _pathFindArray[a - 1];
-
- if (getGameType() == GType_FF || getGameType() == GType_PP) {
- 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;
- } else {
- uint b = (uint16)_variableArray[13];
- p += b * 2 + 1;
- int c = _variableArray[14];
-
- int step;
- int y1, y2;
- int16 *vp;
-
- step = 2;
- if (c < 0) {
- c = -c;
- step = -2;
- }
-
- 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);
- }
-}
-
void AGOSEngine::setBitFlag(uint bit, bool value) {
uint16 *bits = &_bitArray[bit / 16];
*bits = (*bits & ~(1 << (bit & 15))) | (value << (bit & 15));
@@ -2469,29 +1459,6 @@ void AGOSEngine::vc53_dissolveIn() {
debug(0, "vc53_dissolveIn: stub (%d, %d)", num, speed);
}
-void AGOSEngine::vc53_panSFX() {
- VgaSprite *vsp = findCurSprite();
- int pan;
-
- uint16 sound = vcReadNextWord();
- int16 xoffs = vcReadNextWord();
- int16 vol = vcReadNextWord();
-
- 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);
-}
-
void AGOSEngine::vc54_dissolveOut() {
// TODO
uint num = vcReadNextWord();
@@ -2539,13 +1506,6 @@ void AGOSEngine::vc56_fullScreen() {
_system->setPalette(palette, 0, 256);
}
-void AGOSEngine::vc56_delayLong() {
- uint16 num = vcReadVarOrWord() * _frameRate;
-
- addVgaEvent(num + _vgaBaseDelay, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum);
- _vcPtr = (byte *)&_vc_get_out_of_code;
-}
-
void AGOSEngine::vc57_blackPalette() {
uint8 palette[1024];
memset(palette, 0, sizeof(palette));
@@ -2557,46 +1517,11 @@ void AGOSEngine::vc58_checkCodeWheel() {
debug(0, "vc58_checkCodeWheel: stub");
}
-void AGOSEngine::vc58_changePriority() {
- uint16 sprite = _vgaCurSpriteId;
- uint16 file = _vgaCurZoneNum;
- const byte *vcPtrOrg;
- uint16 tmp;
-
- _vgaCurZoneNum = vcReadNextWord();
- _vgaCurSpriteId = vcReadNextWord();
-
- tmp = to16Wrapper(vcReadNextWord());
-
- vcPtrOrg = _vcPtr;
- _vcPtr = (byte *)&tmp;
- vc23_setPriority();
-
- _vcPtr = vcPtrOrg;
- _vgaCurSpriteId = sprite;
- _vgaCurZoneNum = file;
-}
-
void AGOSEngine::vc59_skipIfNotEGA() {
// Skip if not EGA
vcSkipNextInstruction();
}
-void AGOSEngine::vc59_skipIfSpeechEnded() {
- if (!_sound->isVoiceActive())
- vcSkipNextInstruction();
-}
-
-void AGOSEngine::vc59_stopAnimations() {
- uint16 file = vcReadNextWord();
- uint16 start = vcReadNextWord();
- uint16 end = vcReadNextWord() + 1;
-
- do {
- vc_kill_sprite(file, start);
- } while (++start != end);
-}
-
void AGOSEngine::vc_kill_sprite(uint file, uint sprite) {
uint16 old_sprite_id, old_cur_file_id;
VgaSleepStruct *vfs;
@@ -2718,17 +1643,6 @@ void AGOSEngine::vc61() {
}
}
-void AGOSEngine::vc61_setMaskImage() {
- VgaSprite *vsp = findCurSprite();
-
- vsp->image = vcReadVarOrWord();
- vsp->x += vcReadNextWord();
- vsp->y += vcReadNextWord();
- vsp->flags = kDFMasked | kDFUseFrontBuf;
-
- _vgaSpriteChanged++;
-}
-
void AGOSEngine::vc62_fastFadeOut() {
vc29_stopAllSounds();
@@ -2833,493 +1747,357 @@ void AGOSEngine::vc63_fastFadeIn() {
_fastFadeOutFlag = false;
}
-void AGOSEngine::vc64_skipIfSpeechEnded() {
- if ((getGameType() == GType_SIMON2 && _subtitles && _language != Common::HB_ISR) ||
- !_sound->isVoiceActive()) {
- vcSkipNextInstruction();
- }
-}
-
-void AGOSEngine::vc65_slowFadeIn() {
- _fastFadeInFlag = 624;
- _fastFadeCount = 208;
- if (_windowNum != 4) {
- _fastFadeInFlag = 768;
- _fastFadeCount = 256;
- }
- _fastFadeInFlag |= 0x8000;
- _fastFadeOutFlag = false;
-}
-
-void AGOSEngine::vc66_skipIfNotEqual() {
- uint16 a = vcReadNextWord();
- uint16 b = vcReadNextWord();
-
- if (vcReadVar(a) != vcReadVar(b))
- vcSkipNextInstruction();
-}
-
-void AGOSEngine::vc67_skipIfGE() {
- uint16 a = vcReadNextWord();
- uint16 b = vcReadNextWord();
+void AGOSEngine::animate(uint windowNum, uint zoneNum, uint vgaSpriteId, uint x, uint y, uint palette, bool setZone) {
+ VgaSprite *vsp;
+ VgaPointersEntry *vpe;
+ byte *p, *pp;
+ uint count;
- if (vcReadVar(a) >= vcReadVar(b))
- vcSkipNextInstruction();
-}
+ if (isSpriteLoaded(vgaSpriteId, zoneNum))
+ return;
-void AGOSEngine::vc68_skipIfLE() {
- uint16 a = vcReadNextWord();
- uint16 b = vcReadNextWord();
+ vsp = _vgaSprites;
+ while (vsp->id != 0)
+ vsp++;
- if (vcReadVar(a) <= vcReadVar(b))
- vcSkipNextInstruction();
-}
+ vsp->windowNum = windowNum;
+ vsp->priority = 0;
+ vsp->flags = 0;
-void AGOSEngine::vc69_playTrack() {
- int16 track = vcReadNextWord();
- int16 loop = vcReadNextWord();
-
- // Jamieson630:
- // This is a "play track". The original
- // 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
- // to vc72(), except that vc72() may allow for
- // specifying a non-valid track number (999 or -1)
- // as a means of stopping what music is currently
- // playing.
- midi.setLoop(loop != 0);
- midi.startTrack(track);
-}
-
-void AGOSEngine::vc70_queueMusic() {
- // Simon2
- uint16 track = vcReadNextWord();
- uint16 loop = vcReadNextWord();
-
- // 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.
- if (track != 0xFFFF && track != 999)
- midi.queueTrack(track, loop != 0);
+ vsp->y = y;
+ vsp->x = x;
+ vsp->image = 0;
+ if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
+ vsp->palette = 0;
else
- midi.setLoop(loop != 0);
-}
-
-void AGOSEngine::vc71_checkMusicQueue() {
- // 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))
- vcSkipNextInstruction();
-}
-
-void AGOSEngine::vc72_play_track_2() {
- // Jamieson630:
- // This is a "play or stop track". Note that
- // this opcode looks very similar in function
- // to vc69(), except that this opcode may allow
- // for specifying a track of 999 or -1 in order to
- // stop the music. We'll code it that way for now.
+ vsp->palette = palette;
+ vsp->id = vgaSpriteId;
- // 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.
+ if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP)
+ vsp->zoneNum = zoneNum;
+ else
+ vsp->zoneNum = zoneNum = vgaSpriteId / 100;
- int16 track = vcReadNextWord();
- int16 loop = vcReadNextWord();
+ for (;;) {
+ vpe = &_vgaBufferPointers[zoneNum];
+ _curVgaFile1 = vpe->vgaFile1;
+ if (setZone) {
+ _zoneNumber = zoneNum;
+ if (vpe->vgaFile1 != NULL)
+ break;
+ loadZone(zoneNum);
+ } else {
+ if (vpe->vgaFile1 != NULL)
+ break;
+ if (_zoneNumber != zoneNum)
+ _noOverWrite = _zoneNumber;
- if (track == -1 || track == 999) {
- midi.stop();
- } else {
- midi.setLoop (loop != 0);
- midi.startTrack (track);
+ loadZone(zoneNum);
+ _noOverWrite = 0xFFFF;
+ }
}
-}
-
-void AGOSEngine::vc73_setMark() {
- _marks |= (1 << vcReadNextWord());
-}
-void AGOSEngine::vc74_clearMark() {
- _marks &= ~(1 << vcReadNextWord());
-}
+ pp = _curVgaFile1;
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ p = pp + READ_LE_UINT16(pp + 2);
+ count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationCount);
+ p = pp + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationTable);
-int AGOSEngine::getScale(int16 y, int16 x) {
- int16 z;
+ while (count--) {
+ if (READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->id) == vgaSpriteId)
+ break;
+ p += sizeof(AnimationHeader_Feeble);
+ }
+ assert(READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->id) == vgaSpriteId);
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ p = pp + READ_BE_UINT16(pp + 4);
+ count = READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationCount);
+ p = pp + READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationTable);
- 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);
+ while (count--) {
+ if (READ_BE_UINT16(&((AnimationHeader_Simon *) p)->id) == vgaSpriteId)
+ break;
+ p += sizeof(AnimationHeader_Simon);
}
+ assert(READ_BE_UINT16(&((AnimationHeader_Simon *) p)->id) == vgaSpriteId);
+ } else {
+ p = pp + READ_BE_UINT16(pp + 10);
+ p += 20;
- z = ((int16)((x * (1 - ((_baseY - y) * _scale))) + 0.5));
- if (z < 2)
- return(2);
+ count = READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationCount);
+ p = pp + READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationTable);
- return(z);
+ 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);
}
-}
-
-void AGOSEngine::vc75_setScale() {
- _baseY = vcReadNextWord();
- _scale = (float)vcReadNextWord() / 1000000.;
-}
-void AGOSEngine::vc76_setScaleXOffs() {
- if (getGameType() == GType_PP && getBitFlag(120)) {
- VgaSprite *vsp1, *vsp2;
- uint16 old_file_1, tmp1, tmp2;
-
- old_file_1 = _vgaCurSpriteId;
+#ifdef DUMP_FILE_NR
+ {
+ static bool dumped = false;
+ if (res == DUMP_FILE_NR && !dumped) {
+ dumped = true;
+ dump_vga_file(_curVgaFile1);
+ }
+ }
+#endif
- _vgaCurSpriteId = vcReadVar(vcReadNextWord());
- vsp1 = findCurSprite();
- _vgaCurSpriteId = vcReadVar(vcReadNextWord());
- vsp2 = findCurSprite();
+#ifdef DUMP_BITMAPS_FILE_NR
+ {
+ static bool dumped = false;
+ if (res == DUMP_BITMAPS_FILE_NR && !dumped) {
+ dumped = true;
+ dump_vga_bitmaps(_curVgaFile2, _curVgaFile1, zoneNum);
+ }
+ }
+#endif
- tmp1 = vsp1->x;
- tmp2 = vsp2->x;
- vsp1->x = tmp2;
- vsp2->x = tmp1;
- tmp1 = vsp1->y;
- tmp2 = vsp2->y;
- vsp1->y = tmp2;
- vsp2->y = tmp1;
+ if (_startVgaScript) {
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ dump_vga_script(_curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), zoneNum, vgaSpriteId);
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon*)p)->scriptOffs), zoneNum, vgaSpriteId);
+ } else {
+ dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW*)p)->scriptOffs), zoneNum, vgaSpriteId);
+ }
+ }
- _vgaCurSpriteId = old_file_1;
- _vcPtr += 2;
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->scriptOffs), vgaSpriteId, zoneNum);
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon *) p)->scriptOffs), vgaSpriteId, zoneNum);
} 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;
+ addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW *) p)->scriptOffs), vgaSpriteId, zoneNum);
}
}
-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;
+void AGOSEngine::set_video_mode_internal(uint16 mode, uint16 vga_res_id) {
+ uint num, num_lines;
+ VgaPointersEntry *vpe;
+ byte *bb, *b;
+ uint16 count, updateWindow;
+ const byte *vc_ptr_org;
- uint16 posy = readUint16Wrapper(p + 1);
- _variableArrayPtr[16] = posy;
- vsp->y = posy;
+ _windowNum = updateWindow = mode;
+ _lockWord |= 0x20;
- if (getGameType() == GType_FF) {
- setBitFlag(85, false);
- if (getBitFlag(74)) {
- centreScroll();
- }
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ vc27_resetSprite();
}
-}
-
-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++;
+ if (vga_res_id == 0) {
+ if (getGameType() == GType_SIMON1) {
+ _unkPalFlag = true;
+ } else if (getGameType() == GType_SIMON2) {
+ _useBackGround = true;
+ _restoreWindow6 = true;
+ }
}
- _variableArrayPtr[13] = pos;
-}
-
-void AGOSEngine::vc80_setOverlayImage() {
- VgaSprite *vsp = findCurSprite();
+ _zoneNumber = num = vga_res_id / 100;
- vsp->image = vcReadVarOrWord();
+ for (;;) {
+ vpe = &_vgaBufferPointers[num];
- vsp->x += vcReadNextWord();
- vsp->y += vcReadNextWord();
- vsp->flags = kDFOverlayed;
+ _curVgaFile1 = vpe->vgaFile1;
+ _curVgaFile2 = vpe->vgaFile2;
+ _curSfxFile = vpe->sfxFile;
- _vgaSpriteChanged++;
-}
+ if (vpe->vgaFile1 != NULL)
+ break;
-void AGOSEngine::vc81_setRandom() {
- uint16 var = vcReadNextWord();
- uint16 value = vcReadNextWord();
+ loadZone(num);
+ }
- _variableArray[var] = _rnd.getRandomNumber(value - 1);
-}
+ bb = _curVgaFile1;
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ b = bb + READ_LE_UINT16(bb + 2);
+ count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageCount);
+ b = bb + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageTable);
-void AGOSEngine::vc82_getPathValue() {
- uint8 val;
+ while (count--) {
+ if (READ_LE_UINT16(&((ImageHeader_Feeble *) b)->id) == vga_res_id)
+ break;
+ b += sizeof(ImageHeader_Feeble);
+ }
+ assert(READ_LE_UINT16(&((ImageHeader_Feeble *) b)->id) == vga_res_id);
- uint16 var = vcReadNextWord();
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ b = bb + READ_BE_UINT16(bb + 4);
+ count = READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageCount);
+ b = bb + READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageTable);
- if (getGameType() == GType_FF && getBitFlag(82)) {
- val = _pathValues1[_GPVCount1++];
+ while (count--) {
+ if (READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == vga_res_id)
+ break;
+ b += sizeof(ImageHeader_Simon);
+ }
+ assert(READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == vga_res_id);
} else {
- val = _pathValues[_GPVCount++];
- }
-
- vcWriteVar(var, val);
-}
-
-void AGOSEngine::vc83_playSoundLoop() {
- uint16 sound = vcReadNextWord();
- int16 vol = vcReadNextWord();
- int16 pan = vcReadNextWord();
-
- loadSound(sound, pan, vol, 3);
-}
+ b = bb + READ_BE_UINT16(bb + 10);
+ b += 20;
-void AGOSEngine::vc84_stopSoundLoop() {
- _sound->stopSfx5();
-}
+ count = READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageCount);
+ b = bb + READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageTable);
-// Scrolling functions for Feeble Files
-void AGOSEngine::checkScrollX(int16 x, int16 xpos) {
- if (_scrollXMax == 0 || x == 0)
- return;
+ while (count--) {
+ if (READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == vga_res_id)
+ break;
+ b += sizeof(ImageHeader_WW);
+ }
+ assert(READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == vga_res_id);
- if ((getGameType() == GType_FF) && (getBitFlag(80) || getBitFlag(82)))
- return;
+ clearWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_WW *) b)->color));
+ }
- int16 tmp;
- if (x > 0) {
- if (_scrollCount != 0) {
- if (_scrollCount >= 0)
- return;
- _scrollCount = 0;
+ if (_startVgaScript) {
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ dump_vga_script(_curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble*)b)->scriptOffs), num, vga_res_id);
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon*)b)->scriptOffs), num, vga_res_id);
} else {
- if (_scrollFlag != 0)
- return;
+ dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((ImageHeader_WW*)b)->scriptOffs), num, vga_res_id);
}
+ }
- 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 (getGameType() == GType_SIMON1) {
+ if (vga_res_id == 16300) {
+ clearBackFromTop(134);
+ _usePaletteDelay = true;
}
-
- if (xpos - _scrollX < 161) {
- _scrollCount = -320;
- if (_scrollX < 320)
- _scrollCount = -_scrollX;
+ } else if (getGameType() == GType_SIMON2 || getGameType() == GType_FF) {
+ _scrollX = 0;
+ _scrollY = 0;
+ _scrollXMax = 0;
+ _scrollYMax = 0;
+ _scrollCount = 0;
+ _scrollFlag = 0;
+ _scrollHeight = 134;
+ _variableArrayPtr = _variableArray;
+ if (_variableArray[34] >= 0) {
+ if (getGameType() == GType_FF)
+ _variableArray[250] = 0;
+ _variableArray[251] = 0;
}
}
-}
-void AGOSEngine::checkScrollY(int16 y, int16 ypos) {
- if (_scrollYMax == 0)
- return;
+ vc_ptr_org = _vcPtr;
- if (getGameType() == GType_FF && getBitFlag(80))
- return;
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ _vcPtr = _curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble *) b)->scriptOffs);
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ _vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon *) b)->scriptOffs);
+ } else {
+ _vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_WW *) b)->scriptOffs);
+ }
- int16 tmp;
- if (y >= 0) {
- if (_scrollCount != 0) {
- if (_scrollCount >= 0)
- return;
- } else {
- if (_scrollFlag != 0)
- return;
- }
+ runVgaScript();
+ _vcPtr = vc_ptr_org;
- if (ypos - _scrollY >= 440) {
- _scrollCount = 240;
- tmp = _scrollYMax - _scrollY;
- if (tmp < 240)
- _scrollCount = tmp;
- }
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ fillFrontFromBack(0, 0, _screenWidth, _screenHeight);
+ fillBackGroundFromBack(_screenHeight);
+ _syncFlag2 = 1;
+ } else if (getGameType() == GType_SIMON2) {
+ if (!_useBackGround) {
+ num_lines = _windowNum == 4 ? 134 : 200;
+ _boxStarHeight = num_lines;
+ fillFrontFromBack(0, 0, _screenWidth, num_lines);
+ fillBackGroundFromBack(num_lines);
+ _syncFlag2 = 1;
+ }
+ _useBackGround = false;
} else {
- if (_scrollCount != 0) {
- if (_scrollCount < 0)
- return;
- } else {
- if (_scrollFlag != 0)
- return;
- }
+ // Allow one section of Simon the Sorcerer 1 introduction to be displayed
+ // in lower half of screen
+ if (_subroutine == 2923 || _subroutine == 2926)
+ num_lines = 200;
+ else
+ num_lines = _windowNum == 4 ? 134 : 200;
- if (ypos - _scrollY < 100) {
- _scrollCount = -240;
- if (_scrollY < 240)
- _scrollCount = -_scrollY;
- }
+ fillFrontFromBack(0, 0, _screenWidth, num_lines);
+ fillBackGroundFromBack(num_lines);
+
+ _syncFlag2 = 1;
+ _timer5 = 0;
}
-}
-void AGOSEngine::centreScroll() {
- int16 x, y, tmp;
+ if (getGameType() == GType_ELVIRA1 && updateWindow == 3 && _bottomPalette != 0) {
+ byte *dst = getBackBuf() + 42560;
+ int size = 21440;
- 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;
+ while (size--) {
+ *dst += 0x10;
+ dst++;
}
}
-}
-
-void AGOSEngine::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++;
+ _lockWord &= ~0x20;
- 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;
+ if (getGameType() == GType_SIMON1) {
+ if (_unkPalFlag) {
+ _unkPalFlag = false;
+ while (_fastFadeInFlag != 0) {
+ delay(10);
+ }
}
- vsp->id = 1000 + i;
- vsp->zoneNum = zoneNum;
}
}
-void AGOSEngine::startAnOverlayAnim() {
- VgaSprite *vsp = _vgaSprites;
- const byte *vcPtrOrg;
- uint16 a, sprite, file, tmp, zoneNum;
- int16 x;
-
- zoneNum = _variableArray[999];
-
- _vcPtr += 4;
- a = vcReadNextWord();
- _vcPtr += 6;
+void AGOSEngine::waitForSync(uint a) {
+ const uint maxCount = (getGameType() == GType_SIMON1) ? 500 : 1000;
- 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;
+ if (getGameType() == GType_SIMON1 && (getFeatures() & GF_TALKIE)) {
+ if (a != 200) {
+ uint16 tmp = _lastVgaWaitFor;
+ _lastVgaWaitFor = 0;
+ if (tmp == a)
+ return;
+ }
}
- 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;
+ _vgaWaitFor = a;
+ _syncCount = 0;
+ _exitCutscene = false;
+ _rightButtonDown = false;
- tmp = to16Wrapper(vsp->priority);
+ while (_vgaWaitFor != 0) {
+ if (_rightButtonDown) {
+ if (_vgaWaitFor == 200 && (getGameType() == GType_FF || !getBitFlag(14))) {
+ skipSpeech();
+ break;
+ }
+ }
+ if (_exitCutscene) {
+ if (getGameType() == GType_ELVIRA1) {
+ if (_variableArray[105] == 0) {
+ _variableArray[105] = 255;
+ break;
+ }
+ } else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
+ if (_vgaWaitFor == 51) {
+ setBitFlag(244, 1);
+ break;
+ }
+ } else {
+ if (getBitFlag(9)) {
+ endCutscene();
+ break;
+ }
+ }
+ }
+ processSpecialKeys();
- vcPtrOrg = _vcPtr;
- _vcPtr = (byte *)&tmp;
- vc23_setPriority();
+ if (_syncCount >= maxCount) {
+ warning("waitForSync: wait timed out");
+ break;
+ }
- _vcPtr = vcPtrOrg;
- _vgaCurSpriteId = sprite;
- _vgaCurZoneNum = file;
+ delay(1);
+ }
}
} // End of namespace AGOS
diff --git a/engines/agos/vga_ff.cpp b/engines/agos/vga_ff.cpp
new file mode 100644
index 0000000000..dce9506684
--- /dev/null
+++ b/engines/agos/vga_ff.cpp
@@ -0,0 +1,437 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "agos/agos.h"
+#include "agos/intern.h"
+#include "agos/vga.h"
+
+namespace AGOS {
+
+void AGOSEngine::setupFeebleVideoOpcodes(VgaOpcodeProc *op) {
+ setupSimon2VideoOpcodes(op);
+
+ op[53] = &AGOSEngine::vc53_panSFX;
+ 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;
+}
+
+void AGOSEngine::vc53_panSFX() {
+ VgaSprite *vsp = findCurSprite();
+ int pan;
+
+ uint16 sound = vcReadNextWord();
+ int16 xoffs = vcReadNextWord();
+ int16 vol = vcReadNextWord();
+
+ 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);
+}
+
+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::vc75_setScale() {
+ _baseY = vcReadNextWord();
+ _scale = (float)vcReadNextWord() / 1000000.;
+}
+
+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)) {
+ centreScroll();
+ }
+ }
+}
+
+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, 3);
+}
+
+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::centreScroll() {
+ 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;
+ }
+ }
+}
+
+void AGOSEngine::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::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
diff --git a/engines/agos/vga_s1.cpp b/engines/agos/vga_s1.cpp
new file mode 100644
index 0000000000..5e19a4830e
--- /dev/null
+++ b/engines/agos/vga_s1.cpp
@@ -0,0 +1,215 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "agos/agos.h"
+#include "agos/intern.h"
+#include "agos/vga.h"
+
+namespace AGOS {
+
+void AGOSEngine::setupSimon1VideoOpcodes(VgaOpcodeProc *op) {
+ setupCommonVideoOpcodes(op);
+
+ op[11] = &AGOSEngine::vc11_clearPathFinder;
+ op[17] = &AGOSEngine::vc17_setPathfinderItem;
+ op[22] = &AGOSEngine::vc22_setPaletteNew;
+ op[32] = &AGOSEngine::vc32_copyVar;
+ op[37] = &AGOSEngine::vc37_addToSpriteY;
+ op[48] = &AGOSEngine::vc48_setPathFinder;
+ op[59] = &AGOSEngine::vc59_skipIfSpeechEnded;
+ op[60] = &AGOSEngine::vc60_stopAnimation;
+ op[61] = &AGOSEngine::vc61_setMaskImage;
+ op[62] = &AGOSEngine::vc62_fastFadeOut;
+ op[63] = &AGOSEngine::vc63_fastFadeIn;
+}
+
+void AGOSEngine::vc11_clearPathFinder() {
+ memset(&_pathFindArray, 0, sizeof(_pathFindArray));
+}
+
+void AGOSEngine::vc17_setPathfinderItem() {
+ uint16 a = vcReadNextWord();
+ _pathFindArray[a - 1] = (const uint16 *)_vcPtr;
+
+ int end = (getGameType() == GType_FF || getGameType() == GType_PP) ? 9999 : 999;
+ while (readUint16Wrapper(_vcPtr) != end)
+ _vcPtr += 4;
+ _vcPtr += 2;
+}
+
+void AGOSEngine::vc22_setPaletteNew() {
+ byte *offs, *palptr, *src;
+ uint16 a = 0, b, num, palSize;
+
+ a = vcReadNextWord();
+ b = vcReadNextWord();
+
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ num = 256;
+ palSize = 768;
+
+ palptr = _displayPalette;
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ num = a == 0 ? 32 : 16;
+ palSize = 96;
+
+ palptr = &_displayPalette[(a * 64)];
+ }
+
+ offs = _curVgaFile1 + 6;
+ src = offs + b * palSize;
+
+ do {
+ palptr[0] = src[0] * 4;
+ palptr[1] = src[1] * 4;
+ palptr[2] = src[2] * 4;
+ palptr[3] = 0;
+
+ palptr += 4;
+ src += 3;
+ } while (--num);
+
+ _paletteFlag = 2;
+ _vgaSpriteChanged++;
+}
+
+void AGOSEngine::vc32_copyVar() {
+ uint16 a = vcReadVar(vcReadNextWord());
+ vcWriteVar(vcReadNextWord(), a);
+}
+
+void AGOSEngine::vc37_addToSpriteY() {
+ VgaSprite *vsp = findCurSprite();
+ vsp->y += vcReadVar(vcReadNextWord());
+ _vgaSpriteChanged++;
+}
+
+void AGOSEngine::vc45_setSpriteX() {
+ VgaSprite *vsp = findCurSprite();
+ vsp->x = vcReadVar(vcReadNextWord());
+ _vgaSpriteChanged++;
+}
+
+void AGOSEngine::vc46_setSpriteY() {
+ VgaSprite *vsp = findCurSprite();
+ vsp->y = vcReadVar(vcReadNextWord());
+ _vgaSpriteChanged++;
+}
+
+void AGOSEngine::vc47_addToVar() {
+ uint16 var = vcReadNextWord();
+ vcWriteVar(var, vcReadVar(var) + vcReadVar(vcReadNextWord()));
+}
+
+void AGOSEngine::vc48_setPathFinder() {
+ uint16 a = (uint16)_variableArrayPtr[12];
+ const uint16 *p = _pathFindArray[a - 1];
+
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ 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;
+ } else {
+ uint b = (uint16)_variableArray[13];
+ p += b * 2 + 1;
+ int c = _variableArray[14];
+
+ int step;
+ int y1, y2;
+ int16 *vp;
+
+ step = 2;
+ if (c < 0) {
+ c = -c;
+ step = -2;
+ }
+
+ 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);
+ }
+}
+
+void AGOSEngine::vc59_skipIfSpeechEnded() {
+ if (!_sound->isVoiceActive())
+ vcSkipNextInstruction();
+}
+
+void AGOSEngine::vc61_setMaskImage() {
+ VgaSprite *vsp = findCurSprite();
+
+ vsp->image = vcReadVarOrWord();
+ vsp->x += vcReadNextWord();
+ vsp->y += vcReadNextWord();
+ vsp->flags = kDFMasked | kDFUseFrontBuf;
+
+ _vgaSpriteChanged++;
+}
+
+} // End of namespace AGOS
diff --git a/engines/agos/vga_s2.cpp b/engines/agos/vga_s2.cpp
new file mode 100644
index 0000000000..4711b4cc36
--- /dev/null
+++ b/engines/agos/vga_s2.cpp
@@ -0,0 +1,211 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "agos/agos.h"
+#include "agos/intern.h"
+#include "agos/vga.h"
+
+namespace AGOS {
+
+void AGOSEngine::setupSimon2VideoOpcodes(VgaOpcodeProc *op) {
+ setupSimon1VideoOpcodes(op);
+
+ op[56] = &AGOSEngine::vc56_delayLong;
+ op[58] = &AGOSEngine::vc58_changePriority;
+ op[59] = &AGOSEngine::vc59_stopAnimations;
+ op[64] = &AGOSEngine::vc64_skipIfSpeechEnded;
+ op[65] = &AGOSEngine::vc65_slowFadeIn;
+ op[66] = &AGOSEngine::vc66_skipIfNotEqual;
+ op[67] = &AGOSEngine::vc67_skipIfGE;
+ op[68] = &AGOSEngine::vc68_skipIfLE;
+ op[69] = &AGOSEngine::vc69_playTrack;
+ op[70] = &AGOSEngine::vc70_queueMusic;
+ op[71] = &AGOSEngine::vc71_checkMusicQueue;
+ op[72] = &AGOSEngine::vc72_play_track_2;
+ op[73] = &AGOSEngine::vc73_setMark;
+ op[74] = &AGOSEngine::vc74_clearMark;
+}
+
+void AGOSEngine::vc56_delayLong() {
+ uint16 num = vcReadVarOrWord() * _frameRate;
+
+ addVgaEvent(num + _vgaBaseDelay, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum);
+ _vcPtr = (byte *)&_vc_get_out_of_code;
+}
+
+void AGOSEngine::vc58_changePriority() {
+ uint16 sprite = _vgaCurSpriteId;
+ uint16 file = _vgaCurZoneNum;
+ const byte *vcPtrOrg;
+ uint16 tmp;
+
+ _vgaCurZoneNum = vcReadNextWord();
+ _vgaCurSpriteId = vcReadNextWord();
+
+ tmp = to16Wrapper(vcReadNextWord());
+
+ vcPtrOrg = _vcPtr;
+ _vcPtr = (byte *)&tmp;
+ vc23_setPriority();
+
+ _vcPtr = vcPtrOrg;
+ _vgaCurSpriteId = sprite;
+ _vgaCurZoneNum = file;
+}
+
+void AGOSEngine::vc59_stopAnimations() {
+ uint16 file = vcReadNextWord();
+ uint16 start = vcReadNextWord();
+ uint16 end = vcReadNextWord() + 1;
+
+ do {
+ vc_kill_sprite(file, start);
+ } while (++start != end);
+}
+
+void AGOSEngine::vc64_skipIfSpeechEnded() {
+ if ((getGameType() == GType_SIMON2 && _subtitles && _language != Common::HB_ISR) ||
+ !_sound->isVoiceActive()) {
+ vcSkipNextInstruction();
+ }
+}
+
+void AGOSEngine::vc65_slowFadeIn() {
+ _fastFadeInFlag = 624;
+ _fastFadeCount = 208;
+ if (_windowNum != 4) {
+ _fastFadeInFlag = 768;
+ _fastFadeCount = 256;
+ }
+ _fastFadeInFlag |= 0x8000;
+ _fastFadeOutFlag = false;
+}
+
+void AGOSEngine::vc66_skipIfNotEqual() {
+ uint16 a = vcReadNextWord();
+ uint16 b = vcReadNextWord();
+
+ if (vcReadVar(a) != vcReadVar(b))
+ vcSkipNextInstruction();
+}
+
+void AGOSEngine::vc67_skipIfGE() {
+ uint16 a = vcReadNextWord();
+ uint16 b = vcReadNextWord();
+
+ if (vcReadVar(a) >= vcReadVar(b))
+ vcSkipNextInstruction();
+}
+
+void AGOSEngine::vc68_skipIfLE() {
+ uint16 a = vcReadNextWord();
+ uint16 b = vcReadNextWord();
+
+ if (vcReadVar(a) <= vcReadVar(b))
+ vcSkipNextInstruction();
+}
+
+void AGOSEngine::vc69_playTrack() {
+ int16 track = vcReadNextWord();
+ int16 loop = vcReadNextWord();
+
+ // Jamieson630:
+ // This is a "play track". The original
+ // 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
+ // to vc72(), except that vc72() may allow for
+ // specifying a non-valid track number (999 or -1)
+ // as a means of stopping what music is currently
+ // playing.
+ midi.setLoop(loop != 0);
+ midi.startTrack(track);
+}
+
+void AGOSEngine::vc70_queueMusic() {
+ // Simon2
+ uint16 track = vcReadNextWord();
+ uint16 loop = vcReadNextWord();
+
+ // 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.
+ if (track != 0xFFFF && track != 999)
+ midi.queueTrack(track, loop != 0);
+ else
+ midi.setLoop(loop != 0);
+}
+
+void AGOSEngine::vc71_checkMusicQueue() {
+ // 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))
+ vcSkipNextInstruction();
+}
+
+void AGOSEngine::vc72_play_track_2() {
+ // Jamieson630:
+ // This is a "play or stop track". Note that
+ // this opcode looks very similar in function
+ // to vc69(), except that this opcode may allow
+ // for specifying a track of 999 or -1 in order to
+ // stop the music. We'll code it that way for now.
+
+ // 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.
+
+ int16 track = vcReadNextWord();
+ int16 loop = vcReadNextWord();
+
+ if (track == -1 || track == 999) {
+ midi.stop();
+ } else {
+ midi.setLoop (loop != 0);
+ midi.startTrack (track);
+ }
+}
+
+void AGOSEngine::vc73_setMark() {
+ _marks |= (1 << vcReadNextWord());
+}
+
+void AGOSEngine::vc74_clearMark() {
+ _marks &= ~(1 << vcReadNextWord());
+}
+
+} // End of namespace AGOS
diff --git a/engines/agos/zones.cpp b/engines/agos/zones.cpp
new file mode 100644
index 0000000000..7316f15f4f
--- /dev/null
+++ b/engines/agos/zones.cpp
@@ -0,0 +1,196 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001 Ludvig Strigeus
+ * Copyright (C) 2001-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "common/file.h"
+
+#include "agos/intern.h"
+#include "agos/agos.h"
+#include "agos/vga.h"
+
+namespace AGOS {
+
+void AGOSEngine::loadZone(uint zoneNum) {
+ VgaPointersEntry *vpe;
+
+ CHECK_BOUNDS(zoneNum, _vgaBufferPointers);
+
+ vpe = _vgaBufferPointers + zoneNum;
+ if (vpe->vgaFile1 != NULL)
+ return;
+
+ // Loading order is important
+ // due to resource managment
+
+ loadVGAVideoFile(zoneNum, 2);
+ vpe->vgaFile2 = _block;
+ vpe->vgaFile2End = _blockEnd;
+
+ loadVGAVideoFile(zoneNum, 1);
+ vpe->vgaFile1 = _block;
+ vpe->vgaFile1End = _blockEnd;
+
+ vpe->sfxFile = NULL;
+ if (!(getFeatures() & GF_ZLIBCOMP)) {
+ if (loadVGASoundFile(zoneNum, 3)) {
+ vpe->sfxFile = _block;
+ vpe->sfxFileEnd = _blockEnd;
+ }
+ }
+}
+
+void AGOSEngine::setZoneBuffers() {
+ _zoneBuffers = (byte *)malloc(_vgaMemSize);
+
+ _vgaMemPtr = _zoneBuffers;
+ _vgaMemBase = _zoneBuffers;
+ _vgaFrozenBase = _zoneBuffers;
+ _vgaRealBase = _zoneBuffers;
+ _vgaMemEnd = _zoneBuffers + _vgaMemSize;
+}
+
+byte *AGOSEngine::allocBlock(uint32 size) {
+ for (;;) {
+ _block = _vgaMemPtr;
+ _blockEnd = _block + size;
+
+ if (_blockEnd >= _vgaMemEnd) {
+ _vgaMemPtr = _vgaMemBase;
+ } else {
+ _rejectBlock = false;
+ checkNoOverWrite();
+ if (_rejectBlock)
+ continue;
+ checkRunningAnims();
+ if (_rejectBlock)
+ continue;
+ checkZonePtrs();
+ _vgaMemPtr = _blockEnd;
+ return _block;
+ }
+ }
+}
+
+void AGOSEngine::checkNoOverWrite() {
+ VgaPointersEntry *vpe;
+
+ if (_noOverWrite == 0xFFFF)
+ return;
+
+ vpe = &_vgaBufferPointers[_noOverWrite];
+
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block) {
+ _rejectBlock = true;
+ _vgaMemPtr = vpe->vgaFile1End;
+ } else if (vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block) {
+ _rejectBlock = true;
+ _vgaMemPtr = vpe->vgaFile2End;
+ } else if (vpe->sfxFile && vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) {
+ _rejectBlock = true;
+ _vgaMemPtr = vpe->sfxFileEnd;
+ } else {
+ _rejectBlock = false;
+ }
+ } else {
+ if (_block <= vpe->vgaFile1 && _blockEnd >= vpe->vgaFile1 ||
+ _vgaMemPtr <= vpe->vgaFile2 && _blockEnd >= vpe->vgaFile2) {
+ _rejectBlock = true;
+ _vgaMemPtr = vpe->vgaFile1 + 0x5000;
+ } else {
+ _rejectBlock = false;
+ }
+ }
+}
+
+void AGOSEngine::checkRunningAnims() {
+ VgaSprite *vsp;
+ if (getGameType() != GType_FF && getGameType() != GType_PP && (_lockWord & 0x20)) {
+ return;
+ }
+
+ for (vsp = _vgaSprites; vsp->id; vsp++) {
+ checkAnims(vsp->zoneNum);
+ if (_rejectBlock == true)
+ return;
+ }
+}
+
+void AGOSEngine::checkAnims(uint a) {
+ VgaPointersEntry *vpe;
+
+ vpe = &_vgaBufferPointers[a];
+
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block) {
+ _rejectBlock = true;
+ _vgaMemPtr = vpe->vgaFile1End;
+ } else if (vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block) {
+ _rejectBlock = true;
+ _vgaMemPtr = vpe->vgaFile2End;
+ } else if (vpe->sfxFile && vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) {
+ _rejectBlock = true;
+ _vgaMemPtr = vpe->sfxFileEnd;
+ } else {
+ _rejectBlock = false;
+ }
+ } else {
+ if (_block <= vpe->vgaFile1 && _blockEnd >= vpe->vgaFile1 ||
+ _block <= vpe->vgaFile2 && _blockEnd >= vpe->vgaFile2) {
+ _rejectBlock = true;
+ _vgaMemPtr = vpe->vgaFile1 + 0x5000;
+ } else {
+ _rejectBlock = false;
+ }
+ }
+}
+
+void AGOSEngine::checkZonePtrs() {
+ uint count = ARRAYSIZE(_vgaBufferPointers);
+ VgaPointersEntry *vpe = _vgaBufferPointers;
+ do {
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block ||
+ vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block ||
+ vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) {
+ vpe->vgaFile1 = NULL;
+ vpe->vgaFile1End = NULL;
+ vpe->vgaFile2 = NULL;
+ vpe->vgaFile2End = NULL;
+ vpe->sfxFile = NULL;
+ vpe->sfxFileEnd = NULL;
+ }
+ } else {
+ if (_block <= vpe->vgaFile1 && _blockEnd >= vpe->vgaFile1 ||
+ _block <= vpe->vgaFile2 && _blockEnd >= vpe->vgaFile2) {
+ vpe->vgaFile1 = NULL;
+ vpe->vgaFile2 = NULL;
+ }
+ }
+ } while (++vpe, --count);
+}
+
+} // End of namespace AGOS
+
+