Initial commit
This commit is contained in:
197
engines/scumm/he/logic/baseball2001.cpp
Normal file
197
engines/scumm/he/logic/baseball2001.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "scumm/he/intern_he.h"
|
||||
#ifdef USE_ENET
|
||||
#include "scumm/he/net/net_main.h"
|
||||
#ifdef USE_BASIC_NET
|
||||
#include "scumm/he/net/net_lobby.h"
|
||||
#endif
|
||||
#include "scumm/he/net/net_defines.h"
|
||||
#endif
|
||||
|
||||
#include "scumm/he/logic_he.h"
|
||||
|
||||
// DirectPlay opcodes:
|
||||
#define OP_NET_REMOTE_START_SCRIPT 1492
|
||||
#define OP_NET_QUERY_PROVIDERS 1497
|
||||
#define OP_NET_CLOSE_PROVIDER 1500
|
||||
#define OP_NET_QUERY_SESSIONS 1501
|
||||
#define OP_NET_GET_SESSION_NAME 1502
|
||||
#define OP_NET_JOIN_SESSION 1504
|
||||
#define OP_NET_END_SESSION 1505
|
||||
#define OP_NET_ADD_USER 1506
|
||||
#define OP_NET_WHO_SENT_THIS 1508
|
||||
#define OP_NET_REMOTE_SEND_ARRAY 1509
|
||||
#define OP_NET_INIT 1513
|
||||
#define OP_NET_WHO_AM_I 1510
|
||||
#define OP_NET_INIT_LAN_GAME 1515
|
||||
#define OP_NET_SET_PROVIDER_BY_NAME 1516
|
||||
|
||||
// MAIA (Updater) opcodes.
|
||||
#define OP_NET_CHECK_INTERNET_STATUS 3001
|
||||
#define OP_NET_SHUT_DOWN_MAIA 3004
|
||||
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
/**
|
||||
* Logic code for:
|
||||
* Backyard Baseball 2001
|
||||
*/
|
||||
class LogicHEbaseball2001 : public LogicHE {
|
||||
public:
|
||||
LogicHEbaseball2001(ScummEngine_v90he *vm) : LogicHE(vm) {}
|
||||
|
||||
int versionID() override;
|
||||
int startOfFrame() override;
|
||||
int32 dispatch(int op, int numArgs, int32 *args) override;
|
||||
|
||||
protected:
|
||||
#ifdef USE_ENET
|
||||
void netRemoteStartScript(int numArgs, int32 *args);
|
||||
void netRemoteSendArray(int32 *args);
|
||||
#endif
|
||||
};
|
||||
|
||||
int LogicHEbaseball2001::versionID() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEbaseball2001::startOfFrame() {
|
||||
#ifdef USE_ENET
|
||||
#ifdef USE_BASIC_NET
|
||||
_vm->_lobby->doNetworkOnceAFrame();
|
||||
#endif
|
||||
_vm->_net->doNetworkOnceAFrame(15);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 LogicHEbaseball2001::dispatch(int op, int numArgs, int32 *args) {
|
||||
#if defined(USE_ENET) && defined(USE_BASIC_NET)
|
||||
if (op > 2120 && op < 3003 && op != OP_NET_CHECK_INTERNET_STATUS)
|
||||
return _vm->_lobby->dispatch(op, numArgs, args);
|
||||
#endif
|
||||
|
||||
int res = 0;
|
||||
|
||||
switch (op) {
|
||||
case OP_NET_INIT:
|
||||
// Initialize network system, this gets called at boot up and
|
||||
// sets VAR_NETWORK_AVAILABLE (100). We just return a 1 if
|
||||
// ENet is compiled.
|
||||
#ifdef USE_ENET
|
||||
res = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
#ifdef USE_ENET
|
||||
case OP_NET_REMOTE_START_SCRIPT:
|
||||
netRemoteStartScript(numArgs, args);
|
||||
break;
|
||||
|
||||
case OP_NET_CLOSE_PROVIDER:
|
||||
_vm->_net->closeProvider();
|
||||
break;
|
||||
|
||||
case OP_NET_QUERY_SESSIONS:
|
||||
#ifdef USE_BASIC_NET
|
||||
if (_vm->_lobby->_sessionId) {
|
||||
_vm->_net->querySessions();
|
||||
// Only proceed if we've found the session
|
||||
// we're looking for.
|
||||
res = _vm->_net->ifSessionExist(_vm->_lobby->_sessionId);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OP_NET_JOIN_SESSION:
|
||||
#ifdef USE_BASIC_NET
|
||||
if (_vm->_lobby->_sessionId) {
|
||||
res = _vm->_net->joinSessionById(_vm->_lobby->_sessionId);
|
||||
if (res) {
|
||||
_vm->_net->stopQuerySessions();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OP_NET_END_SESSION:
|
||||
res = _vm->_net->endSession();
|
||||
break;
|
||||
|
||||
case OP_NET_ADD_USER:
|
||||
char userName[MAX_PLAYER_NAME];
|
||||
_vm->getStringFromArray(args[0], userName, sizeof(userName));
|
||||
res = _vm->_net->addUser(userName, userName);
|
||||
break;
|
||||
|
||||
case OP_NET_WHO_SENT_THIS:
|
||||
res = _vm->_net->whoSentThis();
|
||||
break;
|
||||
|
||||
case OP_NET_REMOTE_SEND_ARRAY:
|
||||
netRemoteSendArray(args);
|
||||
break;
|
||||
|
||||
case OP_NET_WHO_AM_I:
|
||||
res = _vm->_net->whoAmI();
|
||||
break;
|
||||
#endif // USE_ENET
|
||||
|
||||
case OP_NET_CHECK_INTERNET_STATUS:
|
||||
#if defined(USE_ENET) && defined(USE_BASIC_NET)
|
||||
// We can only use the lobby system if both
|
||||
// libcurl (for lobby communication) and
|
||||
// ENet (for gameplay communication) is enabled.
|
||||
|
||||
// TODO: Actually check if we're connected to the
|
||||
// Internet.
|
||||
res = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OP_NET_SHUT_DOWN_MAIA:
|
||||
break;
|
||||
|
||||
default:
|
||||
LogicHE::dispatch(op, numArgs, args);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef USE_ENET
|
||||
void LogicHEbaseball2001::netRemoteStartScript(int numArgs, int32 *args) {
|
||||
_vm->_net->remoteStartScript(args[0], args[1], args[2], numArgs - 3, &args[3]);
|
||||
}
|
||||
|
||||
void LogicHEbaseball2001::netRemoteSendArray(int32 *args) {
|
||||
_vm->_net->remoteSendArray(args[0], args[1], args[2], args[3]);
|
||||
}
|
||||
#endif // USE_ENET
|
||||
|
||||
LogicHE *makeLogicHEbaseball2001(ScummEngine_v90he *vm) {
|
||||
return new LogicHEbaseball2001(vm);
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
675
engines/scumm/he/logic/basketball_logic.cpp
Normal file
675
engines/scumm/he/logic/basketball_logic.cpp
Normal file
@@ -0,0 +1,675 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "scumm/he/intern_he.h"
|
||||
#include "scumm/he/logic_he.h"
|
||||
#include "scumm/he/basketball/basketball.h"
|
||||
#include "scumm/he/basketball/collision/bball_collision.h"
|
||||
#include "scumm/he/basketball/geo_translations.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
// Opcodes
|
||||
#define WORLD_TO_SCREEN_TRANSLATION 1006
|
||||
#define WORLD_TO_SCREEN_TRANSLATION_PARAMS 3
|
||||
#define SCREEN_TO_WORLD_TRANSLATION 1010
|
||||
#define SCREEN_TO_WORLD_TRANSLATION_PARAMS 2
|
||||
#define INIT_SCREEN_TRANSLATIONS 1011
|
||||
#define INIT_SCREEN_TRANSLATIONS_PARAMS 0
|
||||
#define GET_COURT_DIMENSIONS 1012
|
||||
#define GET_COURT_DIMENSIONS_PARAMS 0
|
||||
|
||||
#define COMPUTE_INITIAL_SHOT_VELOCITY 1030
|
||||
#define COMPUTE_INITIAL_SHOT_VELOCITY_PARAMS 4
|
||||
#define COMPUTE_TRAJECTORY_TO_TARGET 1031
|
||||
#define COMPUTE_TRAJECTORY_TO_TARGET_PARAMS 7
|
||||
#define COMPUTE_LAUNCH_TRAJECTORY 1032
|
||||
#define COMPUTE_LAUNCH_TRAJECTORY_PARAMS 6
|
||||
#define COMPUTE_ANGLE_OF_SHOT 1033
|
||||
#define COMPUTE_ANGLE_OF_SHOT_PARAMS 2
|
||||
#define COMPUTE_ANGLE_OF_PASS 1034
|
||||
#define COMPUTE_ANGLE_OF_PASS_PARAMS 4
|
||||
#define COMPUTE_POINTS_FOR_PIXELS 1035
|
||||
#define COMPUTE_POINTS_FOR_PIXELS_PARAMS 2
|
||||
#define COMPUTE_ANGLE_OF_BOUNCE_PASS 1036
|
||||
#define COMPUTE_ANGLE_OF_BOUNCE_PASS_PARAMS 5
|
||||
#define COMPUTE_BANK_SHOT_TARGET 1037
|
||||
#define COMPUTE_BANK_SHOT_TARGET_PARAMS 4
|
||||
#define COMPUTE_SWOOSH_TARGET 1038
|
||||
#define COMPUTE_SWOOSH_TARGET_PARAMS 4
|
||||
#define DETECT_SHOT_MADE 1039
|
||||
#define DETECT_SHOT_MADE_PARAMS 9
|
||||
#define COMPUTE_ANGLE_BETWEEN_VECTORS 1040
|
||||
#define COMPUTE_ANGLE_BETWEEN_VECTORS_PARAMS 6
|
||||
#define HIT_MOVING_TARGET 1041
|
||||
#define HIT_MOVING_TARGET_PARAMS 7
|
||||
#define GET_PASS_TARGET 1042
|
||||
#define GET_PASS_TARGET_PARAMS 3
|
||||
#define DETECT_PASS_BLOCKER 1043
|
||||
#define DETECT_PASS_BLOCKER_PARAMS 3
|
||||
#define GET_BALL_INTERCEPT 1044
|
||||
#define GET_BALL_INTERCEPT_PARAMS 4
|
||||
|
||||
#define INIT_COURT 1050
|
||||
#define INIT_COURT_PARAMS 1
|
||||
#define INIT_BALL 1051
|
||||
#define INIT_BALL_PARAMS 8
|
||||
#define INIT_PLAYER 1052
|
||||
#define INIT_PLAYER_PARAMS 7
|
||||
#define DEINIT_COURT 1053
|
||||
#define DEINIT_COURT_PARAMS 0
|
||||
#define DEINIT_BALL 1054
|
||||
#define DEINIT_BALL_PARAMS 0
|
||||
#define DEINIT_PLAYER 1055
|
||||
#define DEINIT_PLAYER_PARAMS 1
|
||||
#define DETECT_BALL_COLLISION 1056
|
||||
#define DETECT_BALL_COLLISION_PARAMS 8
|
||||
#define DETECT_PLAYER_COLLISION 1057
|
||||
#define DETECT_PLAYER_COLLISION_PARAMS 8
|
||||
#define GET_LAST_BALL_COLLISION 1058
|
||||
#define GET_LAST_BALL_COLLISION_PARAMS 1
|
||||
#define GET_LAST_PLAYER_COLLISION 1059
|
||||
#define GET_LAST_PLAYER_COLLISION_PARAMS 1
|
||||
#define INIT_VIRTUAL_BALL 1060
|
||||
#define INIT_VIRTUAL_BALL_PARAMS 8
|
||||
#define DEINIT_VIRTUAL_BALL 1061
|
||||
#define DEINIT_VIRTUAL_BALL_PARAMS 0
|
||||
#define PLAYER_OFF 1062
|
||||
#define PLAYER_OFF_PARAMS 1
|
||||
#define PLAYER_ON 1063
|
||||
#define PLAYER_ON_PARAMS 1
|
||||
#define RAISE_SHIELDS 1064
|
||||
#define RAISE_SHIELDS_PARAMS 1
|
||||
#define LOWER_SHIELDS 1065
|
||||
#define LOWER_SHIELDS_PARAMS 1
|
||||
#define FIND_PLAYER_CLOSEST_TO_BALL 1066
|
||||
#define FIND_PLAYER_CLOSEST_TO_BALL_PARAMS 1
|
||||
#define IS_PLAYER_IN_BOUNDS 1067
|
||||
#define IS_PLAYER_IN_BOUNDS_PARAMS 1
|
||||
#define ARE_SHIELDS_CLEAR 1068
|
||||
#define ARE_SHIELDS_CLEAR_PARAMS 0
|
||||
#define SHIELD_PLAYER 1069
|
||||
#define SHIELD_PLAYER_PARAMS 2
|
||||
#define CLEAR_PLAYER_SHIELD 1070
|
||||
#define CLEAR_PLAYER_SHIELD_PARAMS 1
|
||||
#define IS_BALL_IN_BOUNDS 1071
|
||||
#define IS_BALL_IN_BOUNDS_PARAMS 0
|
||||
#define GET_AVOIDANCE_PATH 1072
|
||||
#define GET_AVOIDANCE_PATH_PARAMS 4
|
||||
#define SET_BALL_LOCATION 1073
|
||||
#define SET_BALL_LOCATION_PARAMS 4
|
||||
#define GET_BALL_LOCATION 1074
|
||||
#define GET_BALL_LOCATION_PARAMS 1
|
||||
#define SET_PLAYER_LOCATION 1075
|
||||
#define SET_PLAYER_LOCATION_PARAMS 4
|
||||
#define GET_PLAYER_LOCATION 1076
|
||||
#define GET_PLAYER_LOCATION_PARAMS 1
|
||||
#define START_BLOCK 1077
|
||||
#define START_BLOCK_PARAMS 3
|
||||
#define HOLD_BLOCK 1078
|
||||
#define HOLD_BLOCK_PARAMS 1
|
||||
#define END_BLOCK 1079
|
||||
#define END_BLOCK_PARAMS 1
|
||||
#define IS_PLAYER_IN_GAME 1080
|
||||
#define IS_PLAYER_IN_GAME_PARAMS 1
|
||||
#define IS_BALL_IN_GAME 1081
|
||||
#define IS_BALL_IN_GAME_PARAMS 1
|
||||
|
||||
#define UPDATE_CURSOR_POS 1090
|
||||
#define UPDATE_CURSOR_POS_PARAMS 2
|
||||
#define MAKE_CURSOR_STICKY 1091
|
||||
#define MAKE_CURSOR_STICKY_PARAMS 2
|
||||
#define CURSOR_TRACK_MOVING_OBJECT 1092
|
||||
#define CURSOR_TRACK_MOVING_OBJECT_PARAMS 2
|
||||
#define GET_CURSOR_POSITION 1093
|
||||
#define GET_CURSOR_POSITION_PARAMS 0
|
||||
|
||||
#define AI_GET_OPEN_SPOT 1100
|
||||
#define AI_GET_OPEN_SPOT_PARAMS 10
|
||||
#define AI_GET_OPPONENTS_IN_CONE 1101
|
||||
#define AI_GET_OPPONENTS_IN_CONE_PARAMS 6
|
||||
|
||||
#define U32_CLEAN_UP_OFF_HEAP 1102
|
||||
#define U32_CLEAN_UP_OFF_HEAP_PARAMS 0
|
||||
|
||||
#define DRAW_DEBUG_LINES 1500
|
||||
#define DRAW_DEBUG_LINES_PARAMS 0
|
||||
|
||||
#define ADD_DEBUG_GEOM 1501
|
||||
|
||||
int LogicHEBasketball::versionID() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32 LogicHEBasketball::dispatch(int cmdID, int paramCount, int32 *params) {
|
||||
U32FltPoint3D flt3DPoint1, flt3DPoint2;
|
||||
U32FltPoint2D flt2DPoint1, flt2DPoint2;
|
||||
U32IntVector3D int3DVector1;
|
||||
U32FltVector3D flt3DVector1, flt3DVector2;
|
||||
U32FltVector2D flt2DVector1;
|
||||
U32Sphere sphere1;
|
||||
|
||||
int retValue = 0;
|
||||
|
||||
switch (cmdID) {
|
||||
|
||||
case INIT_SCREEN_TRANSLATIONS:
|
||||
assert(paramCount == INIT_SCREEN_TRANSLATIONS_PARAMS);
|
||||
|
||||
retValue = u32_userInitScreenTranslations();
|
||||
break;
|
||||
|
||||
case WORLD_TO_SCREEN_TRANSLATION:
|
||||
assert(paramCount == WORLD_TO_SCREEN_TRANSLATION_PARAMS);
|
||||
|
||||
flt3DPoint1.x = (float)params[0];
|
||||
flt3DPoint1.y = (float)params[1];
|
||||
flt3DPoint1.z = (float)params[2];
|
||||
|
||||
retValue = u32_userWorldToScreenTranslation(flt3DPoint1);
|
||||
break;
|
||||
|
||||
case SCREEN_TO_WORLD_TRANSLATION:
|
||||
assert(paramCount == SCREEN_TO_WORLD_TRANSLATION_PARAMS);
|
||||
|
||||
flt2DPoint1.x = (float)params[0];
|
||||
flt2DPoint1.y = (float)params[1];
|
||||
|
||||
retValue = u32_userScreenToWorldTranslation(flt2DPoint1);
|
||||
break;
|
||||
|
||||
case GET_COURT_DIMENSIONS:
|
||||
assert(paramCount == GET_COURT_DIMENSIONS_PARAMS);
|
||||
|
||||
retValue = u32_userGetCourtDimensions();
|
||||
break;
|
||||
|
||||
case COMPUTE_TRAJECTORY_TO_TARGET:
|
||||
assert(paramCount == COMPUTE_TRAJECTORY_TO_TARGET_PARAMS);
|
||||
|
||||
flt3DPoint1.x = (float)params[0];
|
||||
flt3DPoint1.y = (float)params[1];
|
||||
flt3DPoint1.z = (float)params[2];
|
||||
|
||||
flt3DPoint2.x = (float)params[3];
|
||||
flt3DPoint2.y = (float)params[4];
|
||||
flt3DPoint2.z = (float)params[5];
|
||||
|
||||
retValue = u32_userComputeTrajectoryToTarget(flt3DPoint1, flt3DPoint2, params[6]);
|
||||
break;
|
||||
|
||||
case COMPUTE_LAUNCH_TRAJECTORY:
|
||||
assert(paramCount == COMPUTE_LAUNCH_TRAJECTORY_PARAMS);
|
||||
|
||||
flt2DPoint1.x = (float)params[0];
|
||||
flt2DPoint1.y = (float)params[1];
|
||||
|
||||
flt2DPoint2.x = (float)params[2];
|
||||
flt2DPoint2.y = (float)params[3];
|
||||
|
||||
retValue = u32_userComputeLaunchTrajectory(flt2DPoint1, flt2DPoint2, params[4], params[5]);
|
||||
break;
|
||||
|
||||
case COMPUTE_ANGLE_BETWEEN_VECTORS:
|
||||
assert(paramCount == COMPUTE_ANGLE_BETWEEN_VECTORS_PARAMS);
|
||||
|
||||
flt3DVector1.x = (float)params[0];
|
||||
flt3DVector1.y = (float)params[1];
|
||||
flt3DVector1.z = (float)params[2];
|
||||
|
||||
flt3DVector2.x = (float)params[3];
|
||||
flt3DVector2.y = (float)params[4];
|
||||
flt3DVector2.z = (float)params[5];
|
||||
|
||||
retValue = u32_userComputeAngleBetweenVectors(flt3DVector1, flt3DVector2);
|
||||
break;
|
||||
|
||||
case COMPUTE_INITIAL_SHOT_VELOCITY:
|
||||
assert(paramCount == COMPUTE_INITIAL_SHOT_VELOCITY_PARAMS);
|
||||
retValue = u32_userComputeInitialShotVelocity(params[0], params[1], params[2], params[3]);
|
||||
break;
|
||||
|
||||
case COMPUTE_ANGLE_OF_SHOT:
|
||||
assert(paramCount == COMPUTE_ANGLE_OF_SHOT_PARAMS);
|
||||
retValue = u32_userComputeAngleOfShot(params[0], params[1]);
|
||||
break;
|
||||
|
||||
case COMPUTE_ANGLE_OF_PASS:
|
||||
assert(paramCount == COMPUTE_ANGLE_OF_PASS_PARAMS);
|
||||
retValue = u32_userComputeAngleOfPass(params[0], params[1], params[2], params[3]);
|
||||
break;
|
||||
|
||||
case COMPUTE_ANGLE_OF_BOUNCE_PASS:
|
||||
assert(paramCount == COMPUTE_ANGLE_OF_BOUNCE_PASS_PARAMS);
|
||||
retValue = u32_userComputeAngleOfBouncePass(params[0], params[1], params[2], params[3], params[4]);
|
||||
break;
|
||||
|
||||
case HIT_MOVING_TARGET:
|
||||
assert(paramCount == HIT_MOVING_TARGET_PARAMS);
|
||||
|
||||
flt2DPoint1.x = (float)params[0];
|
||||
flt2DPoint1.y = (float)params[1];
|
||||
flt2DPoint2.x = (float)params[2];
|
||||
flt2DPoint2.y = (float)params[3];
|
||||
flt2DVector1.x = (float)params[4];
|
||||
flt2DVector1.y = (float)params[5];
|
||||
|
||||
retValue = u32_userHitMovingTarget(flt2DPoint1, flt2DPoint2, flt2DVector1, params[6]);
|
||||
break;
|
||||
|
||||
case GET_PASS_TARGET:
|
||||
assert(paramCount == GET_PASS_TARGET_PARAMS);
|
||||
|
||||
flt3DVector1.x = (float)params[1];
|
||||
flt3DVector1.y = (float)params[2];
|
||||
|
||||
retValue = u32_userGetPassTarget(params[0], flt3DVector1);
|
||||
break;
|
||||
|
||||
case DETECT_PASS_BLOCKER:
|
||||
assert(paramCount == DETECT_PASS_BLOCKER_PARAMS);
|
||||
|
||||
flt3DVector1.x = (float)params[1];
|
||||
flt3DVector1.y = (float)params[2];
|
||||
|
||||
retValue = u32_userDetectPassBlocker(params[0], flt3DVector1);
|
||||
break;
|
||||
|
||||
case GET_BALL_INTERCEPT:
|
||||
assert(paramCount == GET_BALL_INTERCEPT_PARAMS);
|
||||
|
||||
retValue = u32_userGetBallIntercept(params[0], params[1], params[2], params[3]);
|
||||
break;
|
||||
|
||||
case COMPUTE_POINTS_FOR_PIXELS:
|
||||
assert(paramCount == COMPUTE_POINTS_FOR_PIXELS_PARAMS);
|
||||
retValue = u32_userComputePointsForPixels(params[0], params[1]);
|
||||
break;
|
||||
|
||||
case COMPUTE_BANK_SHOT_TARGET:
|
||||
assert(paramCount == COMPUTE_BANK_SHOT_TARGET_PARAMS);
|
||||
|
||||
flt3DPoint1.x = (float)params[0];
|
||||
flt3DPoint1.y = (float)params[1];
|
||||
flt3DPoint1.z = (float)params[2];
|
||||
|
||||
retValue = u32_userComputeBankShotTarget(flt3DPoint1, params[3]);
|
||||
break;
|
||||
|
||||
case COMPUTE_SWOOSH_TARGET:
|
||||
assert(paramCount == COMPUTE_SWOOSH_TARGET_PARAMS);
|
||||
|
||||
flt3DPoint1.x = (float)params[0];
|
||||
flt3DPoint1.y = (float)params[1];
|
||||
flt3DPoint1.z = (float)params[2];
|
||||
|
||||
retValue = u32_userComputeSwooshTarget(flt3DPoint1, params[3]);
|
||||
break;
|
||||
|
||||
case INIT_COURT:
|
||||
assert(paramCount == INIT_COURT_PARAMS);
|
||||
retValue = u32_userInitCourt(params[0]);
|
||||
break;
|
||||
|
||||
case DEINIT_COURT:
|
||||
assert(paramCount == DEINIT_COURT_PARAMS);
|
||||
retValue = u32_userDeinitCourt();
|
||||
break;
|
||||
|
||||
case INIT_BALL:
|
||||
assert(paramCount == INIT_BALL_PARAMS);
|
||||
|
||||
flt3DPoint1.x = (float)params[0];
|
||||
flt3DPoint1.y = (float)params[1];
|
||||
flt3DPoint1.z = (float)params[2];
|
||||
|
||||
flt3DVector1.x = (float)params[3];
|
||||
flt3DVector1.y = (float)params[4];
|
||||
flt3DVector1.z = (float)params[5];
|
||||
|
||||
|
||||
retValue = u32_userInitBall(flt3DPoint1, flt3DVector1, params[6], params[7]);
|
||||
break;
|
||||
|
||||
case DEINIT_BALL:
|
||||
assert(paramCount == DEINIT_BALL_PARAMS);
|
||||
|
||||
retValue = u32_userDeinitBall();
|
||||
break;
|
||||
|
||||
case INIT_VIRTUAL_BALL:
|
||||
assert(paramCount == INIT_VIRTUAL_BALL_PARAMS);
|
||||
|
||||
flt3DPoint1.x = (float)params[0];
|
||||
flt3DPoint1.y = (float)params[1];
|
||||
flt3DPoint1.z = (float)params[2];
|
||||
|
||||
flt3DVector1.x = (float)params[3];
|
||||
flt3DVector1.y = (float)params[4];
|
||||
flt3DVector1.z = (float)params[5];
|
||||
|
||||
retValue = u32_userInitVirtualBall(flt3DPoint1, flt3DVector1, params[6], params[7]);
|
||||
break;
|
||||
|
||||
case DEINIT_VIRTUAL_BALL:
|
||||
assert(paramCount == DEINIT_VIRTUAL_BALL_PARAMS);
|
||||
|
||||
retValue = u32_userDeinitVirtualBall();
|
||||
break;
|
||||
|
||||
case INIT_PLAYER:
|
||||
assert(paramCount == INIT_PLAYER_PARAMS);
|
||||
|
||||
flt3DPoint1.x = (float)params[1];
|
||||
flt3DPoint1.y = (float)params[2];
|
||||
flt3DPoint1.z = (float)params[3];
|
||||
|
||||
retValue = u32_userInitPlayer(params[0], flt3DPoint1, params[4], params[5], (params[6] != 0));
|
||||
break;
|
||||
|
||||
case DEINIT_PLAYER:
|
||||
assert(paramCount == DEINIT_PLAYER_PARAMS);
|
||||
retValue = u32_userDeinitPlayer(params[0]);
|
||||
break;
|
||||
|
||||
case PLAYER_OFF:
|
||||
assert(paramCount == PLAYER_OFF_PARAMS);
|
||||
retValue = u32_userPlayerOff(params[0]);
|
||||
break;
|
||||
|
||||
case PLAYER_ON:
|
||||
assert(paramCount == PLAYER_ON_PARAMS);
|
||||
retValue = u32_userPlayerOn(params[0]);
|
||||
break;
|
||||
|
||||
case SET_BALL_LOCATION:
|
||||
assert(paramCount == SET_BALL_LOCATION_PARAMS);
|
||||
|
||||
flt3DPoint1.x = (float)params[0];
|
||||
flt3DPoint1.y = (float)params[1];
|
||||
flt3DPoint1.z = (float)params[2];
|
||||
|
||||
|
||||
_vm->_basketball->_court->getBallPtr(params[3])->center = flt3DPoint1;
|
||||
|
||||
retValue = 1;
|
||||
break;
|
||||
|
||||
case GET_BALL_LOCATION:
|
||||
assert(paramCount == GET_BALL_LOCATION_PARAMS);
|
||||
|
||||
flt3DPoint1 = _vm->_basketball->_court->getBallPtr(params[0])->center;
|
||||
|
||||
writeScummVar(_vm1->VAR_U32_USER_VAR_A, _vm->_basketball->u32FloatToInt(flt3DPoint1.x));
|
||||
writeScummVar(_vm1->VAR_U32_USER_VAR_B, _vm->_basketball->u32FloatToInt(flt3DPoint1.y));
|
||||
writeScummVar(_vm1->VAR_U32_USER_VAR_C, _vm->_basketball->u32FloatToInt(flt3DPoint1.z));
|
||||
|
||||
retValue = 1;
|
||||
break;
|
||||
|
||||
case SET_PLAYER_LOCATION:
|
||||
assert(paramCount == SET_PLAYER_LOCATION_PARAMS);
|
||||
|
||||
flt3DPoint1.x = (float)params[0];
|
||||
flt3DPoint1.y = (float)params[1];
|
||||
flt3DPoint1.z = (float)params[2];
|
||||
|
||||
flt3DPoint1.z += (_vm->_basketball->_court->getPlayerPtr(params[3])->height / 2);
|
||||
_vm->_basketball->_court->getPlayerPtr(params[3])->center = flt3DPoint1;
|
||||
|
||||
retValue = 1;
|
||||
break;
|
||||
|
||||
case GET_PLAYER_LOCATION:
|
||||
assert(paramCount == GET_PLAYER_LOCATION_PARAMS);
|
||||
|
||||
flt3DPoint1 = _vm->_basketball->_court->getPlayerPtr(params[0])->center;
|
||||
flt3DPoint1.z -= (_vm->_basketball->_court->getPlayerPtr(params[0])->height / 2);
|
||||
|
||||
writeScummVar(_vm1->VAR_U32_USER_VAR_A, _vm->_basketball->u32FloatToInt(flt3DPoint1.x));
|
||||
writeScummVar(_vm1->VAR_U32_USER_VAR_B, _vm->_basketball->u32FloatToInt(flt3DPoint1.y));
|
||||
writeScummVar(_vm1->VAR_U32_USER_VAR_C, _vm->_basketball->u32FloatToInt(flt3DPoint1.z));
|
||||
|
||||
retValue = 1;
|
||||
break;
|
||||
|
||||
case DETECT_BALL_COLLISION:
|
||||
assert(paramCount == DETECT_BALL_COLLISION_PARAMS);
|
||||
|
||||
flt3DPoint1.x = (float)params[0];
|
||||
flt3DPoint1.y = (float)params[1];
|
||||
flt3DPoint1.z = (float)params[2];
|
||||
|
||||
flt3DVector1.x = (float)params[3];
|
||||
flt3DVector1.y = (float)params[4];
|
||||
flt3DVector1.z = (float)params[5];
|
||||
|
||||
retValue = u32_userDetectBallCollision(flt3DPoint1, flt3DVector1, params[6], params[7]);
|
||||
break;
|
||||
|
||||
case DETECT_PLAYER_COLLISION:
|
||||
assert(paramCount == DETECT_PLAYER_COLLISION_PARAMS);
|
||||
|
||||
flt3DPoint1.x = (float)params[1];
|
||||
flt3DPoint1.y = (float)params[2];
|
||||
flt3DPoint1.z = (float)params[3];
|
||||
|
||||
flt3DVector1.x = (float)params[4];
|
||||
flt3DVector1.y = (float)params[5];
|
||||
flt3DVector1.z = (float)params[6];
|
||||
|
||||
retValue = u32_userDetectPlayerCollision(params[0], flt3DPoint1, flt3DVector1, (params[7] != 0));
|
||||
break;
|
||||
|
||||
case GET_LAST_BALL_COLLISION:
|
||||
assert(paramCount == GET_LAST_BALL_COLLISION_PARAMS);
|
||||
|
||||
retValue = u32_userGetLastBallCollision(params[0]);
|
||||
break;
|
||||
|
||||
case GET_LAST_PLAYER_COLLISION:
|
||||
assert(paramCount == GET_LAST_PLAYER_COLLISION_PARAMS);
|
||||
|
||||
retValue = u32_userGetLastPlayerCollision(params[0]);
|
||||
break;
|
||||
|
||||
case DETECT_SHOT_MADE:
|
||||
assert(paramCount == DETECT_SHOT_MADE_PARAMS);
|
||||
|
||||
sphere1.center.x = (float)params[0];
|
||||
sphere1.center.y = (float)params[1];
|
||||
sphere1.center.z = (float)params[2];
|
||||
sphere1.radius = (float)params[6];
|
||||
|
||||
int3DVector1.x = params[3];
|
||||
int3DVector1.y = params[4];
|
||||
int3DVector1.z = params[5];
|
||||
|
||||
retValue = u32_userDetectShotMade(sphere1, int3DVector1, params[7], params[8]);
|
||||
break;
|
||||
|
||||
case RAISE_SHIELDS:
|
||||
assert(paramCount == RAISE_SHIELDS_PARAMS);
|
||||
|
||||
retValue = u32_userRaiseShields(params[0]);
|
||||
break;
|
||||
|
||||
case LOWER_SHIELDS:
|
||||
assert(paramCount == LOWER_SHIELDS_PARAMS);
|
||||
|
||||
retValue = u32_userLowerShields(params[0]);
|
||||
break;
|
||||
|
||||
case FIND_PLAYER_CLOSEST_TO_BALL:
|
||||
assert((paramCount == 0) || (paramCount == FIND_PLAYER_CLOSEST_TO_BALL_PARAMS));
|
||||
|
||||
if (paramCount == 0) {
|
||||
retValue = u32_userGetPlayerClosestToBall();
|
||||
} else {
|
||||
retValue = u32_userGetPlayerClosestToBall(params[0]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case IS_PLAYER_IN_BOUNDS:
|
||||
assert(paramCount == IS_PLAYER_IN_BOUNDS_PARAMS);
|
||||
|
||||
retValue = u32_userIsPlayerInBounds(params[0]);
|
||||
break;
|
||||
|
||||
case IS_BALL_IN_BOUNDS:
|
||||
assert(paramCount == IS_BALL_IN_BOUNDS_PARAMS);
|
||||
|
||||
retValue = u32_userIsBallInBounds();
|
||||
break;
|
||||
|
||||
case ARE_SHIELDS_CLEAR:
|
||||
assert(paramCount == ARE_SHIELDS_CLEAR_PARAMS);
|
||||
|
||||
retValue = u32_userAreShieldsClear();
|
||||
break;
|
||||
|
||||
case SHIELD_PLAYER:
|
||||
assert(paramCount == SHIELD_PLAYER_PARAMS);
|
||||
|
||||
retValue = u32_userShieldPlayer(params[0], params[1]);
|
||||
break;
|
||||
|
||||
case CLEAR_PLAYER_SHIELD:
|
||||
assert(paramCount == CLEAR_PLAYER_SHIELD_PARAMS);
|
||||
|
||||
retValue = u32_userClearPlayerShield(params[0]);
|
||||
break;
|
||||
|
||||
case GET_AVOIDANCE_PATH:
|
||||
assert(paramCount == GET_AVOIDANCE_PATH_PARAMS);
|
||||
|
||||
flt2DPoint1.x = (float)params[1];
|
||||
flt2DPoint1.y = (float)params[2];
|
||||
|
||||
retValue = u32_userGetAvoidancePath(params[0], flt2DPoint1, (EAvoidanceType)params[3]);
|
||||
break;
|
||||
|
||||
case START_BLOCK:
|
||||
assert(paramCount == START_BLOCK_PARAMS);
|
||||
assert((FIRST_PLAYER <= params[0]) && (params[0] <= LAST_PLAYER));
|
||||
|
||||
(_vm->_basketball->_court->getPlayerPtr(params[0]))->startBlocking(params[1], params[2]);
|
||||
|
||||
retValue = 1;
|
||||
break;
|
||||
|
||||
case HOLD_BLOCK:
|
||||
assert(paramCount == HOLD_BLOCK_PARAMS);
|
||||
assert((FIRST_PLAYER <= params[0]) && (params[0] <= LAST_PLAYER));
|
||||
|
||||
(_vm->_basketball->_court->getPlayerPtr(params[0]))->holdBlocking();
|
||||
|
||||
retValue = 1;
|
||||
break;
|
||||
|
||||
case END_BLOCK:
|
||||
assert(paramCount == END_BLOCK_PARAMS);
|
||||
assert((FIRST_PLAYER <= params[0]) && (params[0] <= LAST_PLAYER));
|
||||
|
||||
(_vm->_basketball->_court->getPlayerPtr(params[0]))->endBlocking();
|
||||
|
||||
retValue = 1;
|
||||
break;
|
||||
|
||||
case IS_PLAYER_IN_GAME:
|
||||
assert(paramCount == IS_PLAYER_IN_GAME_PARAMS);
|
||||
assert((FIRST_PLAYER <= params[0]) && (params[0] <= LAST_PLAYER));
|
||||
|
||||
writeScummVar(_vm1->VAR_U32_USER_VAR_A, ((_vm->_basketball->_court->getPlayerPtr(params[0]))->_playerIsInGame) ? 1 : 0);
|
||||
|
||||
retValue = 1;
|
||||
break;
|
||||
|
||||
case IS_BALL_IN_GAME:
|
||||
assert(paramCount == IS_BALL_IN_GAME_PARAMS);
|
||||
|
||||
writeScummVar(_vm1->VAR_U32_USER_VAR_A, ((_vm->_basketball->_court->getBallPtr(params[0]))->_ignore) ? 0 : 1);
|
||||
|
||||
retValue = 1;
|
||||
break;
|
||||
|
||||
case UPDATE_CURSOR_POS:
|
||||
assert(paramCount == UPDATE_CURSOR_POS_PARAMS);
|
||||
|
||||
retValue = u32_userUpdateCursorPos(params[0], params[1]);
|
||||
break;
|
||||
|
||||
case MAKE_CURSOR_STICKY:
|
||||
assert(paramCount == MAKE_CURSOR_STICKY_PARAMS);
|
||||
|
||||
retValue = u32_userMakeCursorSticky(params[0], params[1]);
|
||||
break;
|
||||
|
||||
case CURSOR_TRACK_MOVING_OBJECT:
|
||||
assert(paramCount == CURSOR_TRACK_MOVING_OBJECT_PARAMS);
|
||||
|
||||
retValue = u32_userCursorTrackMovingObject(params[0], params[1]);
|
||||
break;
|
||||
|
||||
case GET_CURSOR_POSITION:
|
||||
assert(paramCount == GET_CURSOR_POSITION_PARAMS);
|
||||
|
||||
retValue = u32_userGetCursorPos();
|
||||
break;
|
||||
|
||||
case AI_GET_OPEN_SPOT:
|
||||
assert(paramCount == AI_GET_OPEN_SPOT_PARAMS);
|
||||
retValue = u32_userGetOpenSpot(
|
||||
params[0],
|
||||
U32FltVector2D((float)params[1], (float)params[2]),
|
||||
U32FltVector2D((float)params[3], (float)params[4]),
|
||||
U32FltVector2D((float)params[5], (float)params[6]),
|
||||
(params[7] != 0),
|
||||
U32FltVector2D((float)params[8], (float)params[9]));
|
||||
break;
|
||||
|
||||
case AI_GET_OPPONENTS_IN_CONE:
|
||||
assert(paramCount == AI_GET_OPPONENTS_IN_CONE_PARAMS);
|
||||
retValue = _vm->_basketball->numOpponentsInCone(
|
||||
params[0],
|
||||
(((float)params[1]) / 65536),
|
||||
U32FltVector2D((float)params[2], (float)params[3]),
|
||||
U32FltVector2D((float)params[4], (float)params[5]));
|
||||
break;
|
||||
|
||||
case U32_CLEAN_UP_OFF_HEAP:
|
||||
// No-op
|
||||
retValue = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
LogicHE *makeLogicHEbasketball(ScummEngine_v100he *vm) {
|
||||
return new LogicHEBasketball(vm);
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
709
engines/scumm/he/logic/football.cpp
Normal file
709
engines/scumm/he/logic/football.cpp
Normal file
@@ -0,0 +1,709 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/savefile.h"
|
||||
|
||||
#include "scumm/he/intern_he.h"
|
||||
|
||||
#ifdef USE_ENET
|
||||
#include "scumm/he/net/net_main.h"
|
||||
#ifdef USE_BASIC_NET
|
||||
#include "scumm/he/net/net_lobby.h"
|
||||
#endif
|
||||
#include "scumm/he/net/net_defines.h"
|
||||
#endif
|
||||
|
||||
#include "scumm/he/logic_he.h"
|
||||
|
||||
// DirectPlay opcodes:
|
||||
#define OP_NET_REMOTE_START_SCRIPT 1492
|
||||
#define OP_NET_QUERY_PROVIDERS 1497
|
||||
#define OP_NET_CLOSE_PROVIDER 1500
|
||||
#define OP_NET_QUERY_SESSIONS 1501
|
||||
#define OP_NET_GET_SESSION_NAME 1502
|
||||
#define OP_NET_JOIN_SESSION 1504
|
||||
#define OP_NET_END_SESSION 1505
|
||||
#define OP_NET_ADD_USER 1506
|
||||
#define OP_NET_WHO_SENT_THIS 1508
|
||||
#define OP_NET_REMOTE_SEND_ARRAY 1509
|
||||
#define OP_NET_INIT 1513
|
||||
#define OP_NET_WHO_AM_I 1510
|
||||
#define OP_NET_INIT_LAN_GAME 1515
|
||||
#define OP_NET_SET_PROVIDER_BY_NAME 1516
|
||||
|
||||
// MAIA (Updater) opcodes.
|
||||
#define OP_NET_CHECK_INTERNET_STATUS 3001
|
||||
#define OP_NET_SHUT_DOWN_MAIA 3004
|
||||
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
/**
|
||||
* Logic code for:
|
||||
* Backyard Football
|
||||
* Backyard Football 2002
|
||||
*/
|
||||
class LogicHEfootball : public LogicHE {
|
||||
public:
|
||||
LogicHEfootball(ScummEngine_v90he *vm) : LogicHE(vm) {}
|
||||
|
||||
int versionID() override;
|
||||
int startOfFrame() override;
|
||||
int32 dispatch(int op, int numArgs, int32 *args) override;
|
||||
|
||||
protected:
|
||||
#ifdef USE_ENET
|
||||
void netRemoteStartScript(int numArgs, int32 *args);
|
||||
void netRemoteSendArray(int32 *args);
|
||||
#endif
|
||||
|
||||
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() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEfootball::startOfFrame() {
|
||||
#ifdef USE_ENET
|
||||
#ifdef USE_BASIC_NET
|
||||
// Football 2002 does not have lobby support, so
|
||||
// _lobby is not defined.
|
||||
if (_vm->_lobby)
|
||||
_vm->_lobby->doNetworkOnceAFrame();
|
||||
#endif
|
||||
_vm->_net->doNetworkOnceAFrame(15);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32 LogicHEfootball::dispatch(int op, int numArgs, int32 *args) {
|
||||
#if defined(USE_ENET) && defined(USE_BASIC_NET)
|
||||
if (op > 2120 && op < 3003 && op != OP_NET_CHECK_INTERNET_STATUS &&
|
||||
_vm->_lobby)
|
||||
return _vm->_lobby->dispatch(op, numArgs, args);
|
||||
#endif
|
||||
|
||||
int res = 0;
|
||||
|
||||
switch (op) {
|
||||
case 1004:
|
||||
res = lineEquation3D(args);
|
||||
break;
|
||||
|
||||
case 1006:
|
||||
res = translateWorldToScreen(args);
|
||||
break;
|
||||
|
||||
case 1007:
|
||||
res = fieldGoalScreenTranslation(args);
|
||||
break;
|
||||
|
||||
case 1010:
|
||||
res = translateScreenToWorld(args);
|
||||
break;
|
||||
|
||||
case 1022:
|
||||
res = nextPoint(args);
|
||||
break;
|
||||
|
||||
case 1023:
|
||||
res = computePlayerBallIntercepts(args);
|
||||
break;
|
||||
|
||||
case 1024:
|
||||
res = computeTwoCircleIntercepts(args);
|
||||
break;
|
||||
|
||||
case 8221968:
|
||||
// Someone had a fun and used his birthday as opcode number
|
||||
res = getFromArray(args[0], args[1], args[2]);
|
||||
break;
|
||||
|
||||
|
||||
case OP_NET_INIT:
|
||||
// Initialize network system, this gets called at boot up and
|
||||
// sets VAR_NETWORK_AVAILABLE (100). We just return a 1 if
|
||||
// ENet is compiled. Used in both 1999 and 2002.
|
||||
#ifdef USE_ENET
|
||||
res = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
#ifdef USE_ENET
|
||||
case OP_NET_REMOTE_START_SCRIPT:
|
||||
netRemoteStartScript(numArgs, args);
|
||||
break;
|
||||
|
||||
case OP_NET_CLOSE_PROVIDER:
|
||||
res = _vm->_net->closeProvider();
|
||||
break;
|
||||
|
||||
case OP_NET_QUERY_SESSIONS:
|
||||
#ifdef USE_BASIC_NET
|
||||
if (_vm->_lobby->_sessionId) {
|
||||
_vm->_net->querySessions();
|
||||
// Only proceed if we've found the session
|
||||
// we're looking for.
|
||||
res = _vm->_net->ifSessionExist(_vm->_lobby->_sessionId);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OP_NET_JOIN_SESSION:
|
||||
#ifdef USE_BASIC_NET
|
||||
if (_vm->_lobby->_sessionId) {
|
||||
res = _vm->_net->joinSessionById(_vm->_lobby->_sessionId);
|
||||
if (res) {
|
||||
_vm->_net->stopQuerySessions();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OP_NET_END_SESSION:
|
||||
res = _vm->_net->endSession();
|
||||
break;
|
||||
|
||||
case OP_NET_ADD_USER:
|
||||
char userName[MAX_PLAYER_NAME];
|
||||
_vm->getStringFromArray(args[0], userName, sizeof(userName));
|
||||
res = _vm->_net->addUser(userName, userName);
|
||||
break;
|
||||
|
||||
case OP_NET_WHO_SENT_THIS:
|
||||
res = _vm->_net->whoSentThis();
|
||||
break;
|
||||
|
||||
case OP_NET_REMOTE_SEND_ARRAY:
|
||||
netRemoteSendArray(args);
|
||||
break;
|
||||
|
||||
case OP_NET_WHO_AM_I:
|
||||
res = _vm->_net->whoAmI();
|
||||
break;
|
||||
#endif // USE_ENET
|
||||
|
||||
case OP_NET_CHECK_INTERNET_STATUS:
|
||||
#if defined(USE_ENET) && defined(USE_BASIC_NET)
|
||||
// We can only use the lobby system if both
|
||||
// libcurl (for lobby communication) and
|
||||
// ENet (for gameplay communication) is enabled.
|
||||
|
||||
// TODO: Actually check if we're connected to the
|
||||
// Internet.
|
||||
res = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OP_NET_SHUT_DOWN_MAIA:
|
||||
break;
|
||||
|
||||
case 1493: case 1494: case 1495: case 1496:
|
||||
case 1498: case 1499:
|
||||
case 1502: case 1503:
|
||||
case 1507: case 1511:
|
||||
case 1512: case 1514: case 1555:
|
||||
// DirectPlay-related
|
||||
// 1513: initialize
|
||||
// 1555: set fake lag
|
||||
break;
|
||||
|
||||
default:
|
||||
LogicHE::dispatch(op, numArgs, args);
|
||||
warning("Tell sev how to reproduce it (%d)", op);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
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]);
|
||||
a4 = ((double)args[3] - (double)args[0]) / ((double)args[5] - (double)args[2]);
|
||||
a2 = (double)args[2] - (double)args[0] * a4 - args[1] * a5;
|
||||
|
||||
res = (double)args[6] * a4 + (double)args[7] * a5 + a2;
|
||||
writeScummVar(108, (int32)res);
|
||||
|
||||
writeScummVar(109, (int32)a2);
|
||||
writeScummVar(110, (int32)a5);
|
||||
writeScummVar(111, (int32)a4);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEfootball::translateWorldToScreen(int32 *args) {
|
||||
// This is more or less the inverse of translateScreenToWorld
|
||||
const double a1 = args[1];
|
||||
double res;
|
||||
|
||||
// 2.9411764e-4 = 1/3400
|
||||
// 5.3050399e-2 = 1/18.85 = 20/377
|
||||
// 1.1764706e-2 = 1/85 = 40/3400
|
||||
// 1.2360656e-1 = 377/3050
|
||||
res = (1.0 - a1 * 2.9411764e-4 * 5.3050399e-2) * 1.2360656e-1 * args[0] +
|
||||
a1 * 1.1764706e-2 + 46;
|
||||
|
||||
// Shortened / optimized version of that formula:
|
||||
// res = (377.0 - a1 / 170.0) / 3050.0 * args[0] + a1 / 85.0 + 46;
|
||||
|
||||
writeScummVar(108, (int32)res);
|
||||
|
||||
// 1.2360656e-1 = 377/3050
|
||||
// 1.1588235e-1 = 197/1700 = 394/3400
|
||||
res = 640.0 - args[2] * 1.2360656e-1 - a1 * 1.1588235e-1 - 26;
|
||||
|
||||
writeScummVar(109, (int32)res);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEfootball::fieldGoalScreenTranslation(int32 *args) {
|
||||
double res, temp;
|
||||
|
||||
temp = (double)args[1] * 0.32;
|
||||
|
||||
if (temp > 304.0)
|
||||
res = -args[2] * 0.142;
|
||||
else
|
||||
res = args[2] * 0.142;
|
||||
|
||||
res += temp;
|
||||
|
||||
writeScummVar(108, (int32)res);
|
||||
|
||||
res = (1000.0 - args[2]) * 0.48;
|
||||
|
||||
writeScummVar(109, (int32)res);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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
|
||||
// 5.3050399e-2 = 1/18.85 = 20/377
|
||||
// 1.1764706e-2 = 1/85 = 40/3400
|
||||
// 1.2360656e-1 = 377/3050
|
||||
double a0 = ((double)args[0] - 46 - a1 * 1.1764706e-2) /
|
||||
((1.0 - a1 * 2.9411764e-4 * 5.3050399e-2) * 1.2360656e-1);
|
||||
|
||||
writeScummVar(108, (int32)a0);
|
||||
writeScummVar(109, (int32)a1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEfootball::nextPoint(int32 *args) {
|
||||
double res;
|
||||
double var10 = args[4] - args[1];
|
||||
double var8 = args[5] - args[2];
|
||||
double var6 = args[3] - args[0];
|
||||
|
||||
res = sqrt(var8 * var8 + var6 * var6 + var10 * var10);
|
||||
|
||||
if (res >= (double)args[6]) {
|
||||
var8 = (double)args[6] * var8 / res;
|
||||
var10 = (double)args[6] * var10 / res;
|
||||
var6 = (double)args[6] * var6 / res;
|
||||
}
|
||||
|
||||
writeScummVar(108, (int32)var6);
|
||||
writeScummVar(109, (int32)var10);
|
||||
writeScummVar(110, (int32)var8);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEfootball::computePlayerBallIntercepts(int32 *args) {
|
||||
double var10, var18, var20, var28, var30, var30_;
|
||||
double argf[7];
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
argf[i] = args[i];
|
||||
|
||||
var10 = (argf[3] - argf[1]) / (argf[2] - argf[0]);
|
||||
var28 = var10 * var10 + 1;
|
||||
var20 = argf[0] * var10;
|
||||
var18 = (argf[5] + argf[1] + var20) * argf[4] * var10 * 2 +
|
||||
argf[6] * argf[6] * var28 + argf[4] * argf[4] -
|
||||
argf[0] * argf[0] * var10 * var10 -
|
||||
argf[5] * argf[0] * var10 * 2 -
|
||||
argf[5] * argf[1] * 2 -
|
||||
argf[1] * argf[1] - argf[5] * argf[5];
|
||||
|
||||
if (var18 >= 0) {
|
||||
var18 = sqrt(var18);
|
||||
|
||||
var30_ = argf[4] + argf[5] * var10 + argf[1] * var10 + argf[0] * var10 * var10;
|
||||
var30 = (var30_ - var18) / var28;
|
||||
var18 = (var30_ + var18) / var28;
|
||||
|
||||
if ((argf[0] - var30 < 0) && (argf[0] - var18 < 0)) {
|
||||
var30_ = var30;
|
||||
var30 = var18;
|
||||
var18 = var30_;
|
||||
}
|
||||
var28 = var18 * var10 - var20 - argf[1];
|
||||
var20 = var30 * var10 - var20 - argf[1];
|
||||
} else {
|
||||
var18 = 0;
|
||||
var20 = 0;
|
||||
var28 = 0;
|
||||
var30 = 0;
|
||||
}
|
||||
|
||||
writeScummVar(108, (int32)var18);
|
||||
writeScummVar(109, (int32)var28);
|
||||
writeScummVar(110, (int32)var30);
|
||||
writeScummVar(111, (int32)var20);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEfootball::computeTwoCircleIntercepts(int32 *args) {
|
||||
// Looks like this was just dummied out
|
||||
writeScummVar(108, 0);
|
||||
writeScummVar(109, 0);
|
||||
writeScummVar(110, 0);
|
||||
writeScummVar(111, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef USE_ENET
|
||||
void LogicHEfootball::netRemoteStartScript(int numArgs, int32 *args) {
|
||||
_vm->_net->remoteStartScript(args[0], args[1], args[2], numArgs - 3, &args[3]);
|
||||
}
|
||||
|
||||
void LogicHEfootball::netRemoteSendArray(int32 *args) {
|
||||
_vm->_net->remoteSendArray(args[0], args[1], args[2], args[3]);
|
||||
}
|
||||
#endif // USE_ENET
|
||||
|
||||
class LogicHEfootball2002 : public LogicHEfootball {
|
||||
public:
|
||||
LogicHEfootball2002(ScummEngine_v90he *vm) : LogicHEfootball(vm) {
|
||||
_var0 = _var1 = _var2 = _var3 = _var4 = 0.0;
|
||||
_angle = 0.0;
|
||||
_maxX = -1;
|
||||
_minX = 1000000;
|
||||
}
|
||||
|
||||
int32 dispatch(int op, int numArgs, int32 *args) override;
|
||||
|
||||
private:
|
||||
int translateWorldToScreen(int32 *args) override;
|
||||
int translateScreenToWorld(int32 *args) override;
|
||||
int getDayOfWeek();
|
||||
int initScreenTranslations();
|
||||
int getPlaybookFiles(int32 *args);
|
||||
int largestFreeBlock();
|
||||
|
||||
#ifdef USE_ENET
|
||||
int netGetSessionName(int index);
|
||||
int netInitLanGame(int32 *args);
|
||||
#endif
|
||||
|
||||
float _var0;
|
||||
float _var1;
|
||||
float _var2;
|
||||
float _var3;
|
||||
float _var4;
|
||||
float _angle;
|
||||
int32 _maxX;
|
||||
int32 _minX;
|
||||
|
||||
#ifdef USE_ENET
|
||||
int _requestedSessionIndex = -2;
|
||||
#endif
|
||||
};
|
||||
|
||||
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 1030:
|
||||
// Get Computer Name (online play only)
|
||||
if (ConfMan.hasKey("network_player_name")) {
|
||||
res = _vm->setupStringArrayFromString(ConfMan.get("network_player_name").c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
// These cases are outside #ifdef USE_ENET intentionally
|
||||
// to silence warnings:
|
||||
case OP_NET_QUERY_PROVIDERS:
|
||||
#ifdef USE_ENET
|
||||
res = _vm->_net->queryProviders();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OP_NET_SET_PROVIDER_BY_NAME:
|
||||
#ifdef USE_ENET
|
||||
res = _vm->_net->setProviderByName(args[0], args[1]);
|
||||
if (res)
|
||||
_requestedSessionIndex = _vm->networkSessionDialog();
|
||||
if (_requestedSessionIndex == -2) {
|
||||
// Cancelled out the join dialog.
|
||||
_vm->_net->closeProvider();
|
||||
res = 0;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
#ifdef USE_ENET
|
||||
case OP_NET_QUERY_SESSIONS:
|
||||
if (_requestedSessionIndex > -1)
|
||||
// Emulate that we've found a session.
|
||||
res = 1;
|
||||
break;
|
||||
|
||||
case OP_NET_GET_SESSION_NAME:
|
||||
res = netGetSessionName(args[0]);
|
||||
break;
|
||||
|
||||
case OP_NET_INIT_LAN_GAME:
|
||||
res = netInitLanGame(args);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
res = LogicHEfootball::dispatch(op, numArgs, args);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int LogicHEfootball2002::translateWorldToScreen(int32 *args) {
|
||||
// While this performs the same task as football's 1006 opcode,
|
||||
// the implementation is different. Note that this is also the
|
||||
// same as basketball's 1006 opcode with different constants!
|
||||
|
||||
double v9;
|
||||
if (args[1] >= _minX) {
|
||||
if (args[1] < _maxX) {
|
||||
v9 = (sqrt(_var1 + args[1]) - sqrt(_var1)) / sqrt(_var0);
|
||||
} else {
|
||||
double v10 = sqrt(_var0 * (_maxX + _var1));
|
||||
v9 = 1.0 / (v10 + v10) * (args[1] - _maxX) + 451.0;
|
||||
}
|
||||
} else {
|
||||
double v8 = sqrt(_var0 * (_minX + _var1));
|
||||
v9 = 1.0 / (v8 + v8) * (args[1] - _minX) - 29.0;
|
||||
}
|
||||
|
||||
double v11 = tan(_angle);
|
||||
double v12, v13;
|
||||
|
||||
if (v9 >= -29.0) {
|
||||
if (v9 >= 451.0) {
|
||||
v12 = 1517.0 - (451.0 / v11 + 451.0 / v11);
|
||||
v13 = tan(1.570796326794895 - _angle) * 451.0;
|
||||
} else {
|
||||
v12 = 1517.0 - (v9 / v11 + v9 / v11);
|
||||
v13 = tan(1.570796326794895 - _angle) * v9;
|
||||
}
|
||||
} else {
|
||||
v12 = 1517.0 - (-29.0 / v11 + -29.0 / v11);
|
||||
v13 = tan(1.570796326794895 - _angle) * -29.0;
|
||||
}
|
||||
|
||||
writeScummVar(108, scummRound(v12 * args[0] / 12200.0 + v13 + 41.0));
|
||||
writeScummVar(109, scummRound(611.0 - v9 - v12 * args[2] / 12200.0));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEfootball2002::translateScreenToWorld(int32 *args) {
|
||||
// While this performs the same task as football's 1010 opcode,
|
||||
// the implementation is different. Note that this is also the
|
||||
// same as basketball's 1010 opcode with different constants!
|
||||
|
||||
double v15 = 611.0 - args[1];
|
||||
double v5 = tan(_angle);
|
||||
double v4, v6, v7;
|
||||
|
||||
if (v15 >= -29.0) {
|
||||
if (v15 >= 451.0) {
|
||||
v4 = (_var2 * 902.0 + _var3) * (v15 - 451.0) + _maxX;
|
||||
v6 = 1517.0 - (451.0 / v5 + 451.0 / v5);
|
||||
v7 = tan(1.570796326794895 - _angle) * 451.0;
|
||||
} else {
|
||||
v4 = (v15 * _var2 + _var3) * v15 + _var4;
|
||||
v6 = 1517.0 - (v15 / v5 + v15 / v5);
|
||||
v7 = tan(1.570796326794895 - _angle) * v15;
|
||||
}
|
||||
} else {
|
||||
v4 = (_var3 - _var2 * 58.0) * (v15 - -29.0) + _minX;
|
||||
v6 = 1517.0 - (-29.0 / v5 + -29.0 / v5);
|
||||
v7 = tan(1.570796326794895 - _angle) * -29.0;
|
||||
}
|
||||
|
||||
writeScummVar(108, scummRound((args[0] - (v7 + 41.0)) * (12200.0 / v6)));
|
||||
writeScummVar(109, scummRound(v4));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEfootball2002::getDayOfWeek() {
|
||||
// Get day of week, store in var 108
|
||||
|
||||
TimeDate time;
|
||||
_vm->_system->getTimeAndDate(time);
|
||||
writeScummVar(108, time.tm_wday);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEfootball2002::initScreenTranslations() {
|
||||
// Set values used by translateWorldToScreen/translateScreenToWorld
|
||||
_var0 = _var2 = 0.0029172597f;
|
||||
_var1 = 4896.3755f;
|
||||
_var3 = 7.5588355f;
|
||||
_var4 = 0.0f;
|
||||
_angle = (float)atan(2.899280575539569);
|
||||
_maxX = 4002;
|
||||
_minX = -217;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEfootball2002::getPlaybookFiles(int32 *args) {
|
||||
// Get the pattern and then skip over the directory prefix ("*\" or "*:")
|
||||
// Also prepend the target name
|
||||
Common::String targetName = _vm->getTargetName();
|
||||
Common::String basePattern = ((const char *)_vm->getStringAddress(args[0] & ~MAGIC_ARRAY_NUMBER) + 2);
|
||||
Common::String pattern = targetName + '-' + basePattern;
|
||||
|
||||
// Prepare a buffer to hold the file names
|
||||
Common::String output;
|
||||
|
||||
// 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(); i++) {
|
||||
// Isolate the base part of the filename and concatenate it to our buffer
|
||||
Common::String fileName(fileList[i].c_str() + targetName.size() + 1, fileList[i].size() - (basePattern.size() - 1) - (targetName.size() + 1));
|
||||
output += fileName + '>'; // names separated by '>'
|
||||
}
|
||||
|
||||
// Now store the result in an array
|
||||
int array = _vm->setupStringArray(output.size());
|
||||
Common::strlcpy((char *)_vm->getStringAddress(array), output.c_str(), output.size() + 1);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
#ifdef USE_ENET
|
||||
int LogicHEfootball2002::netGetSessionName(int index) {
|
||||
char name[MAX_SESSION_NAME];
|
||||
_vm->_net->getSessionName(_requestedSessionIndex, name, sizeof(name));
|
||||
return _vm->setupStringArrayFromString(name);
|
||||
}
|
||||
|
||||
int LogicHEfootball2002::netInitLanGame(int32 *args) {
|
||||
// Initialize Session
|
||||
// Arg 0 is the provider name ("TCP/IP")
|
||||
// Arg 1 is the session name
|
||||
// Arg 2 is the host name.
|
||||
// Arg 3 is a boolean determining we're hosting or joining a session.
|
||||
char sessionName[MAX_SESSION_NAME];
|
||||
_vm->getStringFromArray(args[1], sessionName, sizeof(sessionName));
|
||||
char userName[MAX_PLAYER_NAME];
|
||||
_vm->getStringFromArray(args[2], userName, sizeof(userName));
|
||||
|
||||
int res;
|
||||
|
||||
if (args[3] == 1) {
|
||||
// Stop querying sessions if we haven't already
|
||||
_vm->_net->stopQuerySessions();
|
||||
// And host our new game.
|
||||
// If there's a custom game name, use that instead.
|
||||
if (ConfMan.hasKey("game_session_name")) {
|
||||
Common::String gameSessionName = ConfMan.get("game_session_name");
|
||||
return _vm->_net->hostGame(const_cast<char *>(gameSessionName.c_str()), userName);
|
||||
}
|
||||
res = _vm->_net->hostGame(sessionName, userName);
|
||||
} else {
|
||||
res = _vm->_net->joinSession(_requestedSessionIndex);
|
||||
if (res)
|
||||
_vm->_net->addUser(userName, userName);
|
||||
_vm->_net->stopQuerySessions();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
LogicHE *makeLogicHEfootball(ScummEngine_v90he *vm) {
|
||||
return new LogicHEfootball(vm);
|
||||
}
|
||||
|
||||
LogicHE *makeLogicHEfootball2002(ScummEngine_v90he *vm) {
|
||||
return new LogicHEfootball2002(vm);
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
215
engines/scumm/he/logic/funshop.cpp
Normal file
215
engines/scumm/he/logic/funshop.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "scumm/he/intern_he.h"
|
||||
#include "scumm/he/logic_he.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
/**
|
||||
* Logic code for:
|
||||
* Freddi Fish's One-Stop Fun Shop
|
||||
* Pajama Sam's One-Stop Fun Shop
|
||||
* Putt-Putt's One-Stop Fun Shop
|
||||
*/
|
||||
class LogicHEfunshop : public LogicHE {
|
||||
public:
|
||||
LogicHEfunshop(ScummEngine_v90he *vm) : LogicHE(vm) {}
|
||||
|
||||
int versionID() override;
|
||||
int32 dispatch(int op, int numArgs, int32 *args) override;
|
||||
|
||||
private:
|
||||
void op_1004(int32 *args);
|
||||
void op_1005(int32 *args);
|
||||
int checkShape(int32 data0, int32 data1, int32 data4, int32 data5, int32 data2, int32 data3, int32 data6, int32 data7, int32 *x, int32 *y);
|
||||
};
|
||||
|
||||
int LogicHEfunshop::versionID() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32 LogicHEfunshop::dispatch(int op, int numArgs, int32 *args) {
|
||||
switch (op) {
|
||||
case 1004:
|
||||
op_1004(args);
|
||||
break;
|
||||
|
||||
case 1005:
|
||||
op_1005(args);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LogicHEfunshop::op_1004(int32 *args) {
|
||||
double data[8], at, sq;
|
||||
int32 x, y;
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= 6; i += 2) {
|
||||
data[i] = getFromArray(args[0], 0, 519 + i);
|
||||
data[i + 1] = getFromArray(args[0], 0, 519 + i + 1);
|
||||
}
|
||||
int s = checkShape((int32)data[0], (int32)data[1], (int32)data[4], (int32)data[5],
|
||||
(int32)data[2], (int32)data[3], (int32)data[6], (int32)data[7], &x, &y);
|
||||
|
||||
if (s != 1) {
|
||||
error("LogicHEfunshop::op_1004: Your shape has defied the laws of physics");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i <= 6; i += 2) {
|
||||
data[i] -= (double)x;
|
||||
data[i + 1] -= (double)y;
|
||||
}
|
||||
|
||||
double a1 = (double)args[1] * DEG2RAD;
|
||||
|
||||
for (i = 0; i <= 6; i += 2) {
|
||||
at = atan2(data[i + 1], data[i]);
|
||||
sq = sqrt(data[i + 1] * data[i + 1] + data[i] * data[i]);
|
||||
|
||||
if (at <= 0)
|
||||
at += 2 * M_PI;
|
||||
|
||||
data[i] = cos(at + a1) * sq;
|
||||
data[i + 1] = sin(at + a1) * sq;
|
||||
}
|
||||
|
||||
double minx = data[0];
|
||||
double miny = data[1];
|
||||
|
||||
for (i = 0; i <= 6; i += 2) {
|
||||
if (data[i] < minx)
|
||||
minx = data[i];
|
||||
if (data[i + 1] < miny)
|
||||
miny = data[i + 1];
|
||||
}
|
||||
|
||||
for (i = 0; i <= 6; i += 2) {
|
||||
data[i] -= minx;
|
||||
data[i + 1] -= miny;
|
||||
|
||||
putInArray(args[0], 0, 519 + i, scummRound(data[i]));
|
||||
putInArray(args[0], 0, 519 + i + 1, scummRound(data[i + 1]));
|
||||
}
|
||||
}
|
||||
|
||||
void LogicHEfunshop::op_1005(int32 *args) {
|
||||
double data[8];
|
||||
double args1, args2;
|
||||
int i;
|
||||
for (i = 520; i <= 526; i += 2) {
|
||||
data[i - 520] = getFromArray(args[0], 0, i - 1);
|
||||
data[i - 520 + 1] = getFromArray(args[0], 0, i);
|
||||
}
|
||||
|
||||
args1 = (double)args[1] * 0.01 + 1;
|
||||
args2 = (double)args[2] * 0.01 + 1;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
data[2 * i] *= args1;
|
||||
data[2 * i + 1] *= args2;
|
||||
}
|
||||
|
||||
for (i = 520; i <= 526; i += 2) {
|
||||
putInArray(args[0], 0, i - 1, scummRound(data[i - 520]));
|
||||
putInArray(args[0], 0, i, scummRound(data[i - 520 + 1]));
|
||||
}
|
||||
}
|
||||
|
||||
int LogicHEfunshop::checkShape(int32 data0, int32 data1, int32 data4, int32 data5, int32 data2, int32 data3, int32 data6, int32 data7, int32 *x, int32 *y) {
|
||||
int32 diff5_1, diff0_4, diff7_3, diff2_6;
|
||||
int32 diff1, diff2;
|
||||
int32 delta, delta2;
|
||||
int32 sum1, sum2;
|
||||
|
||||
diff0_4 = data0 - data4;
|
||||
diff5_1 = data5 - data1;
|
||||
diff1 = data1 * data4 - data0 * data5;
|
||||
sum1 = diff0_4 * data3 + diff1 + diff5_1 * data2;
|
||||
sum2 = diff0_4 * data7 + diff1 + diff5_1 * data6;
|
||||
|
||||
if (sum1 != 0 && sum2 != 0) {
|
||||
sum2 ^= sum1;
|
||||
|
||||
if (sum2 >= 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff2_6 = data2 - data6;
|
||||
diff7_3 = data7 - data3;
|
||||
diff2 = data3 * data6 - data2 * data7;
|
||||
sum1 = diff2_6 * data1 + diff2 + diff7_3 * data0;
|
||||
sum2 = diff2_6 * data5 + diff2 + diff7_3 * data4;
|
||||
|
||||
if (sum1 != 0 && sum2 != 0) {
|
||||
sum2 ^= sum1;
|
||||
|
||||
if (sum2 >= 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
delta = diff2_6 * diff5_1 - diff0_4 * diff7_3;
|
||||
|
||||
if (delta == 0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (delta < 0) {
|
||||
data7 = -((delta + 1) >> 1);
|
||||
} else {
|
||||
data7 = delta >> 1;
|
||||
}
|
||||
|
||||
delta2 = diff2 * diff0_4 - diff1 * diff2_6;
|
||||
|
||||
if (delta2 < 0) {
|
||||
delta2 -= data7;
|
||||
} else {
|
||||
delta2 += data7;
|
||||
}
|
||||
|
||||
*x = delta2 / delta;
|
||||
|
||||
delta2 = diff1 * diff7_3 - diff2 * diff5_1;
|
||||
|
||||
if (delta2 < 0) {
|
||||
delta2 -= data7;
|
||||
} else {
|
||||
delta2 += data7;
|
||||
}
|
||||
|
||||
*y = delta2 / delta;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
LogicHE *makeLogicHEfunshop(ScummEngine_v90he *vm) {
|
||||
return new LogicHEfunshop(vm);
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
784
engines/scumm/he/logic/moonbase_logic.cpp
Normal file
784
engines/scumm/he/logic/moonbase_logic.cpp
Normal file
@@ -0,0 +1,784 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "scumm/he/intern_he.h"
|
||||
#include "scumm/he/logic_he.h"
|
||||
#include "scumm/he/moonbase/moonbase.h"
|
||||
#include "scumm/he/moonbase/ai_main.h"
|
||||
#ifdef USE_ENET
|
||||
#include "scumm/he/net/net_main.h"
|
||||
#include "scumm/he/net/net_defines.h"
|
||||
#endif
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
/**
|
||||
* Logic code for:
|
||||
* Moonbase Commander
|
||||
*/
|
||||
class LogicHEmoonbase : public LogicHE {
|
||||
public:
|
||||
LogicHEmoonbase(ScummEngine_v100he *vm) : LogicHE(vm) { _vm1 = vm; }
|
||||
|
||||
int versionID() override;
|
||||
|
||||
int startOfFrame() override;
|
||||
|
||||
int32 dispatch(int op, int numArgs, int32 *args) override;
|
||||
bool userCodeProcessWizImageCmd(const WizImageCommand *icmdPtr) override;
|
||||
bool overrideImageHitTest(int *outValue, int globNum, int state, int x, int y, int32 flags) override;
|
||||
bool overrideImagePixelHitTest(int *outValue, int globNum, int state, int x, int y, int32 flags) override;
|
||||
|
||||
private:
|
||||
int op_create_multi_state_wiz(int op, int numArgs, int32 *args);
|
||||
int op_load_multi_channel_wiz(int op, int numArgs, int32 *args);
|
||||
int op_wiz_from_multi_channel_wiz(int op, int numArgs, int32 *args);
|
||||
void op_dos_command(int op, int numArgs, int32 *args);
|
||||
void op_set_fow_sentinel(int32 *args);
|
||||
void op_set_fow_information(int op, int numArgs, int32 *args);
|
||||
int op_set_fow_image(int op, int numArgs, int32 *args);
|
||||
|
||||
void op_ai_test_kludge(int op, int numArgs, int32 *args);
|
||||
int op_ai_master_control_program(int op, int numArgs, int32 *args);
|
||||
void op_ai_reset(int op, int numArgs, int32 *args);
|
||||
void op_ai_set_type(int op, int numArgs, int32 *args);
|
||||
void op_ai_clean_up(int op, int numArgs, int32 *args);
|
||||
|
||||
#ifdef USE_ENET
|
||||
void op_net_remote_start_script(int op, int numArgs, int32 *args);
|
||||
void op_net_remote_send_array(int op, int numArgs, int32 *args);
|
||||
int op_net_remote_start_function(int op, int numArgs, int32 *args);
|
||||
int op_net_do_init_all(int op, int numArgs, int32 *args);
|
||||
int op_net_do_init_provider(int op, int numArgs, int32 *args);
|
||||
int op_net_do_init_session(int op, int numArgs, int32 *args);
|
||||
int op_net_do_init_user(int op, int numArgs, int32 *args);
|
||||
int op_net_query_providers(int op, int numArgs, int32 *args);
|
||||
int op_net_get_provider_name(int op, int numArgs, int32 *args);
|
||||
int op_net_set_provider(int op, int numArgs, int32 *args);
|
||||
int op_net_close_provider(int op, int numArgs, int32 *args);
|
||||
int op_net_start_query_sessions(int op, int numArgs, int32 *args);
|
||||
int op_net_update_query_sessions(int op, int numArgs, int32 *args);
|
||||
int op_net_stop_query_sessions(int op, int numArgs, int32 *args);
|
||||
int op_net_query_sessions(int op, int numArgs, int32 *args);
|
||||
int op_net_get_session_name(int op, int numArgs, int32 *args);
|
||||
int op_net_get_session_player_count(int op, int numArgs, int32 *args);
|
||||
int op_net_destroy_player(int op, int numArgs, int32 *args);
|
||||
int op_net_get_player_long_name(int op, int numArgs, int32 *args);
|
||||
int op_net_get_player_short_name(int op, int numArgs, int32 *args);
|
||||
int op_net_create_session(int op, int numArgs, int32 *args);
|
||||
int op_net_join_session(int op, int numArgs, int32 *args);
|
||||
int op_net_end_session(int op, int numArgs, int32 *args);
|
||||
int op_net_disable_session_player_join(int op, int numArgs, int32 *args);
|
||||
int op_net_enable_session_player_join(int op, int numArgs, int32 *args);
|
||||
int op_net_set_ai_player_count(int op, int numArgs, int32 *args);
|
||||
int op_net_add_user(int op, int numArgs, int32 *args);
|
||||
int op_net_remove_user(int op, int numArgs, int32 *args);
|
||||
int op_net_who_sent_this(int op, int numArgs, int32 *args);
|
||||
int op_net_who_am_i(int op, int numArgs, int32 *args);
|
||||
int op_net_set_provider_by_name(int op, int numArgs, int32 *args);
|
||||
void op_net_set_fake_latency(int op, int numArgs, int32 *args);
|
||||
int op_net_get_host_name(int op, int numArgs, int32 *args);
|
||||
int op_net_get_ip_from_name(int op, int numArgs, int32 *args);
|
||||
int op_net_host_tcpip_game(int op, int numArgs, int32 *args);
|
||||
int op_net_join_tcpip_game(int op, int numArgs, int32 *args);
|
||||
#endif
|
||||
|
||||
private:
|
||||
ScummEngine_v100he *_vm1;
|
||||
};
|
||||
|
||||
int LogicHEmoonbase::versionID() {
|
||||
if (_vm->_game.features & GF_DEMO)
|
||||
return -100;
|
||||
else if (strcmp(_vm->_game.variant, "1.1") == 0)
|
||||
return 110;
|
||||
else
|
||||
return 100;
|
||||
}
|
||||
|
||||
#define OP_CREATE_MULTI_STATE_WIZ 100
|
||||
#define OP_LOAD_MULTI_CHANNEL_WIZ 101
|
||||
#define OP_WIZ_FROM_MULTI_CHANNEL_WIZ 102
|
||||
#define OP_DOS_COMMAND 103
|
||||
#define OP_SET_FOW_SENTINEL 104
|
||||
#define OP_SET_FOW_INFORMATION 105
|
||||
#define OP_SET_FOW_IMAGE 106
|
||||
|
||||
#define OP_AI_TEST_KLUDGE 10000
|
||||
#define OP_AI_MASTER_CONTROL_PROGRAM 10001
|
||||
#define OP_AI_RESET 10002
|
||||
#define OP_AI_SET_TYPE 10003
|
||||
#define OP_AI_CLEAN_UP 10004
|
||||
|
||||
#define OP_NET_REMOTE_START_SCRIPT 1492
|
||||
#define OP_NET_DO_INIT_ALL 1493
|
||||
#define OP_NET_DO_INIT_PROVIDER 1494
|
||||
#define OP_NET_DO_INIT_SESSION 1495
|
||||
#define OP_NET_DO_INIT_USER 1496
|
||||
#define OP_NET_QUERY_PROVIDERS 1497
|
||||
#define OP_NET_GET_PROVIDER_NAME 1498
|
||||
#define OP_NET_SET_PROVIDER 1499
|
||||
#define OP_NET_CLOSE_PROVIDER 1500
|
||||
#define OP_NET_QUERY_SESSIONS 1501
|
||||
#define OP_NET_GET_SESSION_NAME 1502
|
||||
#define OP_NET_CREATE_SESSION 1503
|
||||
#define OP_NET_JOIN_SESSION 1504
|
||||
#define OP_NET_END_SESSION 1505
|
||||
#define OP_NET_ADD_USER 1506
|
||||
#define OP_NET_REMOVE_USER 1507
|
||||
#define OP_NET_WHO_SENT_THIS 1508
|
||||
#define OP_NET_REMOTE_SEND_ARRAY 1509
|
||||
#define OP_NET_WHO_AM_I 1510
|
||||
#define OP_NET_REMOTE_START_FUNCTION 1511
|
||||
#define OP_NET_GET_PLAYER_LONG_NAME 1512
|
||||
#define OP_NET_GET_PLAYER_SHORT_NAME 1513
|
||||
#define OP_NET_SET_PROVIDER_BY_NAME 1516
|
||||
#define OP_NET_HOST_TCPIP_GAME 1517
|
||||
#define OP_NET_JOIN_TCPIP_GAME 1518
|
||||
#define OP_NET_SET_FAKE_LAG 1555
|
||||
#define OP_NET_SET_FAKE_LATENCY 1555 /* SET_FAKE_LAG is a valid alias for backwards compatibility */
|
||||
#define OP_NET_GET_HOST_NAME 1556
|
||||
#define OP_NET_GET_IP_FROM_NAME 1557
|
||||
#define OP_NET_GET_SESSION_PLAYER_COUNT 1558
|
||||
#define OP_NET_DISABLE_SESSION_PLAYER_JOIN 1559
|
||||
#define OP_NET_START_QUERY_SESSIONS 1560
|
||||
#define OP_NET_UPDATE_QUERY_SESSIONS 1561
|
||||
#define OP_NET_STOP_QUERY_SESSIONS 1562
|
||||
#define OP_NET_DESTROY_PLAYER 1563
|
||||
#define OP_NET_ENABLE_SESSION_PLAYER_JOIN 1564
|
||||
#define OP_NET_SET_AI_PLAYER_COUNT 1565
|
||||
|
||||
int LogicHEmoonbase::startOfFrame() {
|
||||
#ifdef USE_ENET
|
||||
_vm1->_net->doNetworkOnceAFrame(15); // Value should be passed in...
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 LogicHEmoonbase::dispatch(int op, int numArgs, int32 *args) {
|
||||
switch (op) {
|
||||
// Development kludge commands which are called within a room
|
||||
// which is not compiled into the final game files
|
||||
case OP_CREATE_MULTI_STATE_WIZ:
|
||||
return op_create_multi_state_wiz(op, numArgs, args);
|
||||
case OP_LOAD_MULTI_CHANNEL_WIZ:
|
||||
return op_load_multi_channel_wiz(op, numArgs, args);
|
||||
case OP_WIZ_FROM_MULTI_CHANNEL_WIZ:
|
||||
return op_wiz_from_multi_channel_wiz(op, numArgs, args);
|
||||
case OP_DOS_COMMAND:
|
||||
op_dos_command(op, numArgs, args);
|
||||
break;
|
||||
|
||||
// "Fog of war" commands
|
||||
case OP_SET_FOW_SENTINEL:
|
||||
op_set_fow_sentinel(args);
|
||||
break;
|
||||
case OP_SET_FOW_INFORMATION:
|
||||
op_set_fow_information(op, numArgs, args);
|
||||
break;
|
||||
case OP_SET_FOW_IMAGE:
|
||||
return op_set_fow_image(op, numArgs, args);
|
||||
|
||||
// AI commands
|
||||
case OP_AI_TEST_KLUDGE:
|
||||
op_ai_test_kludge(op, numArgs, args);
|
||||
break;
|
||||
case OP_AI_MASTER_CONTROL_PROGRAM:
|
||||
return op_ai_master_control_program(op, numArgs, args);
|
||||
case OP_AI_RESET:
|
||||
op_ai_reset(op, numArgs, args);
|
||||
break;
|
||||
case OP_AI_SET_TYPE:
|
||||
op_ai_set_type(op, numArgs, args);
|
||||
break;
|
||||
case OP_AI_CLEAN_UP:
|
||||
op_ai_clean_up(op, numArgs, args);
|
||||
break;
|
||||
|
||||
#ifdef USE_ENET
|
||||
// Network commands
|
||||
case OP_NET_REMOTE_START_SCRIPT:
|
||||
op_net_remote_start_script(op, numArgs, args);
|
||||
break;
|
||||
case OP_NET_REMOTE_SEND_ARRAY:
|
||||
op_net_remote_send_array(op, numArgs, args);
|
||||
break;
|
||||
case OP_NET_REMOTE_START_FUNCTION:
|
||||
return op_net_remote_start_function(op, numArgs, args);
|
||||
case OP_NET_DO_INIT_ALL:
|
||||
return op_net_do_init_all(op, numArgs, args);
|
||||
case OP_NET_DO_INIT_PROVIDER:
|
||||
return op_net_do_init_provider(op, numArgs, args);
|
||||
case OP_NET_DO_INIT_SESSION:
|
||||
return op_net_do_init_session(op, numArgs, args);
|
||||
case OP_NET_DO_INIT_USER:
|
||||
return op_net_do_init_user(op, numArgs, args);
|
||||
case OP_NET_QUERY_PROVIDERS:
|
||||
return op_net_query_providers(op, numArgs, args);
|
||||
case OP_NET_GET_PROVIDER_NAME:
|
||||
return op_net_get_provider_name(op, numArgs, args);
|
||||
case OP_NET_SET_PROVIDER:
|
||||
return op_net_set_provider(op, numArgs, args);
|
||||
case OP_NET_CLOSE_PROVIDER:
|
||||
return op_net_close_provider(op, numArgs, args);
|
||||
case OP_NET_START_QUERY_SESSIONS:
|
||||
return op_net_start_query_sessions(op, numArgs, args);
|
||||
case OP_NET_UPDATE_QUERY_SESSIONS:
|
||||
return op_net_update_query_sessions(op, numArgs, args);
|
||||
case OP_NET_STOP_QUERY_SESSIONS:
|
||||
return op_net_stop_query_sessions(op, numArgs, args);
|
||||
case OP_NET_QUERY_SESSIONS:
|
||||
return op_net_query_sessions(op, numArgs, args);
|
||||
case OP_NET_GET_SESSION_NAME:
|
||||
return op_net_get_session_name(op, numArgs, args);
|
||||
case OP_NET_GET_SESSION_PLAYER_COUNT:
|
||||
return op_net_get_session_player_count(op, numArgs, args);
|
||||
case OP_NET_DESTROY_PLAYER:
|
||||
return op_net_destroy_player(op, numArgs, args);
|
||||
case OP_NET_GET_PLAYER_LONG_NAME:
|
||||
return op_net_get_player_long_name(op, numArgs, args);
|
||||
case OP_NET_GET_PLAYER_SHORT_NAME:
|
||||
return op_net_get_player_short_name(op, numArgs, args);
|
||||
case OP_NET_CREATE_SESSION:
|
||||
return op_net_create_session(op, numArgs, args);
|
||||
case OP_NET_JOIN_SESSION:
|
||||
return op_net_join_session(op, numArgs, args);
|
||||
case OP_NET_END_SESSION:
|
||||
return op_net_end_session(op, numArgs, args);
|
||||
case OP_NET_DISABLE_SESSION_PLAYER_JOIN:
|
||||
return op_net_disable_session_player_join(op, numArgs, args);
|
||||
case OP_NET_ENABLE_SESSION_PLAYER_JOIN:
|
||||
return op_net_enable_session_player_join(op, numArgs, args);
|
||||
case OP_NET_SET_AI_PLAYER_COUNT:
|
||||
return op_net_set_ai_player_count(op, numArgs, args);
|
||||
case OP_NET_ADD_USER:
|
||||
return op_net_add_user(op, numArgs, args);
|
||||
case OP_NET_REMOVE_USER:
|
||||
return op_net_remove_user(op, numArgs, args);
|
||||
case OP_NET_WHO_SENT_THIS:
|
||||
return op_net_who_sent_this(op, numArgs, args);
|
||||
case OP_NET_WHO_AM_I:
|
||||
return op_net_who_am_i(op, numArgs, args);
|
||||
case OP_NET_SET_PROVIDER_BY_NAME:
|
||||
return op_net_set_provider_by_name(op, numArgs, args);
|
||||
case OP_NET_SET_FAKE_LATENCY: // SET_FAKE_LAG is a valid alias for backwards compatibility
|
||||
op_net_set_fake_latency(op, numArgs, args);
|
||||
break;
|
||||
case OP_NET_GET_HOST_NAME:
|
||||
return op_net_get_host_name(op, numArgs, args);
|
||||
case OP_NET_GET_IP_FROM_NAME:
|
||||
return op_net_get_ip_from_name(op, numArgs, args);
|
||||
case OP_NET_HOST_TCPIP_GAME:
|
||||
return op_net_host_tcpip_game(op, numArgs, args);
|
||||
case OP_NET_JOIN_TCPIP_GAME:
|
||||
return op_net_join_tcpip_game(op, numArgs, args);
|
||||
#endif
|
||||
|
||||
default:
|
||||
LogicHE::dispatch(op, numArgs, args);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool LogicHEmoonbase::userCodeProcessWizImageCmd(const WizImageCommand *params) {
|
||||
// Make sure there is a imgcmd struct and it's a render operation
|
||||
if (!params) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (params->actionType != kWADraw) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If there are special rendering bits bail
|
||||
if (params->flags & kWRFSpecialRenderBitMask) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check to see if the caller wants to use a source buffer
|
||||
int sourceBufferImage = 0;
|
||||
|
||||
if (params->actionFlags & kWAFSourceImage) {
|
||||
sourceBufferImage = params->sourceImage;
|
||||
}
|
||||
|
||||
// Check to see if the caller wants to render into another image.
|
||||
int destImage = 0;
|
||||
|
||||
if (params->actionFlags & kWAFDestImage) {
|
||||
destImage = params->destImageNumber;
|
||||
}
|
||||
|
||||
// Get the glob address and state number
|
||||
byte *globPtr = _vm->getResourceAddress(rtImage, params->image);
|
||||
|
||||
if (!globPtr) {
|
||||
error("LogicHEmoonbase::userCodeProcessWizImageCmd(): Image %d not on heap?", params->image);
|
||||
return false;
|
||||
}
|
||||
|
||||
int state = (params->actionFlags & kWAFState) ? params->state : 0;
|
||||
|
||||
// Make sure the dest buffer is one we can handle (Background or foreground)
|
||||
WizMultiTypeBitmap mappedMultiBM;
|
||||
|
||||
bool drawIntoBackground = ((params->flags & kWRFBackground) == kWRFBackground);
|
||||
|
||||
if (destImage) {
|
||||
if (!_vm->_wiz->dwGetMultiTypeBitmapFromImageState(destImage, 0, &mappedMultiBM)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!_vm->_wiz->pgGetMultiTypeBitmapFromDrawBuffer(&mappedMultiBM, drawIntoBackground)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Common::Rect clipRect, bitmapLimitsRect;
|
||||
|
||||
bitmapLimitsRect.left = 0;
|
||||
bitmapLimitsRect.top = 0;
|
||||
bitmapLimitsRect.right = (mappedMultiBM.width - 1);
|
||||
bitmapLimitsRect.bottom = (mappedMultiBM.height - 1);
|
||||
|
||||
if (params->actionFlags & kWAFRect) {
|
||||
clipRect.left = params->box.left;
|
||||
clipRect.top = params->box.top;
|
||||
clipRect.right = params->box.right;
|
||||
clipRect.bottom = params->box.bottom;
|
||||
|
||||
if (!_vm->_wiz->findRectOverlap(&clipRect, &bitmapLimitsRect)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
clipRect = bitmapLimitsRect;
|
||||
}
|
||||
|
||||
// Validate source image if requested
|
||||
byte *altSourceData = nullptr;
|
||||
|
||||
if (sourceBufferImage) {
|
||||
WizMultiTypeBitmap sourceMultiBM;
|
||||
|
||||
if (!_vm->_wiz->dwGetMultiTypeBitmapFromImageState(sourceBufferImage, 0, &sourceMultiBM)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((sourceMultiBM.width != mappedMultiBM.width) ||
|
||||
(sourceMultiBM.height != mappedMultiBM.height) ||
|
||||
(sourceMultiBM.stride != mappedMultiBM.stride) ||
|
||||
(sourceMultiBM.format != mappedMultiBM.format) ||
|
||||
(sourceMultiBM.bpp != mappedMultiBM.bpp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
altSourceData = sourceMultiBM.data;
|
||||
}
|
||||
|
||||
// Convert the icmd struct to useful info for the renderer
|
||||
int32 locationX, locationY;
|
||||
|
||||
if (params->actionFlags & kWAFSpot) {
|
||||
locationX = params->xPos;
|
||||
locationY = params->yPos;
|
||||
} else {
|
||||
locationX = 0;
|
||||
locationY = 0;
|
||||
}
|
||||
|
||||
int32 wizDrawFlags;
|
||||
|
||||
if (params->actionFlags & kWAFFlags) {
|
||||
wizDrawFlags = params->flags;
|
||||
} else {
|
||||
wizDrawFlags = 0;
|
||||
}
|
||||
|
||||
// Get any palette specified
|
||||
byte *paletteData;
|
||||
|
||||
if (params->actionFlags & kWAFPalette) {
|
||||
paletteData = _vm->getHEPaletteSlot(params->palette);
|
||||
} else {
|
||||
paletteData = _vm->getHEPaletteSlot(1);
|
||||
}
|
||||
|
||||
// Finally call the renderer (returns false if not handled or error)
|
||||
if ((_vm1->_moonbase->_fowSentinelImage != params->image) ||
|
||||
(_vm1->_moonbase->_fowSentinelState != state) ||
|
||||
(_vm1->_moonbase->_fowSentinelConditionBits != (uint32)params->extendedRenderInfo.conditionBits)) {
|
||||
|
||||
if (!_vm->_wiz->drawMoonbaseLayeredWiz(
|
||||
mappedMultiBM.data,
|
||||
mappedMultiBM.width, mappedMultiBM.height,
|
||||
mappedMultiBM.stride, mappedMultiBM.format, mappedMultiBM.bpp,
|
||||
globPtr, locationX, locationY, state,
|
||||
clipRect.left, clipRect.top, clipRect.right, clipRect.bottom,
|
||||
wizDrawFlags, params->extendedRenderInfo.conditionBits,
|
||||
paletteData, altSourceData)) {
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
_vm1->_moonbase->renderFOW(&mappedMultiBM);
|
||||
}
|
||||
|
||||
if (destImage) {
|
||||
_vm->_res->setModified(rtImage, destImage);
|
||||
} else {
|
||||
Common::Rect updateRectangle = clipRect;
|
||||
|
||||
if (drawIntoBackground) {
|
||||
_vm->backgroundToForegroundBlit(updateRectangle);
|
||||
} else {
|
||||
_vm->markRectAsDirty(kMainVirtScreen, updateRectangle);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LogicHEmoonbase::overrideImageHitTest(int *outValue, int globNum, int state, int x, int y, int32 flags) {
|
||||
// Make sure this is a hit-test operation is a type we can handle
|
||||
byte *globPtr = _vm->getResourceAddress(rtImage, globNum);
|
||||
|
||||
if (!globPtr) {
|
||||
warning("LogicHEmoonbase::overrideImageHitTest(): Image %d not on heap", globNum);
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 actualValue = 0;
|
||||
int32 eatValue = 0;
|
||||
|
||||
if (!_vm->_wiz->moonbaseLayeredWizHitTest(&eatValue, &actualValue, globPtr, state, x, y, flags, (uint32)0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*outValue = (int)eatValue;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LogicHEmoonbase::overrideImagePixelHitTest(int *outValue, int globNum, int state, int x, int y, int32 flags) {
|
||||
// Make sure this is a hit-test operation is a type we can handle
|
||||
byte *globPtr = _vm->getResourceAddress(rtImage, globNum);
|
||||
|
||||
if (!globPtr) {
|
||||
warning("LogicHEmoonbase::overrideImagePixelHitTest(): Image %d not on heap", globNum);
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 actualValue = ~0;
|
||||
int32 eatValue = 0;
|
||||
|
||||
if (!_vm->_wiz->moonbaseLayeredWizHitTest(&eatValue, &actualValue, globPtr, state, x, y, flags, (uint32)0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*outValue = (int)actualValue;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_create_multi_state_wiz(int op, int numArgs, int32 *params) {
|
||||
debug("LogicHEmoonbase::op_create_multi_state_wiz(): Unused development command called by a script non compiled in the final game files, ignoring");
|
||||
LogicHE::dispatch(op, numArgs, params);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_load_multi_channel_wiz(int op, int numArgs, int32 *params) {
|
||||
debug("LogicHEmoonbase::op_load_multi_channel_wiz(): Unused development command called by a script non compiled in the final game files, ignoring");
|
||||
LogicHE::dispatch(op, numArgs, params);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_wiz_from_multi_channel_wiz(int op, int numArgs, int32 *params) {
|
||||
debug("LogicHEmoonbase::op_wiz_from_multi_channel_wiz(): Unused development command called by a script non compiled in the final game files, ignoring");
|
||||
LogicHE::dispatch(op, numArgs, params);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LogicHEmoonbase::op_dos_command(int op, int numArgs, int32 *params) {
|
||||
debug("LogicHEmoonbase::op_dos_command(): Unused development command called by a script non compiled in the final game files, ignoring");
|
||||
LogicHE::dispatch(op, numArgs, params);
|
||||
}
|
||||
|
||||
void LogicHEmoonbase::op_set_fow_sentinel(int32 *args) {
|
||||
debug(2, "op_set_fow_sentinel(%d, %d, %d)", args[0], args[1], args[2]);
|
||||
|
||||
_vm1->_moonbase->_fowSentinelImage = args[0];
|
||||
_vm1->_moonbase->_fowSentinelState = args[1];
|
||||
_vm1->_moonbase->_fowSentinelConditionBits = args[2];
|
||||
}
|
||||
|
||||
void LogicHEmoonbase::op_set_fow_information(int op, int numArgs, int32 *args) {
|
||||
Common::String str;
|
||||
|
||||
str = Common::String::format("op_set_fow_information(%d", args[0]);
|
||||
for (int i = 1; i < numArgs; i++) {
|
||||
str += Common::String::format(", %d", args[i]);
|
||||
}
|
||||
str += ")";
|
||||
|
||||
debug(2, "%s", str.c_str());
|
||||
|
||||
_vm1->_moonbase->setFOWInfo(
|
||||
args[0], // array
|
||||
args[1], // array down dimension
|
||||
args[2], // array across dimension
|
||||
args[3], // logical view X coordinate
|
||||
args[4], // logical view Y coordinate
|
||||
args[5], // screen draw clip rect x1
|
||||
args[6], // screen draw clip rect y1
|
||||
args[7], // screen draw clip rect x2
|
||||
args[8], // screen draw clip rect y2
|
||||
args[9], // techinque
|
||||
args[10] // frame
|
||||
);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_set_fow_image(int op, int numArgs, int32 *args) {
|
||||
debug(2, "op_set_fow_image(%d)", args[0]);
|
||||
return _vm1->_moonbase->setFOWImage(args[0]) ? 1 : 0;
|
||||
}
|
||||
|
||||
void LogicHEmoonbase::op_ai_test_kludge(int op, int numArgs, int32 *args) {
|
||||
warning("STUB: op_ai_test_kludge()");
|
||||
LogicHE::dispatch(op, numArgs, args);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_ai_master_control_program(int op, int numArgs, int32 *args) {
|
||||
debugC(DEBUG_MOONBASE_AI, "op_ai_master_control_program()");
|
||||
return _vm1->_moonbase->_ai->masterControlProgram(numArgs, args);
|
||||
}
|
||||
|
||||
void LogicHEmoonbase::op_ai_reset(int op, int numArgs, int32 *args) {
|
||||
debugC(DEBUG_MOONBASE_AI, "op_ai_reset())");
|
||||
_vm1->_moonbase->_ai->resetAI();
|
||||
}
|
||||
|
||||
void LogicHEmoonbase::op_ai_set_type(int op, int numArgs, int32 *args) {
|
||||
debugC(DEBUG_MOONBASE_AI, "op_ai_set_type()");
|
||||
_vm1->_moonbase->_ai->setAIType(numArgs, args);
|
||||
}
|
||||
|
||||
void LogicHEmoonbase::op_ai_clean_up(int op, int numArgs, int32 *args) {
|
||||
debugC(DEBUG_MOONBASE_AI, "op_ai_clean_up()");
|
||||
_vm1->_moonbase->_ai->cleanUpAI();
|
||||
}
|
||||
|
||||
#ifdef USE_ENET
|
||||
void LogicHEmoonbase::op_net_remote_start_script(int op, int numArgs, int32 *args) {
|
||||
_vm1->_net->remoteStartScript(args[0], args[1], args[2], numArgs - 3, &args[3]);
|
||||
}
|
||||
|
||||
void LogicHEmoonbase::op_net_remote_send_array(int op, int numArgs, int32 *args) {
|
||||
_vm1->_net->remoteSendArray(args[0], args[1], args[2], args[3]);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_remote_start_function(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->remoteStartScriptFunction(args[0], args[1], args[2], args[3], numArgs - 4, &args[4]);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_do_init_all(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->initAll();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_do_init_provider(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->initProvider();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_do_init_session(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->initSession();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_do_init_user(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->initUser();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_query_providers(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->queryProviders();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_get_provider_name(int op, int numArgs, int32 *args) {
|
||||
char name[MAX_PROVIDER_NAME];
|
||||
_vm1->_net->getProviderName(args[0] - 1, name, sizeof(name));
|
||||
return _vm1->setupStringArrayFromString(name);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_set_provider(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->setProvider(args[0] - 1);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_close_provider(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->closeProvider();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_start_query_sessions(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->startQuerySessions();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_update_query_sessions(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->updateQuerySessions();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_stop_query_sessions(int op, int numArgs, int32 *args) {
|
||||
_vm1->_net->stopQuerySessions();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_query_sessions(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->querySessions();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_get_session_name(int op, int numArgs, int32 *args) {
|
||||
char name[MAX_PROVIDER_NAME];
|
||||
_vm1->_net->getSessionName(args[0] - 1, name, sizeof(name));
|
||||
return _vm1->setupStringArrayFromString(name);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_get_session_player_count(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->getSessionPlayerCount(args[0] - 1);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_destroy_player(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->destroyPlayer(args[0]);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_get_player_long_name(int op, int numArgs, int32 *args) {
|
||||
return _vm1->setupStringArrayFromString("long name"); // TODO: gdefMultiPlay.playername1
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_get_player_short_name(int op, int numArgs, int32 *args) {
|
||||
return _vm1->setupStringArrayFromString("short"); // TODO: gdefMultiPlay.playername2
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_create_session(int op, int numArgs, int32 *args) {
|
||||
char name[MAX_SESSION_NAME];
|
||||
_vm1->getStringFromArray(args[0], name, sizeof(name));
|
||||
return _vm1->_net->createSession(name);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_join_session(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->joinSession(args[0] - 1);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_end_session(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->endSession();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_disable_session_player_join(int op, int numArgs, int32 *args) {
|
||||
_vm1->_net->disableSessionJoining();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_enable_session_player_join(int op, int numArgs, int32 *args) {
|
||||
_vm1->_net->enableSessionJoining();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_set_ai_player_count(int op, int numArgs, int32 *args) {
|
||||
_vm1->_net->setBotsCount(args[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_add_user(int op, int numArgs, int32 *args) {
|
||||
char userName[MAX_PLAYER_NAME];
|
||||
_vm1->getStringFromArray(args[0], userName, sizeof(userName));
|
||||
return _vm1->_net->addUser(userName, userName);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_remove_user(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->removeUser();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_who_sent_this(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->whoSentThis();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_who_am_i(int op, int numArgs, int32 *args) {
|
||||
return _vm1->_net->whoAmI();
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_set_provider_by_name(int op, int numArgs, int32 *args) {
|
||||
// Parameter 1 is the provider name and
|
||||
// Parameter 2 is the (optional) tcp/ip address
|
||||
return _vm1->_net->setProviderByName(args[0], args[1]);
|
||||
}
|
||||
|
||||
void LogicHEmoonbase::op_net_set_fake_latency(int op, int numArgs, int32 *args) {
|
||||
_vm1->_net->setFakeLatency(args[0]);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_get_host_name(int op, int numArgs, int32 *args) {
|
||||
char name[MAX_HOSTNAME_SIZE];
|
||||
|
||||
if (_vm1->_net->getHostName(name, MAX_HOSTNAME_SIZE)) {
|
||||
return _vm1->setupStringArrayFromString(name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_get_ip_from_name(int op, int numArgs, int32 *args) {
|
||||
char name[MAX_HOSTNAME_SIZE];
|
||||
_vm1->getStringFromArray(args[0], name, sizeof(name));
|
||||
|
||||
char ip[MAX_IP_SIZE];
|
||||
|
||||
if (_vm1->_net->getIPfromName(ip, MAX_IP_SIZE, name)) {
|
||||
return _vm1->setupStringArrayFromString(ip);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_host_tcpip_game(int op, int numArgs, int32 *args) {
|
||||
char sessionName[MAX_SESSION_NAME];
|
||||
char userName[MAX_PLAYER_NAME];
|
||||
|
||||
_vm1->getStringFromArray(args[0], sessionName, sizeof(sessionName));
|
||||
_vm1->getStringFromArray(args[1], userName, sizeof(userName));
|
||||
|
||||
return _vm1->_net->hostGame(sessionName, userName);
|
||||
}
|
||||
|
||||
int LogicHEmoonbase::op_net_join_tcpip_game(int op, int numArgs, int32 *args) {
|
||||
char ip[MAX_IP_SIZE];
|
||||
char userName[MAX_PLAYER_NAME];
|
||||
|
||||
_vm1->getStringFromArray(args[0], ip, sizeof(ip));
|
||||
_vm1->getStringFromArray(args[1], userName, sizeof(userName));
|
||||
|
||||
return _vm1->_net->joinGame(ip, userName);
|
||||
}
|
||||
#endif
|
||||
|
||||
LogicHE *makeLogicHEmoonbase(ScummEngine_v100he *vm) {
|
||||
return new LogicHEmoonbase(vm);
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
375
engines/scumm/he/logic/puttrace.cpp
Normal file
375
engines/scumm/he/logic/puttrace.cpp
Normal file
@@ -0,0 +1,375 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "scumm/he/intern_he.h"
|
||||
#include "scumm/he/logic_he.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
/**
|
||||
* Logic code for:
|
||||
* Putt-Putt Enters the Race
|
||||
*/
|
||||
class LogicHErace : public LogicHE {
|
||||
private:
|
||||
float *_userData;
|
||||
double *_userDataD;
|
||||
public:
|
||||
LogicHErace(ScummEngine_v90he *vm);
|
||||
~LogicHErace() override;
|
||||
|
||||
int versionID() override;
|
||||
int32 dispatch(int op, int numArgs, int32 *args) override;
|
||||
|
||||
private:
|
||||
int32 op_1003(int32 *args);
|
||||
int32 op_1004(int32 *args);
|
||||
int32 op_1100(int32 *args);
|
||||
int32 op_1101(int32 *args);
|
||||
int32 op_1102(int32 *args);
|
||||
int32 op_1103(int32 *args);
|
||||
int32 op_1110();
|
||||
int32 op_1120(int32 *args);
|
||||
int32 op_1130(int32 *args);
|
||||
int32 op_1140(int32 *args);
|
||||
|
||||
void op_sub1(float arg);
|
||||
void op_sub2(float arg);
|
||||
void op_sub3(float arg);
|
||||
};
|
||||
|
||||
LogicHErace::LogicHErace(ScummEngine_v90he *vm) : LogicHE(vm) {
|
||||
// Originally it used 0x930 and stored both floats and doubles inside
|
||||
_userData = (float *)calloc(550, sizeof(float));
|
||||
_userDataD = (double *)calloc(30, sizeof(double));
|
||||
|
||||
// FIXME: of the 550 entries in _userData, only 516 till 532 are used
|
||||
// FIXME: similarly, in _userDataD only 9 till 17 are used for computations
|
||||
// (some of the other entries are also set, but never read, hence useless).
|
||||
}
|
||||
|
||||
LogicHErace::~LogicHErace() {
|
||||
free(_userData);
|
||||
free(_userDataD);
|
||||
}
|
||||
|
||||
int LogicHErace::versionID() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32 LogicHErace::dispatch(int op, int numArgs, int32 *args) {
|
||||
int32 res;
|
||||
|
||||
switch (op) {
|
||||
case 1003:
|
||||
res = op_1003(args);
|
||||
break;
|
||||
|
||||
case 1004:
|
||||
res = op_1004(args);
|
||||
break;
|
||||
|
||||
case 1100:
|
||||
res = op_1100(args);
|
||||
break;
|
||||
|
||||
case 1101:
|
||||
res = op_1101(args);
|
||||
break;
|
||||
|
||||
case 1102:
|
||||
res = op_1102(args);
|
||||
break;
|
||||
|
||||
case 1103:
|
||||
res = op_1103(args);
|
||||
break;
|
||||
|
||||
case 1110:
|
||||
res = op_1110();
|
||||
break;
|
||||
|
||||
case 1120:
|
||||
res = op_1120(args);
|
||||
break;
|
||||
|
||||
case 1130:
|
||||
res = op_1130(args);
|
||||
break;
|
||||
|
||||
case 1140:
|
||||
res = op_1140(args);
|
||||
break;
|
||||
|
||||
default:
|
||||
res = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#define RAD2DEG (180 / M_PI)
|
||||
#define DEG2RAD (M_PI / 180)
|
||||
|
||||
int32 LogicHErace::op_1003(int32 *args) {
|
||||
int value = args[2] ? args[2] : 1;
|
||||
|
||||
writeScummVar(108, (int32)(atan2((double)args[0], (double)args[1]) * RAD2DEG * value));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32 LogicHErace::op_1004(int32 *args) {
|
||||
int value = args[1] ? args[1] : 1;
|
||||
|
||||
writeScummVar(108, (int32)(sqrt((float)args[0]) * value));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32 LogicHErace::op_1100(int32 *args) {
|
||||
// _userData 516,517,518 describe a 3D translation?
|
||||
_userData[516] = (float)args[0] / args[10];
|
||||
_userData[517] = (float)args[1] / args[10];
|
||||
_userData[518] = (float)args[2] / args[10];
|
||||
|
||||
// _userData 519,520,521 describe rotation angles around the x,y,z axes?
|
||||
_userData[519] = (float)args[3] / args[10];
|
||||
_userData[520] = (float)args[4] / args[10];
|
||||
_userData[521] = (float)args[5] / args[10];
|
||||
|
||||
op_sub1(_userData[520]);
|
||||
op_sub2(_userData[521]);
|
||||
|
||||
// _userData[532] seems to be some kind of global scale factor
|
||||
_userData[532] = (float)args[10];
|
||||
|
||||
_userData[524] = (float)args[8]; // not used
|
||||
_userData[525] = (float)args[9]; // not used
|
||||
_userData[522] = (float)args[6] / args[10]; // not used
|
||||
_userData[523] = (float)args[7] / args[10]; // only used to compute 528 and 529
|
||||
|
||||
// The following two are some kind of scale factors
|
||||
_userData[526] = (float)args[6] / args[8] / args[10];
|
||||
_userData[527] = (float)args[7] / args[9] / args[10];
|
||||
|
||||
// Set var 108 and 109 -- the value set here corresponds to the values
|
||||
// set by op_1110!
|
||||
writeScummVar(108, (int32)((float)args[6] / args[8] * args[10]));
|
||||
writeScummVar(109, (int32)((float)args[7] / args[9] * args[10]));
|
||||
|
||||
_userData[528] = (float)(_userData[519] - _userData[523] * 0.5);
|
||||
_userData[529] = (float)(_userData[519] + _userData[523] * 0.5);
|
||||
|
||||
writeScummVar(110, (int32)(_userData[528] * args[10]));
|
||||
writeScummVar(111, (int32)(_userData[529] * args[10]));
|
||||
|
||||
// 530 and 531 are only used to set vars 112 and 113, so no need
|
||||
// to store them permanently
|
||||
_userData[530] = (float)(_userData[517] / tan(_userData[529] * DEG2RAD));
|
||||
_userData[531] = (float)(_userData[517] / tan(_userData[528] * DEG2RAD));
|
||||
|
||||
writeScummVar(112, (int32)(_userData[530] * args[10]));
|
||||
writeScummVar(113, (int32)(_userData[531] * args[10]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32 LogicHErace::op_1101(int32 *args) {
|
||||
// Update rotation params?
|
||||
int32 retval;
|
||||
float temp;
|
||||
|
||||
temp = args[0] / _userData[532];
|
||||
if (_userData[519] != temp) {
|
||||
_userData[519] = temp;
|
||||
op_sub3(temp);
|
||||
retval = 1;
|
||||
} else {
|
||||
retval = (int32)temp;
|
||||
}
|
||||
|
||||
temp = args[1] / _userData[532];
|
||||
if (_userData[520] != temp) {
|
||||
_userData[520] = temp;
|
||||
op_sub1(temp);
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
temp = args[2] / _userData[532];
|
||||
if (_userData[521] != temp) {
|
||||
_userData[521] = temp;
|
||||
op_sub2(temp);
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int32 LogicHErace::op_1102(int32 *args) {
|
||||
// Update translation params?
|
||||
int32 retval;
|
||||
float temp;
|
||||
|
||||
temp = args[0] / _userData[532];
|
||||
if (_userData[516] != temp) {
|
||||
_userData[516] = temp;
|
||||
retval = 1;
|
||||
} else {
|
||||
retval = (int32)_userData[532];
|
||||
}
|
||||
|
||||
temp = args[1] / _userData[532];
|
||||
if (_userData[517] != temp) {
|
||||
_userData[517] = temp;
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
temp = args[2] / _userData[532];
|
||||
if (_userData[518] != temp) {
|
||||
_userData[518] = temp;
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int32 LogicHErace::op_1103(int32 *args) {
|
||||
double angle = (double)args[0] / (double)args[1] * DEG2RAD;
|
||||
|
||||
writeScummVar(108, (int32)(sin(angle) * args[2]));
|
||||
writeScummVar(109, (int32)(cos(angle) * args[2]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32 LogicHErace::op_1110() {
|
||||
writeScummVar(108, (int32)(_userData[526] * _userData[532] * _userData[532]));
|
||||
writeScummVar(109, (int32)(_userData[527] * _userData[532] * _userData[532]));
|
||||
writeScummVar(110, (int32)(_userData[532]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32 LogicHErace::op_1120(int32 *args) {
|
||||
double a0, a1, a2;
|
||||
double b0, b1, b2;
|
||||
double res1, res2;
|
||||
|
||||
a0 = args[0] / _userData[532] - _userData[516];
|
||||
a1 = args[1] / _userData[532] - _userData[517];
|
||||
a2 = args[2] / _userData[532] - _userData[518];
|
||||
|
||||
// Perform matrix multiplication (multiplying by a rotation matrix)
|
||||
b2 = a2 * _userDataD[17] + a1 * _userDataD[14] + a0 * _userDataD[11];
|
||||
b1 = a2 * _userDataD[16] + a1 * _userDataD[13] + a0 * _userDataD[10];
|
||||
b0 = a2 * _userDataD[15] + a1 * _userDataD[12] + a0 * _userDataD[9];
|
||||
|
||||
res1 = (atan2(b0, b2) * RAD2DEG) / _userData[526];
|
||||
res2 = (atan2(b1, b2) * RAD2DEG - _userData[528]) / _userData[527];
|
||||
|
||||
writeScummVar(108, (int32)res1);
|
||||
writeScummVar(109, (int32)res2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32 LogicHErace::op_1130(int32 *args) {
|
||||
double cs = cos(args[0] / _userData[532] * DEG2RAD);
|
||||
double sn = sin(args[0] / _userData[532] * DEG2RAD);
|
||||
|
||||
writeScummVar(108, (int32)(cs * args[1] + sn * args[2]));
|
||||
writeScummVar(109, (int32)(cs * args[2] - sn * args[1]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32 LogicHErace::op_1140(int32 *args) {
|
||||
// This functions seems to perform some kind of projection: We project
|
||||
// the vector (arg2,arg3) onto the vector (arg0,arg1), but also apply
|
||||
// some kind of distortion factor ?!?
|
||||
double x = args[2], y = args[3];
|
||||
|
||||
// We start by normalizing the vector described by arg2 and arg3.
|
||||
// So compute its length and divide the x and y coordinates
|
||||
const double sq = sqrt(x*x + y*y);
|
||||
x /= sq;
|
||||
y /= sq;
|
||||
|
||||
// Compute the scalar product of the vectors (arg0,arg1) and (x,y)
|
||||
const double scalarProduct = x * args[0] + y * args[1];
|
||||
|
||||
// Finally compute the projection of (arg2,arg3) onto (arg0,arg1)
|
||||
double projX = args[0] - 2 * scalarProduct * x;
|
||||
double projY = args[1] - 2 * scalarProduct * y;
|
||||
|
||||
projX = projX * 20.0 / 23.0; // FIXME: Why is this here?
|
||||
|
||||
writeScummVar(108, (int32)projX);
|
||||
|
||||
if (args[3] >= 0) // FIXME: Why is this here?
|
||||
projY = projY * 5.0 / 6.0;
|
||||
|
||||
writeScummVar(109, (int32)projY);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LogicHErace::op_sub1(float arg) {
|
||||
// Setup a rotation matrix
|
||||
_userDataD[10] = _userDataD[12] = _userDataD[14] = _userDataD[16] = 0;
|
||||
_userDataD[13] = 1;
|
||||
|
||||
_userDataD[9] = cos(arg * DEG2RAD);
|
||||
_userDataD[15] = sin(arg * DEG2RAD);
|
||||
_userDataD[11] = -_userDataD[15];
|
||||
_userDataD[17] = _userDataD[9];
|
||||
}
|
||||
|
||||
void LogicHErace::op_sub2(float arg) {
|
||||
// Setup a rotation matrix -- but it is NEVER USED!
|
||||
_userDataD[20] = _userDataD[21] = _userDataD[24] = _userDataD[25] = 0;
|
||||
_userDataD[26] = 1;
|
||||
|
||||
_userDataD[19] = sin(arg * DEG2RAD);
|
||||
_userDataD[18] = cos(arg * DEG2RAD);
|
||||
_userDataD[21] = -_userDataD[19];
|
||||
_userDataD[22] = _userDataD[18];
|
||||
}
|
||||
|
||||
void LogicHErace::op_sub3(float arg) {
|
||||
// Setup a rotation matrix -- but it is NEVER USED!
|
||||
_userDataD[1] = _userDataD[2] = _userDataD[3] = _userDataD[6] = 0;
|
||||
_userDataD[0] = 1;
|
||||
|
||||
_userDataD[4] = cos(arg * DEG2RAD);
|
||||
_userDataD[5] = sin(arg * DEG2RAD);
|
||||
_userDataD[7] = -_userDataD[5];
|
||||
_userDataD[8] = _userDataD[4];
|
||||
}
|
||||
|
||||
LogicHE *makeLogicHErace(ScummEngine_v90he *vm) {
|
||||
return new LogicHErace(vm);
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
1211
engines/scumm/he/logic/soccer.cpp
Normal file
1211
engines/scumm/he/logic/soccer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user