aboutsummaryrefslogtreecommitdiff
path: root/engines/agos/icons.cpp
diff options
context:
space:
mode:
authorEugene Sandulenko2006-09-29 08:37:24 +0000
committerEugene Sandulenko2006-09-29 08:37:24 +0000
commit798c7ee6822517601ef3c4096ad76a2fc0eefb50 (patch)
tree02b63f44348a35d6e3b6ab53540e94b2e45738e7 /engines/agos/icons.cpp
parent8e2c703baba570b18aec9d871fdc8ee7efe49e57 (diff)
downloadscummvm-rg350-798c7ee6822517601ef3c4096ad76a2fc0eefb50.tar.gz
scummvm-rg350-798c7ee6822517601ef3c4096ad76a2fc0eefb50.tar.bz2
scummvm-rg350-798c7ee6822517601ef3c4096ad76a2fc0eefb50.zip
Phase 2 of Simon renaming. Simon directory renaming
svn-id: r24009
Diffstat (limited to 'engines/agos/icons.cpp')
-rw-r--r--engines/agos/icons.cpp571
1 files changed, 571 insertions, 0 deletions
diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp
new file mode 100644
index 0000000000..2904d9024d
--- /dev/null
+++ b/engines/agos/icons.cpp
@@ -0,0 +1,571 @@
+/* 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/agos.h"
+
+namespace Simon {
+
+void SimonEngine::loadIconFile() {
+ Common::File in;
+ uint size;
+
+ in.open(getFileName(GAME_ICONFILE));
+ if (in.isOpen() == false)
+ error("Can't open icons file '%s'", getFileName(GAME_ICONFILE));
+
+ size = in.size();
+
+ _iconFilePtr = (byte *)malloc(size);
+ if (_iconFilePtr == NULL)
+ error("Out of icon memory");
+
+ in.read(_iconFilePtr, size);
+ in.close();
+}
+
+void SimonEngine::loadIconData() {
+ loadZone(8);
+ VgaPointersEntry *vpe = &_vgaBufferPointers[8];
+
+ byte *src = vpe->vgaFile2 + READ_LE_UINT32(vpe->vgaFile2 + 8);
+
+ _iconFilePtr = (byte *)malloc(43 * 336);
+ if (_iconFilePtr == NULL)
+ error("Out of icon memory");
+
+ memcpy(_iconFilePtr, src, 43 * 336);
+ o_unfreezeZones();
+}
+
+// Thanks to Stuart Caie for providing the original
+// C conversion upon which this function is based.
+void decompressIconAmiga (byte *dst, byte *src, byte base, uint pitch) {
+ byte icon_pln[288];
+ byte *i, *o, x, y;
+
+ // Decode RLE planar icon data
+ i = src;
+ o = icon_pln;
+ while (o < &icon_pln[288]) {
+ x = *i++;
+ if (x < 128) {
+ do {
+ *o++ = *i++;
+ *o++ = *i++;
+ *o++ = *i++;
+ } while (x-- > 0);
+ } else {
+ x = 256 - x;
+ do {
+ *o++ = i[0];
+ *o++ = i[1];
+ *o++ = i[2];
+ } while (x-- > 0);
+ i += 3;
+ }
+ }
+
+ // Translate planar data to chunky (very slow method)
+ for (y = 0; y < 24; y++) {
+ for (x = 0; x < 24; x++) {
+ byte pixel =
+ (icon_pln[(( y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 1 : 0)
+ | (icon_pln[((24 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 2 : 0)
+ | (icon_pln[((48 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 4 : 0)
+ | (icon_pln[((72 + y) * 3) + (x >> 3)] & (1 << (7 - (x & 7))) ? 8 : 0);
+ if (pixel)
+ dst[x] = pixel | base;
+ }
+ dst += pitch;
+ }
+}
+
+static void decompressIcon(byte *dst, byte *src, uint w, uint h_org, byte base, uint pitch) {
+ int8 reps;
+ byte color_1, color_2;
+ byte *dst_org = dst;
+ uint h = h_org;
+
+ for (;;) {
+ reps = *src++;
+ if (reps < 0) {
+ reps--;
+ color_1 = *src >> 4;
+ if (color_1 != 0)
+ color_1 |= base;
+ color_2 = *src++ & 0xF;
+ if (color_2 != 0)
+ color_2 |= base;
+
+ do {
+ if (color_1 != 0)
+ *dst = color_1;
+ dst += pitch;
+ if (color_2 != 0)
+ *dst = color_2;
+ dst += pitch;
+
+ // reached bottom?
+ if (--h == 0) {
+ // reached right edge?
+ if (--w == 0)
+ return;
+ dst = ++dst_org;
+ h = h_org;
+ }
+ } while (++reps != 0);
+ } else {
+ do {
+ color_1 = *src >> 4;
+ if (color_1 != 0)
+ *dst = color_1 | base;
+ dst += pitch;
+
+ color_2 = *src++ & 0xF;
+ if (color_2 != 0)
+ *dst = color_2 | base;
+ dst += pitch;
+
+ // reached bottom?
+ if (--h == 0) {
+ // reached right edge?
+ if (--w == 0)
+ return;
+ dst = ++dst_org;
+ h = h_org;
+ }
+ } while (--reps >= 0);
+ }
+ }
+}
+
+void SimonEngine::draw_icon_c(WindowBlock *window, uint icon, uint x, uint y) {
+ byte *dst;
+ byte *src;
+
+ _lockWord |= 0x8000;
+ dst = getFrontBuf();
+
+ if (getGameType() == GType_SIMON1) {
+ // Simon 1
+ dst += (x + window->x) * 8;
+ dst += (y * 25 + window->y) * _dxSurfacePitch;
+
+ if (getPlatform() == Common::kPlatformAmiga) {
+ src = _iconFilePtr;
+ src += READ_BE_UINT32(&((uint32 *)src)[icon]);
+ decompressIconAmiga (dst, src, 224, _dxSurfacePitch);
+ } else {
+ src = _iconFilePtr;
+ src += READ_LE_UINT16(&((uint16 *)src)[icon]);
+ decompressIcon(dst, src, 24, 12, 224, _dxSurfacePitch);
+ }
+ } else {
+ // Simon 2
+ dst += 110;
+ dst += x;
+ dst += (y + window->y) * _dxSurfacePitch;
+
+ src = _iconFilePtr;
+ src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 0]);
+ decompressIcon(dst, src, 20, 10, 224, _dxSurfacePitch);
+
+ src = _iconFilePtr;
+ src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 1]);
+ decompressIcon(dst, src, 20, 10, 208, _dxSurfacePitch);
+ }
+
+ _lockWord &= ~0x8000;
+}
+
+void SimonEngine::drawIconArray(uint num, Item *itemRef, int line, int classMask) {
+ if (getGameType() == GType_FF) {
+ drawIconArray_FF(num, itemRef, line, classMask);
+ } else {
+ drawIconArray_Simon(num, itemRef, line, classMask);
+ }
+}
+
+void SimonEngine::drawIconArray_Simon(uint num, Item *itemRef, int line, int classMask) {
+ Item *item_ptr_org = itemRef;
+ WindowBlock *window;
+ uint width, height;
+ uint k, i, curWidth;
+ bool item_again, showArrows;
+ uint x_pos, y_pos;
+ const int iconSize = (getGameType() == GType_SIMON1) ? 1 : 20;
+
+ window = _windowArray[num & 7];
+
+ if (getGameType() == GType_SIMON1) {
+ width = window->width / 3;
+ height = window->height / 3;
+ } else {
+ width = 100;
+ height = 40;
+ }
+
+ i = 0;
+
+ if (window == NULL)
+ return;
+
+ if (window->iconPtr)
+ removeIconArray(num);
+
+ window->iconPtr = (IconBlock *) malloc(sizeof(IconBlock));
+ window->iconPtr->itemRef = itemRef;
+ window->iconPtr->upArrow = -1;
+ window->iconPtr->downArrow = -1;
+ window->iconPtr->line = line;
+ window->iconPtr->classMask = classMask;
+
+ itemRef = derefItem(itemRef->child);
+
+ while (itemRef && line-- != 0) {
+ curWidth = 0;
+ while (itemRef && width > curWidth) {
+ if ((classMask == 0 || itemRef->classFlags & classMask) && has_item_childflag_0x10(itemRef))
+ curWidth += iconSize;
+ itemRef = derefItem(itemRef->sibling);
+ }
+ }
+
+ if (itemRef == NULL) {
+ window->iconPtr->line = 0;
+ itemRef = derefItem(item_ptr_org->child);
+ }
+
+ x_pos = 0;
+ y_pos = 0;
+ k = 0;
+ item_again = false;
+ showArrows = false;
+
+ while (itemRef) {
+ if ((classMask == 0 || itemRef->classFlags & classMask) && has_item_childflag_0x10(itemRef)) {
+ if (item_again == false) {
+ window->iconPtr->iconArray[k].item = itemRef;
+ if (getGameType() == GType_SIMON1) {
+ draw_icon_c(window, itemGetIconNumber(itemRef), x_pos * 3, y_pos);
+ window->iconPtr->iconArray[k].boxCode =
+ setupIconHitArea(window, 0, x_pos * 3, y_pos, itemRef);
+ } else {
+ draw_icon_c(window, itemGetIconNumber(itemRef), x_pos, y_pos);
+ window->iconPtr->iconArray[k].boxCode =
+ setupIconHitArea(window, 0, x_pos, y_pos, itemRef);
+ }
+ k++;
+ } else {
+ window->iconPtr->iconArray[k].item = NULL;
+ showArrows = 1;
+ }
+
+ x_pos += iconSize;
+ if (x_pos >= width) {
+ x_pos = 0;
+ y_pos += iconSize;
+ if (y_pos >= height)
+ item_again = true;
+ }
+ }
+ itemRef = derefItem(itemRef->sibling);
+ }
+
+ window->iconPtr->iconArray[k].item = NULL;
+
+ if (showArrows != 0 || window->iconPtr->line != 0) {
+ /* Plot arrows and add their boxes */
+ defineArrowBoxes(window);
+ window->iconPtr->upArrow = _scrollUpHitArea;
+ window->iconPtr->downArrow = _scrollDownHitArea;
+ }
+}
+
+void SimonEngine::drawIconArray_FF(uint num, Item *itemRef, int line, int classMask) {
+ Item *item_ptr_org = itemRef;
+ WindowBlock *window;
+ uint16 flagnumber = 201;
+ uint16 iconperline = 458;
+ uint16 iconsdown = 384;
+ uint16 idone = 0;
+ uint16 icount = 0;
+ uint16 xp = 188, yp = 306;
+ int k;
+ _iOverflow = 0;
+
+ line = _variableArray[30];
+ if (line == 0)
+ _variableArray[31] = 0;
+
+ window = _windowArray[num & 7];
+ if (window == NULL)
+ return;
+
+ for (k = flagnumber; k <= flagnumber + 18; k++)
+ _variableArray[k] = 0;
+
+ if (window->iconPtr)
+ removeIconArray(num);
+
+ window->iconPtr=(IconBlock *)malloc(sizeof(IconBlock));
+ window->iconPtr->itemRef = itemRef;
+ window->iconPtr->upArrow = -1;
+ window->iconPtr->downArrow = -1;
+ window->iconPtr->line = line;
+ window->iconPtr->classMask = classMask;
+
+ itemRef = derefItem(itemRef->child);
+ k = flagnumber;
+
+ while (itemRef && (line > 65)) {
+ uint16 ct = xp;
+ while (itemRef && ct < iconperline) {
+ if ((classMask == 0) || ((itemRef->classFlags & classMask) != 0)) {
+ if (has_item_childflag_0x10(itemRef)) {
+ ct += 45;
+ k++;
+ }
+ }
+ itemRef = derefItem(itemRef->sibling);
+ }
+ line -= 52;
+ if (k == (flagnumber + 18))
+ k = flagnumber;
+ }
+ yp -= line; // Adjust starting y
+
+ if (itemRef == NULL) {
+ window->iconPtr->line = 0;
+ itemRef = derefItem(item_ptr_org->child);
+ }
+
+ while (itemRef) {
+ if ((classMask != 0) && ((itemRef->classFlags & classMask) == 0))
+ goto l1;
+ if (has_item_childflag_0x10(itemRef) == 0)
+ goto l1;
+ if (!idone) {
+/*
+ * Create thee icon and graphics rendering
+ */
+ window->iconPtr->iconArray[icount].item = itemRef;
+ _variableArray[k] = itemGetIconNumber(itemRef);
+ window->iconPtr->iconArray[icount++].boxCode =
+ setupIconHitArea(window, k++, xp, yp, itemRef);
+ } else {
+/*
+ * Just remember the overflow has occured
+ */
+ window->iconPtr->iconArray[icount].item = NULL; /* END MARKINGS */
+ _iOverflow = 1;
+ }
+ xp += 45;
+ if (xp >= iconperline) { /* End of line ? */
+ if (k == (flagnumber + 18))
+ k = flagnumber;
+ xp = 188;
+ yp += 52; /* Move down */
+ if (yp >= iconsdown) { /* Full ? */
+ idone = 1; /* Note completed screen */
+ }
+ }
+l1:; itemRef = derefItem(itemRef->sibling);
+ }
+ window->iconPtr->iconArray[icount].item = NULL; /* END MARKINGS */
+ if (_variableArray[30] == 0) {
+ if (yp != 306)
+ _variableArray[31] = 52;
+ if ((xp == 188) && (yp == 358))
+ _variableArray[31] = 0;
+ }
+
+ /* Plot arrows and add their boxes */
+ defineArrowBoxes(window);
+ window->iconPtr->upArrow = _scrollUpHitArea;
+ window->iconPtr->downArrow = _scrollDownHitArea;
+}
+
+void SimonEngine::defineArrowBoxes(WindowBlock *window) {
+ HitArea *ha;
+
+ ha = findEmptyHitArea();
+ _scrollUpHitArea = ha - _hitAreas;
+ if (getGameType() == GType_FF) {
+ ha->x = 496;
+ ha->y = 279;
+ ha->width = 30;
+ ha->height = 45;
+ ha->flags = kBFBoxInUse | kBFNoTouchName;
+ ha->id = 0x7FFB;
+ ha->priority = 100;
+ ha->window = window;
+ ha->verb = 1;
+ } else if (getGameType() == GType_SIMON2) {
+ ha->x = 81;
+ ha->y = 158;
+ ha->width = 12;
+ ha->height = 26;
+ ha->flags = kBFBoxInUse | kBFNoTouchName;
+ ha->id = 0x7FFB;
+ ha->priority = 100;
+ ha->window = window;
+ ha->verb = 1;
+ } else {
+ ha->x = 308;
+ ha->y = 149;
+ ha->width = 12;
+ ha->height = 17;
+ ha->flags = kBFBoxInUse | kBFNoTouchName;
+ ha->id = 0x7FFB;
+ ha->priority = 100;
+ ha->window = window;
+ ha->verb = 1;
+ }
+
+ ha = findEmptyHitArea();
+ _scrollDownHitArea = ha - _hitAreas;
+
+ if (getGameType() == GType_FF) {
+ ha->x = 496;
+ ha->y = 324;
+ ha->width = 30;
+ ha->height = 44;
+ ha->flags = kBFBoxInUse | kBFNoTouchName;
+ ha->id = 0x7FFC;
+ ha->priority = 100;
+ ha->window = window;
+ ha->verb = 1;
+ } else if (getGameType() == GType_SIMON2) {
+ ha->x = 227;
+ ha->y = 162;
+ ha->width = 12;
+ ha->height = 26;
+ ha->flags = kBFBoxInUse | kBFNoTouchName;
+ ha->id = 0x7FFC;
+ ha->priority = 100;
+ ha->window = window;
+ ha->verb = 1;
+ } else {
+ ha->x = 308;
+ ha->y = 176;
+ ha->width = 12;
+ ha->height = 17;
+ ha->flags = kBFBoxInUse | kBFNoTouchName;
+ ha->id = 0x7FFC;
+ ha->priority = 100;
+ ha->window = window;
+ ha->verb = 1;
+
+ stopAnimateSimon1(128);
+ loadSprite(0, 1, 128, 0, 0, 14);
+ }
+}
+
+uint SimonEngine::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) {
+ HitArea *ha;
+
+ ha = findEmptyHitArea();
+
+ if (getGameType() == GType_FF) {
+ ha->x = x;
+ ha->y = y;
+ ha->item_ptr = item_ptr;
+ ha->width = 45;
+ ha->height = 44;
+ ha->flags = kBFBoxInUse | kBFBoxItem;
+ ha->id = num;
+ ha->priority = 100;
+ ha->verb = 208;
+ } else if (getGameType() == GType_SIMON2) {
+ ha->x = x + 110;
+ ha->y = window->y + y;
+ ha->item_ptr = item_ptr;
+ ha->width = 20;
+ ha->height = 20;
+ ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem;
+ ha->id = 0x7FFD;
+ ha->priority = 100;
+ ha->verb = 208;
+ } else {
+ ha->x = (x + window->x) * 8;
+ ha->y = y * 25 + window->y;
+ ha->item_ptr = item_ptr;
+ ha->width = 24;
+ ha->height = 24;
+ ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem;
+ ha->id = 0x7FFD;
+ ha->priority = 100;
+ ha->verb = 208;
+ }
+
+ return ha - _hitAreas;
+}
+
+void SimonEngine::removeIconArray(uint num) {
+ WindowBlock *window;
+ uint16 curWindow;
+ uint16 i;
+
+ window = _windowArray[num & 7];
+ curWindow = _curWindow;
+
+ if (window == NULL || window->iconPtr == NULL)
+ return;
+
+ if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ changeWindow(num);
+ windowPutChar(12);
+ changeWindow(curWindow);
+ }
+
+ for (i = 0; window->iconPtr->iconArray[i].item != NULL; i++) {
+ delete_hitarea_by_index(window->iconPtr->iconArray[i].boxCode);
+ }
+
+ if (window->iconPtr->upArrow != -1) {
+ delete_hitarea_by_index(window->iconPtr->upArrow);
+ }
+
+ if (window->iconPtr->downArrow != -1) {
+ delete_hitarea_by_index(window->iconPtr->downArrow);
+ if (getGameType() == GType_SIMON1)
+ removeArrows(window, num);
+ }
+
+ free(window->iconPtr);
+ window->iconPtr = NULL;
+
+ _fcsData1[num] = 0;
+ _fcsData2[num] = 0;
+}
+
+void SimonEngine::removeArrows(WindowBlock *window, uint num) {
+ stopAnimateSimon1(128);
+}
+
+} // End of namespace Simon