aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/he
diff options
context:
space:
mode:
Diffstat (limited to 'engines/scumm/he')
-rw-r--r--engines/scumm/he/intern_he.h8
-rw-r--r--engines/scumm/he/logic/football.cpp169
-rw-r--r--engines/scumm/he/logic_he.cpp3
-rw-r--r--engines/scumm/he/logic_he.h1
-rw-r--r--engines/scumm/he/script_v100he.cpp13
-rw-r--r--engines/scumm/he/script_v60he.cpp2
-rw-r--r--engines/scumm/he/script_v90he.cpp14
-rw-r--r--engines/scumm/he/sound_he.cpp2
8 files changed, 175 insertions, 37 deletions
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index cdc5faa084..fc5e4bcdf0 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -187,6 +187,8 @@ public:
Wiz *_wiz;
+ virtual int setupStringArray(int size);
+
protected:
virtual void setupOpcodes();
@@ -201,7 +203,6 @@ protected:
virtual void clearDrawQueues();
int getStringCharWidth(byte chr);
- virtual int setupStringArray(int size);
void appendSubstring(int dst, int src, int len2, int len);
void adjustRect(Common::Rect &rect);
@@ -258,6 +259,9 @@ public:
virtual void resetScumm();
+ virtual byte *getStringAddress(ResId idx);
+ virtual int setupStringArray(int size);
+
protected:
virtual void setupOpcodes();
@@ -265,7 +269,6 @@ protected:
virtual void resetScummVars();
virtual void readArrayFromIndexFile();
- virtual byte *getStringAddress(ResId idx);
virtual void readMAXS(int blockSize);
virtual void redrawBGAreas();
@@ -280,7 +283,6 @@ protected:
void copyArray(int array1, int a1_dim2start, int a1_dim2end, int a1_dim1start, int a1_dim1end,
int array2, int a2_dim2start, int a2_dim2end, int a2_dim1start, int a2_dim1end);
void copyArrayHelper(ArrayHeader *ah, int idx2, int idx1, int len1, byte **data, int *size, int *num);
- virtual int setupStringArray(int size);
int readFileToArray(int slot, int32 size);
void writeFileFromArray(int slot, int32 resID);
diff --git a/engines/scumm/he/logic/football.cpp b/engines/scumm/he/logic/football.cpp
index f86f97eaf7..f67e07c475 100644
--- a/engines/scumm/he/logic/football.cpp
+++ b/engines/scumm/he/logic/football.cpp
@@ -20,6 +20,8 @@
*
*/
+#include "common/savefile.h"
+
#include "scumm/he/intern_he.h"
#include "scumm/he/logic_he.h"
@@ -35,16 +37,16 @@ public:
LogicHEfootball(ScummEngine_v90he *vm) : LogicHE(vm) {}
int versionID();
- int32 dispatch(int op, int numArgs, int32 *args);
-
-private:
- int op_1004(int32 *args);
- int op_1006(int32 *args);
- int op_1007(int32 *args);
- int op_1010(int32 *args);
- int op_1022(int32 *args);
- int op_1023(int32 *args);
- int op_1024(int32 *args);
+ virtual int32 dispatch(int op, int numArgs, int32 *args);
+
+protected:
+ int lineEquation3D(int32 *args);
+ virtual int translateWorldToScreen(int32 *args);
+ int fieldGoalScreenTranslation(int32 *args);
+ virtual int translateScreenToWorld(int32 *args);
+ int nextPoint(int32 *args);
+ int computePlayerBallIntercepts(int32 *args);
+ int computeTwoCircleIntercepts(int32 *args);
};
int LogicHEfootball::versionID() {
@@ -56,31 +58,31 @@ int32 LogicHEfootball::dispatch(int op, int numArgs, int32 *args) {
switch (op) {
case 1004:
- res = op_1004(args);
+ res = lineEquation3D(args);
break;
case 1006:
- res = op_1006(args);
+ res = translateWorldToScreen(args);
break;
case 1007:
- res = op_1007(args);
+ res = fieldGoalScreenTranslation(args);
break;
case 1010:
- res = op_1010(args);
+ res = translateScreenToWorld(args);
break;
case 1022:
- res = op_1022(args);
+ res = nextPoint(args);
break;
case 1023:
- res = op_1023(args);
+ res = computePlayerBallIntercepts(args);
break;
case 1024:
- res = op_1024(args);
+ res = computeTwoCircleIntercepts(args);
break;
case 8221968:
@@ -123,8 +125,8 @@ int32 LogicHEfootball::dispatch(int op, int numArgs, int32 *args) {
return res;
}
-int LogicHEfootball::op_1004(int32 *args) {
- // Identical to LogicHEsoccer::op_1004
+int LogicHEfootball::lineEquation3D(int32 *args) {
+ // Identical to soccer's 1004 opcode
double res, a2, a4, a5;
a5 = ((double)args[4] - (double)args[1]) / ((double)args[5] - (double)args[2]);
@@ -141,8 +143,8 @@ int LogicHEfootball::op_1004(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1006(int32 *args) {
- // This seems to be more or less the inverse of op_1010
+int LogicHEfootball::translateWorldToScreen(int32 *args) {
+ // This is more or less the inverse of translateScreenToWorld
const double a1 = args[1];
double res;
@@ -167,7 +169,7 @@ int LogicHEfootball::op_1006(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1007(int32 *args) {
+int LogicHEfootball::fieldGoalScreenTranslation(int32 *args) {
double res, temp;
temp = (double)args[1] * 0.32;
@@ -188,8 +190,8 @@ int LogicHEfootball::op_1007(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1010(int32 *args) {
- // This seems to be more or less the inverse of op_1006
+int LogicHEfootball::translateScreenToWorld(int32 *args) {
+ // This is more or less the inverse of translateWorldToScreen
double a1 = (640.0 - (double)args[1] - 26.0) / 1.1588235e-1;
// 2.9411764e-4 = 1/3400
@@ -205,7 +207,7 @@ int LogicHEfootball::op_1010(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1022(int32 *args) {
+int LogicHEfootball::nextPoint(int32 *args) {
double res;
double var10 = args[4] - args[1];
double var8 = args[5] - args[2];
@@ -226,7 +228,7 @@ int LogicHEfootball::op_1022(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1023(int32 *args) {
+int LogicHEfootball::computePlayerBallIntercepts(int32 *args) {
double var10, var18, var20, var28, var30, var30_;
double argf[7];
@@ -272,7 +274,8 @@ int LogicHEfootball::op_1023(int32 *args) {
return 1;
}
-int LogicHEfootball::op_1024(int32 *args) {
+int LogicHEfootball::computeTwoCircleIntercepts(int32 *args) {
+ // Looks like this was just dummied out
writeScummVar(108, 0);
writeScummVar(109, 0);
writeScummVar(110, 0);
@@ -281,8 +284,120 @@ int LogicHEfootball::op_1024(int32 *args) {
return 1;
}
+class LogicHEfootball2002 : public LogicHEfootball {
+public:
+ LogicHEfootball2002(ScummEngine_v90he *vm) : LogicHEfootball(vm) {}
+
+ int32 dispatch(int op, int numArgs, int32 *args);
+
+private:
+ int translateWorldToScreen(int32 *args);
+ int translateScreenToWorld(int32 *args);
+ int getDayOfWeek();
+ int initScreenTranslations();
+ int getPlaybookFiles(int32 *args);
+ int largestFreeBlock();
+};
+
+int32 LogicHEfootball2002::dispatch(int op, int numArgs, int32 *args) {
+ int32 res = 0;
+
+ switch (op) {
+ case 1025:
+ res = getDayOfWeek();
+ break;
+
+ case 1026:
+ res = initScreenTranslations();
+ break;
+
+ case 1027:
+ res = getPlaybookFiles(args);
+ break;
+
+ case 1028:
+ res = largestFreeBlock();
+ break;
+
+ case 1029:
+ // Clean-up off heap
+ // Dummied in the Windows U32
+ res = 1;
+ break;
+
+ case 1516:
+ // Start auto LAN game
+ break;
+
+ default:
+ res = LogicHEfootball::dispatch(op, numArgs, args);
+ break;
+ }
+
+ return res;
+}
+
+int LogicHEfootball2002::translateWorldToScreen(int32 *args) {
+ // TODO: Implement modified 2002 version
+ return LogicHEfootball::translateWorldToScreen(args);
+}
+
+int LogicHEfootball2002::translateScreenToWorld(int32 *args) {
+ // TODO: Implement modified 2002 version
+ return LogicHEfootball::translateScreenToWorld(args);
+}
+
+int LogicHEfootball2002::getDayOfWeek() {
+ // TODO: Get day of week, store in var 108
+ return 1;
+}
+
+int LogicHEfootball2002::initScreenTranslations() {
+ // TODO: Set values used by translateWorldToScreen/translateScreenToWorld
+ return 1;
+}
+
+int LogicHEfootball2002::getPlaybookFiles(int32 *args) {
+ // Get the pattern and then skip over the directory prefix ("*\" or "*:")
+ Common::String pattern = (const char *)_vm->getStringAddress(args[0] & ~0x33539000) + 2;
+
+ // Prepare a buffer to hold the file names
+ char buffer[1000];
+ buffer[0] = 0;
+
+ // Get the list of file names that match the pattern and iterate over it
+ Common::StringArray fileList = _vm->getSaveFileManager()->listSavefiles(pattern);
+
+ for (uint32 i = 0; i < fileList.size() && strlen(buffer) < 970; i++) {
+ // Isolate the base part of the filename and concatenate it to our buffer
+ Common::String fileName = Common::String(fileList[i].c_str(), fileList[i].size() - (pattern.size() - 1));
+ strcat(buffer, fileName.c_str());
+ strcat(buffer, ">"); // names separated by '>'
+ }
+
+ // Now store the result in an array
+ int array = _vm->setupStringArray(strlen(buffer));
+ strcpy((char *)_vm->getStringAddress(array), buffer);
+
+ // And store the array index in variable 108
+ writeScummVar(108, array);
+
+ return 1;
+}
+
+int LogicHEfootball2002::largestFreeBlock() {
+ // The Windows version always sets the variable to this
+ // The Mac version actually checks for the largest free block
+ writeScummVar(108, 100000000);
+ return 1;
+}
+
LogicHE *makeLogicHEfootball(ScummEngine_v90he *vm) {
return new LogicHEfootball(vm);
}
+LogicHE *makeLogicHEfootball2002(ScummEngine_v90he *vm) {
+ return new LogicHEfootball2002(vm);
+}
+
} // End of namespace Scumm
diff --git a/engines/scumm/he/logic_he.cpp b/engines/scumm/he/logic_he.cpp
index a76c393e13..0f9454ba28 100644
--- a/engines/scumm/he/logic_he.cpp
+++ b/engines/scumm/he/logic_he.cpp
@@ -87,6 +87,9 @@ LogicHE *LogicHE::makeLogicHE(ScummEngine_v90he *vm) {
case GID_FOOTBALL:
return makeLogicHEfootball(vm);
+ case GID_FOOTBALL2002:
+ return makeLogicHEfootball2002(vm);
+
case GID_SOCCER:
case GID_SOCCERMLS:
case GID_SOCCER2004:
diff --git a/engines/scumm/he/logic_he.h b/engines/scumm/he/logic_he.h
index 893dc81b87..93c0569a4f 100644
--- a/engines/scumm/he/logic_he.h
+++ b/engines/scumm/he/logic_he.h
@@ -61,6 +61,7 @@ protected:
LogicHE *makeLogicHErace(ScummEngine_v90he *vm);
LogicHE *makeLogicHEfunshop(ScummEngine_v90he *vm);
LogicHE *makeLogicHEfootball(ScummEngine_v90he *vm);
+LogicHE *makeLogicHEfootball2002(ScummEngine_v90he *vm);
LogicHE *makeLogicHEsoccer(ScummEngine_v90he *vm);
LogicHE *makeLogicHEbaseball2001(ScummEngine_v90he *vm);
LogicHE *makeLogicHEbasketball(ScummEngine_v90he *vm);
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index 56ea10f507..a2eb42214b 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -876,6 +876,7 @@ void ScummEngine_v100he::o100_floodFill() {
_floodFillParams.box.top = 0;
_floodFillParams.box.right = 639;
_floodFillParams.box.bottom = 479;
+ adjustRect(_floodFillParams.box);
break;
case 6:
_floodFillParams.y = pop();
@@ -886,6 +887,7 @@ void ScummEngine_v100he::o100_floodFill() {
_floodFillParams.box.right = pop();
_floodFillParams.box.top = pop();
_floodFillParams.box.left = pop();
+ adjustRect(_floodFillParams.box);
break;
case 20:
_floodFillParams.flags = pop();
@@ -1345,6 +1347,7 @@ void ScummEngine_v100he::o100_wizImageOps() {
_wizParams.fillColor = pop();
_wizParams.box2.top = _wizParams.box2.bottom = pop();
_wizParams.box2.left = _wizParams.box2.right = pop();
+ adjustRect(_wizParams.box2);
break;
case 135:
_wizParams.processFlags |= kWPFDstResNum;
@@ -1358,6 +1361,7 @@ void ScummEngine_v100he::o100_wizImageOps() {
_wizParams.box2.right = pop();
_wizParams.box2.top = pop();
_wizParams.box2.left = pop();
+ adjustRect(_wizParams.box2);
break;
case 137:
_wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
@@ -1365,6 +1369,7 @@ void ScummEngine_v100he::o100_wizImageOps() {
_wizParams.fillColor = pop();
_wizParams.box2.top = _wizParams.box2.bottom = pop();
_wizParams.box2.left = _wizParams.box2.right = pop();
+ adjustRect(_wizParams.box2);
break;
case 138:
_wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
@@ -1374,6 +1379,7 @@ void ScummEngine_v100he::o100_wizImageOps() {
_wizParams.box2.right = pop();
_wizParams.box2.top = pop();
_wizParams.box2.left = pop();
+ adjustRect(_wizParams.box2);
break;
default:
error("o100_wizImageOps: Unknown case %d", subOp);
@@ -2339,6 +2345,13 @@ void ScummEngine_v100he::o100_writeFile() {
}
void ScummEngine_v100he::o100_debugInput() {
+ // Backyard Baseball 2003 / Basketball / Football 2002
+ // use older o72_debugInput code
+ if (_game.heversion == 101) {
+ ScummEngine_v72he::o72_debugInput();
+ return;
+ }
+
byte subOp = fetchScriptByte();
switch (subOp) {
diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp
index dbeee567bf..5e359385b6 100644
--- a/engines/scumm/he/script_v60he.cpp
+++ b/engines/scumm/he/script_v60he.cpp
@@ -124,8 +124,6 @@ int ScummEngine_v60he::convertFilePath(byte *dst, int dstSize) {
} else if (dst[0] == '.' && dst[1] == '/') { // Game Data Path
// The default game data path is set to './' by ScummVM
r = 2;
- } else if (dst[2] == 'b' && dst[5] == 'k') { // Backyard Basketball INI
- r = 13;
} else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (Windows HE72 - HE100)
// The default save game path is set to '*/' by ScummVM
r = 2;
diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp
index 0beebdb7a1..1ea9960a18 100644
--- a/engines/scumm/he/script_v90he.cpp
+++ b/engines/scumm/he/script_v90he.cpp
@@ -244,6 +244,7 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.box2.right = pop();
_wizParams.box2.top = pop();
_wizParams.box2.left = pop();
+ adjustRect(_wizParams.box2);
break;
case 134: // HE99+
_wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
@@ -253,6 +254,7 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.box2.right = pop();
_wizParams.box2.top = pop();
_wizParams.box2.left = pop();
+ adjustRect(_wizParams.box2);
break;
case 135: // HE99+
_wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
@@ -260,6 +262,7 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.fillColor = pop();
_wizParams.box2.top = _wizParams.box2.bottom = pop();
_wizParams.box2.left = _wizParams.box2.right = pop();
+ adjustRect(_wizParams.box2);
break;
case 136: // HE99+
_wizParams.processFlags |= kWPFFillColor | kWPFClipBox2;
@@ -267,6 +270,7 @@ void ScummEngine_v90he::o90_wizImageOps() {
_wizParams.fillColor = pop();
_wizParams.box2.top = _wizParams.box2.bottom = pop();
_wizParams.box2.left = _wizParams.box2.right = pop();
+ adjustRect(_wizParams.box2);
break;
case 137: // HE99+
_wizParams.processFlags |= kWPFDstResNum;
@@ -1488,6 +1492,7 @@ void ScummEngine_v90he::o90_floodFill() {
_floodFillParams.box.top = 0;
_floodFillParams.box.right = 639;
_floodFillParams.box.bottom = 479;
+ adjustRect(_floodFillParams.box);
break;
case 65:
_floodFillParams.y = pop();
@@ -1501,6 +1506,7 @@ void ScummEngine_v90he::o90_floodFill() {
_floodFillParams.box.right = pop();
_floodFillParams.box.top = pop();
_floodFillParams.box.left = pop();
+ adjustRect(_floodFillParams.box);
break;
case 255:
floodFill(&_floodFillParams, this);
@@ -1666,7 +1672,7 @@ void ScummEngine_v90he::o90_getPolygonOverlap() {
{
Common::Rect r2;
_sprite->getSpriteBounds(args2[0], false, r2);
- Common::Rect r1(args1[0], args1[1], args1[2], args1[3]);
+ Common::Rect r1(args1[0], args1[1], args1[2] + 1, args1[3] + 1);
if (r2.isValidRect() == false) {
push(0);
break;
@@ -1711,7 +1717,7 @@ void ScummEngine_v90he::o90_getPolygonOverlap() {
{
Common::Rect r2;
_sprite->getSpriteBounds(args2[0], true, r2);
- Common::Rect r1(args1[0], args1[1], args1[2], args1[3]);
+ Common::Rect r1(args1[0], args1[1], args1[2] + 1, args1[3] + 1);
if (r2.isValidRect() == false) {
push(0);
break;
@@ -2373,8 +2379,8 @@ void ScummEngine_v90he::o90_kernelSetFunctions() {
case 2001:
_logicHE->dispatch(args[1], num - 2, (int32 *)&args[2]);
break;
- case 201102:
- // Used in puttzoo iOS
+ case 201102: // Used in puttzoo iOS
+ case 20111014: // Used in spyfox iOS
break;
default:
error("o90_kernelSetFunctions: default case %d (param count %d)", args[0], num);
diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp
index 1007d2a7b0..f94b74ac45 100644
--- a/engines/scumm/he/sound_he.cpp
+++ b/engines/scumm/he/sound_he.cpp
@@ -65,7 +65,7 @@ void SoundHE::addSoundToQueue(int sound, int heOffset, int heChannel, int heFlag
if (_vm->VAR_LAST_SOUND != 0xFF)
_vm->VAR(_vm->VAR_LAST_SOUND) = sound;
- if ((_vm->_game.heversion <= 99 && (heFlags & 16)) || (_vm->_game.heversion == 100 && (heFlags & 8))) {
+ if ((_vm->_game.heversion <= 99 && (heFlags & 16)) || (_vm->_game.heversion >= 100 && (heFlags & 8))) {
playHESound(sound, heOffset, heChannel, heFlags);
return;
} else {