diff options
-rw-r--r-- | scumm/intern.h | 11 | ||||
-rw-r--r-- | scumm/script_v72he.cpp | 4 | ||||
-rw-r--r-- | scumm/script_v7he.cpp | 146 | ||||
-rw-r--r-- | scumm/script_v80he.cpp | 4 | ||||
-rw-r--r-- | scumm/script_v90he.cpp | 4 | ||||
-rw-r--r-- | scumm/scumm.cpp | 9 | ||||
-rw-r--r-- | scumm/scumm.h | 10 |
7 files changed, 142 insertions, 46 deletions
diff --git a/scumm/intern.h b/scumm/intern.h index 6963756b8f..52dc0eddbf 100644 --- a/scumm/intern.h +++ b/scumm/intern.h @@ -620,6 +620,12 @@ protected: int getCharsetOffsets(int chr); void arrrays_unk2(int dst, int src, int len2, int len); + void polygonStore(int id, bool flag, int vert1x, int vert1y, int vert2x, int vert2y, + int vert3x, int vert3y, int vert4x, int vert4y); + void polygonErase(int fromId, int toId); + bool polygonContains(WizPolygon &pol, int x, int y); + + /* HE version 70 script opcodes */ void o7_cursorCommand(); void o7_startSound(); @@ -637,8 +643,8 @@ protected: void o7_unknownF6(); void o7_setFilePath(); void o7_unknownFA(); - void o7_unknownFB(); - void o7_unknownFC(); + void o7_polygonOps(); + void o7_polygonHit(); }; class ScummEngine_v72he : public ScummEngine_v7he { @@ -786,7 +792,6 @@ protected: void loadImgSpot(int resId, int state, Common::Point &spot); void loadWizCursor(int resId, int resType, bool state); - /* HE version 80 script opcodes */ void o80_unknown45(); diff --git a/scumm/script_v72he.cpp b/scumm/script_v72he.cpp index f63aca5b07..68f69c135b 100644 --- a/scumm/script_v72he.cpp +++ b/scumm/script_v72he.cpp @@ -358,9 +358,9 @@ void ScummEngine_v72he::setupOpcodes() { OPCODE(o72_unknownF8), OPCODE(o72_setFilePath), OPCODE(o72_unknownFA), - OPCODE(o7_unknownFB), + OPCODE(o7_polygonOps), /* FC */ - OPCODE(o7_unknownFC), + OPCODE(o7_polygonHit), OPCODE(o6_invalid), OPCODE(o6_invalid), OPCODE(o6_invalid), diff --git a/scumm/script_v7he.cpp b/scumm/script_v7he.cpp index fe3cfe61f9..c25c756f91 100644 --- a/scumm/script_v7he.cpp +++ b/scumm/script_v7he.cpp @@ -359,9 +359,9 @@ void ScummEngine_v7he::setupOpcodes() { OPCODE(o6_invalid), OPCODE(o7_setFilePath), OPCODE(o7_unknownFA), - OPCODE(o7_unknownFB), + OPCODE(o7_polygonOps), /* FC */ - OPCODE(o7_unknownFC), + OPCODE(o7_polygonHit), OPCODE(o6_invalid), OPCODE(o6_invalid), OPCODE(o6_invalid), @@ -1001,54 +1001,126 @@ void ScummEngine_v7he::o7_unknownFA() { _scriptPointer += len + 1; } -void ScummEngine_v7he::o7_unknownFB() { - int a, b, c, d, e, f, g, h, i; - byte subOp = fetchScriptByte(); +void ScummEngine_v7he::o7_polygonOps() { + byte b; + b = fetchScriptByte(); + int vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y; + int id; + int fromId, toId; - switch (subOp) { + switch (b) { case 246: - a = pop(); - b = pop(); - c = pop(); - d = pop(); - e = pop(); - f = pop(); - g = pop(); - h = pop(); - i = pop(); - debug(1,"o7_unknownFB case 246 stub (%d, %d, %d, %d, %d, %d, %d, %d, %d)", a, b, c, d, e, f, g, h, i); + case 248: + vert4y = pop(); + vert4x = pop(); + vert3y = pop(); + vert3x = pop(); + vert2y = pop(); + vert2x = pop(); + vert1y = pop(); + vert1x = pop(); + id = pop(); + + polygonStore(id, (b == 248), vert1x, vert1y, vert2x, vert2y, vert3x, vert3y, + vert4x, vert4y); break; case 247: - a = pop(); - b = pop(); - debug(1,"o7_unknownFB case 247 stub (%d, %d)", a, b); - break; - case 248: - a = pop(); - b = pop(); - c = pop(); - d = pop(); - e = pop(); - f = pop(); - g = pop(); - h = pop(); - i = pop(); - debug(1,"o7_unknownFB case 248 stub (%d, %d, %d, %d, %d, %d, %d, %d, %d)", a, b, c, d, e, f, g, h, i); + toId = pop(); + fromId = pop(); + + polygonErase(fromId, toId); break; - default: - error("o7_unknownFB: default case %d", subOp); } } -void ScummEngine_v7he::o7_unknownFC() { +void ScummEngine_v7he::polygonStore(int id, bool flag, int vert1x, int vert1y, int vert2x, + int vert2y, int vert3x, int vert3y, int vert4x, int vert4y) { + int i; + + debug(1, "polygonStore(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d", id, flag, vert1x, + vert1y, vert2x, vert2y, vert3x, vert3y, vert4x, vert4y); + + for (i = 0; i < _WizNumPolygons; i++) + if (_WizPolygons[i].id == 0) + break; + + if (i == _WizNumPolygons) { + error("ScummEngine_v7he::polygonStore: out of polygon slot, max = %d", + _WizNumPolygons); + } + + _WizPolygons[i].vert[0].x = vert1x; + _WizPolygons[i].vert[0].y = vert1y; + _WizPolygons[i].vert[1].x = vert2x; + _WizPolygons[i].vert[1].y = vert2y; + _WizPolygons[i].vert[2].x = vert3x; + _WizPolygons[i].vert[2].y = vert3y; + _WizPolygons[i].vert[3].x = vert4x; + _WizPolygons[i].vert[3].y = vert4y; + _WizPolygons[i].vert[4].x = vert1x; + _WizPolygons[i].vert[4].y = vert1y; + _WizPolygons[i].id = id; + _WizPolygons[i].flag = flag; + + _WizPolygons[i].bound.left = 10000; + _WizPolygons[i].bound.top = 10000; + _WizPolygons[i].bound.right = -10000; + _WizPolygons[i].bound.bottom = -10000; + + for (int j = 0; j < 4; j++) { + _WizPolygons[i].bound.left = MIN(_WizPolygons[i].bound.left, _WizPolygons[i].vert[j].x); + _WizPolygons[i].bound.top = MIN(_WizPolygons[i].bound.top, _WizPolygons[i].vert[j].y); + _WizPolygons[i].bound.right = MAX(_WizPolygons[i].bound.left, _WizPolygons[i].vert[j].x); + _WizPolygons[i].bound.bottom = MAX(_WizPolygons[i].bound.left, _WizPolygons[i].vert[j].y); + } +} + +void ScummEngine_v7he::polygonErase(int fromId, int toId) { + for (int i = 0; i < _WizNumPolygons; i++) { + if (_WizPolygons[i].id >= fromId && _WizPolygons[i].id <= toId) + memset(&_WizPolygons[i], 0, sizeof(WizPolygon)); + } +} + +void ScummEngine_v7he::o7_polygonHit() { // Checks virtual mouse x/y co-ordinates when in verb/inventory area // Maybe checks for polygons ? int y = pop(); int x = pop(); - int r = findObject(x, y); - push(r); - debug(1,"o7_unknownFC (x %d, y %d) stub", x, y); + debug(1, "o7_polygonHit(%d, %d)", x, y); + + for (int i = 0; i < _WizNumPolygons; i++) { + if (_WizPolygons[i].bound.contains(x, y)) { + if (polygonContains(_WizPolygons[i], x, y)) { + push(_WizPolygons[i].id); + return; + } + } + } + + push(0); +} + +bool ScummEngine_v7he::polygonContains(WizPolygon &pol, int x, int y) { + int pi = pol.numVerts - 1; + bool diry = (y < pol.vert[pi].y); + bool curdir; + bool r = false; + + for (int i = 0; i < pol.numVerts; i++) { + curdir = (y <= pol.vert[i].y); + + if (curdir != diry) { + if (((pol.vert[pi].y - pol.vert[i].y) * (pol.vert[i].x - x) <= + (pol.vert[pi].x - pol.vert[i].x) * (pol.vert[pi].y - y)) == diry) + r = r ? false : true; + } + + pi = i; + diry = curdir; + } + return r; } } // End of namespace Scumm diff --git a/scumm/script_v80he.cpp b/scumm/script_v80he.cpp index 84645f2605..2b0a5e33ac 100644 --- a/scumm/script_v80he.cpp +++ b/scumm/script_v80he.cpp @@ -358,9 +358,9 @@ void ScummEngine_v80he::setupOpcodes() { OPCODE(o72_unknownF8), OPCODE(o72_setFilePath), OPCODE(o72_unknownFA), - OPCODE(o7_unknownFB), + OPCODE(o7_polygonOps), /* FC */ - OPCODE(o7_unknownFC), + OPCODE(o7_polygonHit), OPCODE(o6_invalid), OPCODE(o6_invalid), OPCODE(o6_invalid), diff --git a/scumm/script_v90he.cpp b/scumm/script_v90he.cpp index c087567adb..6c9f17b954 100644 --- a/scumm/script_v90he.cpp +++ b/scumm/script_v90he.cpp @@ -358,9 +358,9 @@ void ScummEngine_v90he::setupOpcodes() { OPCODE(o72_unknownF8), OPCODE(o72_setFilePath), OPCODE(o72_unknownFA), - OPCODE(o7_unknownFB), + OPCODE(o7_polygonOps), /* FC */ - OPCODE(o7_unknownFC), + OPCODE(o7_polygonHit), OPCODE(o6_invalid), OPCODE(o6_invalid), OPCODE(o6_invalid), diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index fa62a4be26..53d2a954f0 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -679,6 +679,8 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS _costumeRenderer = NULL; _2byteFontPtr = 0; _V1_talkingActor = 0; + _WizNumPolygons = 200; // Used as constant in original + _WizPolygons = NULL; _actorClipOverride.top = 0; _actorClipOverride.bottom = 479; @@ -1391,6 +1393,13 @@ void ScummEngine::scummInit() { for (i = 0; i < 512; i++) _keyDownMap[i] = false; + if (_heversion >= 70) { + if (_WizPolygons) + free (_WizPolygons); + + _WizPolygons = (WizPolygon *)calloc(_WizNumPolygons, sizeof(WizPolygon)); + } + initScummVars(); _lastSaveTime = _system->get_msecs(); diff --git a/scumm/scumm.h b/scumm/scumm.h index b572bd6026..6bdd394735 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -320,6 +320,14 @@ struct LangIndexNode { int32 offset; }; +struct WizPolygon { + Common::Point vert[5]; + Common::Rect bound; + int id; + int numVerts; + bool flag; +}; + class ScummEngine : public Engine { friend class ScummDebugger; friend class SmushPlayer; @@ -651,6 +659,8 @@ protected: uint32 *_HEV7RoomIntOffsets; const byte *_resourceLastSearchBuf; // FIXME: need to put it to savefile? uint32 _resourceLastSearchSize; // FIXME: need to put it to savefile? + int _WizNumPolygons; + WizPolygon *_WizPolygons; void allocateArrays(); void openRoom(int room); |