aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/prince/curve_values.h45
-rw-r--r--engines/prince/prince.cpp117
-rw-r--r--engines/prince/prince.h11
-rw-r--r--engines/prince/script.cpp17
4 files changed, 157 insertions, 33 deletions
diff --git a/engines/prince/curve_values.h b/engines/prince/curve_values.h
new file mode 100644
index 0000000000..d72f11fd36
--- /dev/null
+++ b/engines/prince/curve_values.h
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+namespace Prince {
+
+const int curveValues[17][4] = {
+ { 32768, 0, 0, 0 },
+ { 25200, 7200, 480, -112 },
+ { 18816, 12544, 1792, -384 },
+ { 13520, 16224, 3744, -720 },
+ { 9216, 18432, 6144, -1024 },
+ { 5808, 19360, 8800, -1200 },
+ { 3200, 19200, 11520, -1152 },
+ { 1296, 18144, 14112, -784 },
+ { 0, 16384, 16384, 0 },
+ { -784, 14112, 18144, 1296 },
+ { -1152, 11520, 19200, 3200 },
+ { -1200, 8800, 19360, 5808 },
+ { -1024, 6144, 18432, 9216 },
+ { -720, 3744, 16224, 13520 },
+ { -384, 1792, 12544, 18816 },
+ { -112, 480, 7200, 25200 },
+ { 0, 0, 0, 32768 }
+};
+
+} // End of namespace Prince
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp
index 9ede877d0e..9e19033507 100644
--- a/engines/prince/prince.cpp
+++ b/engines/prince/prince.cpp
@@ -60,6 +60,7 @@
#include "prince/resource.h"
#include "prince/animation.h"
#include "prince/option_text.h"
+#include "prince/curve_values.h"
namespace Prince {
@@ -92,7 +93,7 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc)
_traceLineLen(0), _rembBitmapTemp(nullptr), _rembBitmap(nullptr), _rembMask(0), _rembX(0), _rembY(0), _fpX(0), _fpY(0),
_checkBitmapTemp(nullptr), _checkBitmap(nullptr), _checkMask(0), _checkX(0), _checkY(0), _traceLineFirstPointFlag(false),
_tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr),
- _shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0) {
+ _shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0), _curveData(nullptr), _curvPos(0) {
// Debug/console setup
DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel");
@@ -189,6 +190,8 @@ PrinceEngine::~PrinceEngine() {
free(_zoomBitmap);
free(_shadowBitmap);
+
+ free(_curveData);
}
GUI::Debugger *PrinceEngine::getDebugger() {
@@ -333,6 +336,8 @@ void PrinceEngine::init() {
_zoomBitmap = (byte *)malloc(kZoomBitmapLen);
_shadowBitmap = (byte *)malloc(2 * kShadowBitmapSize);
+
+ _curveData = (int16 *)malloc(2 * kCurveLen * sizeof(int16));
}
void PrinceEngine::showLogo() {
@@ -889,13 +894,9 @@ void PrinceEngine::keyHandler(Common::Event event) {
}
}
-int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobList, bool usePriorityList) {
- Common::Point mousepos = _system->getEventManager()->getMousePos();
- Common::Point mousePosCamera(mousepos.x + _picWindowX, mousepos.y);
+int PrinceEngine::getMob(Common::Array<Mob> &mobList, bool usePriorityList, int posX, int posY) {
- if (_mouseFlag == 0 || _mouseFlag == 3) {
- return -1;
- }
+ Common::Point pointPos(posX, posY);
int mobListSize;
if (usePriorityList) {
@@ -921,7 +922,7 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobLis
case 0:
case 1:
//normal_mob
- if (!mob->_rect.contains(mousePosCamera)) {
+ if (!mob->_rect.contains(pointPos)) {
continue;
}
break;
@@ -932,9 +933,9 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobLis
if (nr != 0xFF) {
Object &obj = *_objList[nr];
Common::Rect objectRect(obj._x, obj._y, obj._x + obj._width, obj._y + obj._height);
- if (objectRect.contains(mousePosCamera)) {
+ if (objectRect.contains(pointPos)) {
Graphics::Surface *objSurface = obj.getSurface();
- byte *pixel = (byte *)objSurface->getBasePtr(mousePosCamera.x - obj._x, mousePosCamera.y - obj._y);
+ byte *pixel = (byte *)objSurface->getBasePtr(posX - obj._x, posY - obj._y);
if (*pixel != 255) {
break;
}
@@ -952,14 +953,14 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobLis
if (backAnim._animData != nullptr) {
if (!backAnim._state) {
Common::Rect backAnimRect(backAnim._currX, backAnim._currY, backAnim._currX + backAnim._currW, backAnim._currY + backAnim._currH);
- if (backAnimRect.contains(mousePosCamera)) {
+ if (backAnimRect.contains(pointPos)) {
int phase = backAnim._showFrame;
int phaseFrameIndex = backAnim._animData->getPhaseFrameIndex(phase);
Graphics::Surface *backAnimSurface = backAnim._animData->getFrame(phaseFrameIndex);
- byte pixel = *(byte *)backAnimSurface->getBasePtr(mousePosCamera.x - backAnim._currX, mousePosCamera.y - backAnim._currY);
+ byte pixel = *(byte *)backAnimSurface->getBasePtr(posX - backAnim._currX, posY - backAnim._currY);
if (pixel != 255) {
if (type == 5) {
- if (mob->_rect.contains(mousePosCamera)) {
+ if (mob->_rect.contains(pointPos)) {
break;
}
} else {
@@ -978,7 +979,24 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobLis
break;
}
- Common::String mobName = mob->_name;
+ if (usePriorityList) {
+ return _mobPriorityList[mobNumber];
+ } else {
+ return mobNumber;
+ }
+ }
+ return -1;
+}
+
+int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobList, bool usePriorityList) {
+ if (_mouseFlag == 0 || _mouseFlag == 3) {
+ return -1;
+ }
+ Common::Point mousePos = _system->getEventManager()->getMousePos();
+ int mobNumber = getMob(mobList, usePriorityList, mousePos.x + _picWindowX, mousePos.y);
+
+ if (mobNumber != -1) {
+ Common::String mobName = mobList[mobNumber]._name;
if (getLanguage() == Common::DE_DEU) {
for (uint i = 0; i < mobName.size(); i++) {
@@ -1010,7 +1028,7 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobLis
uint16 textW = getTextWidth(mobName.c_str());
- uint16 x = mousepos.x - textW / 2;
+ uint16 x = mousePos.x - textW / 2;
if (x > screen->w) {
x = 0;
}
@@ -1019,20 +1037,15 @@ int PrinceEngine::checkMob(Graphics::Surface *screen, Common::Array<Mob> &mobLis
x = screen->w - textW;
}
- uint16 y = mousepos.y - _font->getFontHeight();
+ uint16 y = mousePos.y - _font->getFontHeight();
if (y > screen->h) {
y = _font->getFontHeight() - 2;
}
_font->drawString(screen, mobName, x, y, screen->w, 216);
-
- if (usePriorityList) {
- return _mobPriorityList[mobNumber];
- } else {
- return mobNumber;
- }
}
- return -1;
+
+ return mobNumber;
}
void PrinceEngine::printAt(uint32 slot, uint8 color, char *s, uint16 x, uint16 y) {
@@ -2851,6 +2864,61 @@ void PrinceEngine::freeAllNormAnims() {
}
}
+void PrinceEngine::getCurve() {
+ _flags->setFlagValue(Flags::TORX1, _curveData[_curvPos]);
+ _flags->setFlagValue(Flags::TORY1, _curveData[_curvPos + 1]);
+ _curvPos += 2;
+}
+
+void PrinceEngine::makeCurve() {
+ _curvPos = 0;
+ int x1 = _flags->getFlagValue(Flags::TORX1);
+ int y1 = _flags->getFlagValue(Flags::TORY1);
+ int x2 = _flags->getFlagValue(Flags::TORX2);
+ int y2 = _flags->getFlagValue(Flags::TORY2);
+
+ for (int i = 0; i < kCurveLen; i++) {
+ int sum1 = x1 * curveValues[i][0];
+ sum1 += (x2 + (x1 - x2) / 2) * curveValues[i][1];
+ sum1 += x2 * curveValues[i][2];
+ sum1 += x2 * curveValues[i][3];
+
+ int sum2 = y1 * curveValues[i][0];
+ sum2 += (y2 - 20) * curveValues[i][1];
+ sum2 += (y2 - 10) * curveValues[i][2];
+ sum2 += y2 * curveValues[i][3];
+
+ _curveData[i * 2] = (sum1 >> 15);
+ _curveData[i * 2 + 1] = (sum2 >> 15);
+ }
+}
+
+void PrinceEngine::mouseWeirdo() {
+ if (_mouseFlag == 3) {
+ int weirdDir = _randomSource.getRandomNumber(3);
+ Common::Point mousePos = _system->getEventManager()->getMousePos();
+ switch (weirdDir) {
+ case 0:
+ mousePos.x += kCelStep;
+ break;
+ case 1:
+ mousePos.x -= kCelStep;
+ break;
+ case 2:
+ mousePos.y += kCelStep;
+ break;
+ case 3:
+ mousePos.y -= kCelStep;
+ break;
+ }
+ mousePos.x = CLIP(mousePos.x, (int16) 0, (int16) 639);
+ _flags->setFlagValue(Flags::MXFLAG, mousePos.x);
+ mousePos.y = CLIP(mousePos.y, (int16) 0, (int16) 479);
+ _flags->setFlagValue(Flags::MYFLAG, mousePos.y);
+ _system->warpMouse(mousePos.x, mousePos.y);
+ }
+}
+
// Modified version of Graphics::drawLine() to allow breaking the loop and return value
int PrinceEngine::drawLine(int x0, int y0, int x1, int y1, int (*plotProc)(int, int, void *), void *data) {
// Bresenham's line algorithm, as described by Wikipedia
@@ -4424,6 +4492,9 @@ void PrinceEngine::mainLoop() {
return;
}
+ // for "throw a rock" mini-game
+ mouseWeirdo();
+
_interpreter->stepBg();
_interpreter->stepFg();
diff --git a/engines/prince/prince.h b/engines/prince/prince.h
index fe9379180d..0c7e68c081 100644
--- a/engines/prince/prince.h
+++ b/engines/prince/prince.h
@@ -481,6 +481,17 @@ public:
void blackPalette();
void setPalette();
+ int getMob(Common::Array<Mob> &mobList, bool usePriorityList, int posX, int posY);
+
+ // 'Throw a rock' mini-game:
+ static const int16 kCurveLen = 17;
+ static const int kCelStep = 4;
+ int16 *_curveData;
+ int _curvPos;
+ void makeCurve();
+ void getCurve();
+ void mouseWeirdo();
+
// Pathfinding
static const int16 kPathGridStep = 2;
static const int32 kPathBitmapLen = (kMaxPicHeight / kPathGridStep * kMaxPicWidth / kPathGridStep) / 8;
diff --git a/engines/prince/script.cpp b/engines/prince/script.cpp
index e0fdff1e31..91b8e50ea6 100644
--- a/engines/prince/script.cpp
+++ b/engines/prince/script.cpp
@@ -1844,26 +1844,23 @@ void Interpreter::O_OPENINVENTORY() {
debugInterpreter("O_OPENINVENTORY");
}
-// TODO
void Interpreter::O_KRZYWA() {
+ _vm->makeCurve();
debugInterpreter("O_KRZYWA");
}
-// TODO
void Interpreter::O_GETKRZYWA() {
+ _vm->getCurve();
debugInterpreter("O_GETKRZYWA");
- // _flags->setFlagValue(Flags::TORX1, krzywa[_krzywaIndex++])
- // _flags->setFlagValue(Flags::TORY1, krzywa[_krzywaIndex++])
- // Check _krzywaIndex
}
-// TODO
void Interpreter::O_GETMOB() {
Flags::Id flagId = readScriptFlagId();
- uint16 mx = readScriptFlagValue();
- uint16 my = readScriptFlagValue();
- debugInterpreter("O_GETMOB flagId %d, mx %d, my %d", flagId, mx, my);
- // check if current mob pos = (mx, my)
+ uint16 posX = readScriptFlagValue();
+ uint16 posY = readScriptFlagValue();
+ int mobNumber = _vm->getMob(_vm->_mobList, true, posX, posY);
+ _flags->setFlagValue(flagId, mobNumber + 1);
+ debugInterpreter("O_GETMOB flagId %d, posX %d, posY %d", flagId, posX, posY);
}
// Not used in game