diff options
| -rw-r--r-- | engines/scumm/he/logic_he.cpp | 154 | ||||
| -rw-r--r-- | engines/scumm/he/logic_he.h | 32 | 
2 files changed, 151 insertions, 35 deletions
diff --git a/engines/scumm/he/logic_he.cpp b/engines/scumm/he/logic_he.cpp index 33647634d3..70931b19b6 100644 --- a/engines/scumm/he/logic_he.cpp +++ b/engines/scumm/he/logic_he.cpp @@ -823,12 +823,18 @@ int LogicHEsoccer::versionID() {  }  LogicHEsoccer::LogicHEsoccer(ScummEngine_v90he *vm) : LogicHE(vm) { -	_userData = (byte *)calloc(6921, 1); // Allocate user data -	_userDataD = (double *)_userData; +	_userDataD = (double *)calloc(1732, sizeof(double)); +	_intArray1 = 0; +	_intArray2 = 0; +	_intArraysAllocated = false; +	_array1013 = 0; +	_array1013Allocated = false;  }  LogicHEsoccer::~LogicHEsoccer() { -	free(_userData); +	free(_userDataD); +	op_1020(); // clear int arrays +	delete[] _array1013;  }  int32 LogicHEsoccer::dispatch(int op, int numArgs, int32 *args) { @@ -864,10 +870,18 @@ int32 LogicHEsoccer::dispatch(int op, int numArgs, int32 *args) {  		res = op_1013(args[0], args[1], args[2]);  		break; +	case 1019: +		res = op_1019(args); +		break; +  	case 1020:  		res = op_1020();  		break; +	case 1021: +		res = op_1021(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); +		break; +  	case 8221968:  		// Someone had a fun and used his birthday as opcode number  		res = getFromArray(args[0], args[1], args[2]); @@ -882,7 +896,7 @@ int32 LogicHEsoccer::dispatch(int op, int numArgs, int32 *args) {  }  void LogicHEsoccer::beforeBootScript() { -	if (_userData[6869]) +	if (_intArraysAllocated)  		op_1020();  	_userDataD[530] = 0; @@ -890,7 +904,7 @@ void LogicHEsoccer::beforeBootScript() {  void LogicHEsoccer::initOnce() {  	// The original sets some paths here that we don't need to worry about -	_userData[6881] = 0; +	_array1013Allocated = false;  	_userDataD[530] = 0;  } @@ -968,11 +982,11 @@ int LogicHEsoccer::op_1006(int32 a1, int32 a2, int32 a3, int32 a4) {  }  int LogicHEsoccer::op_1007(int32 *args) { -	// TODO: Used when the HE logo is shown +	// Used when the HE logo is shown  	// This initializes the _userDataD fields that are used in op_1006/op_1011 +	_intArraysAllocated = false;  	double v14 = (double)args[0] * 0.01; -	_userData[6873] = 0;  	double v13 = (double)args[2] * 0.01;  	_userDataD[524] = v14;  	double v12 = atan2(v13, v14); @@ -990,25 +1004,20 @@ int LogicHEsoccer::op_1007(int32 *args) {  	_userDataD[523] = _userDataD[527] / _userDataD[519];  	_userDataD[518] = v13; -	*((uint32 *)_userData[6857]) = 0; -	memset(_userData + 2737, 0, 4 * 1024); -	for (int i = 0; i < 146; i++) -		_userDataD[538 + i] = 0; -	_userData[2736] = 0; +	// Clear both byte arrays +	memset(_byteArray1, 0, 4096); +	memset(_byteArray2, 0, 585); -	if (*((uint32 *)_userData[6885]) == 0 ) +	if (_array1013Allocated == 0 )  		op_1013(4, args[8], args[9]);  	return 1;  } -#if 0 -// TODO: Used by several opcodes  // Returns the square root of the sum of the squares of the arguments -static inline double fsqrtSquare(double a1, double a2, double a3) { +static inline double sqrtSquare(double a1, double a2, double a3) {  	return sqrt(a1 * a1 + a2 * a2 + a3 * a3); -} -#endif +}	  int LogicHEsoccer::op_1008(int32 *args) {  	// TODO: Used during a match (kicking?) @@ -1164,6 +1173,7 @@ void LogicHEsoccer::op_1011_sub(int32 a1, int32 a2, int32 a3, int32 a4) {  int LogicHEsoccer::op_1012(int32 *args) {  	// Used after op_1019  	// This function activates startOfFrame() to call op_1011 +	// (Possibly field parameters?)  	_userDataD[530] = (args[0] != 0) ? 1 : 0;  	_userDataD[531] = args[1]; @@ -1176,8 +1186,6 @@ int LogicHEsoccer::op_1012(int32 *args) {  	return 1;  } -#if 0 -// TODO: Used by op_1013  // Some strange power operation, ignores negative exponents  static inline double u32Pow(float a1, int a2) {  	if (a2 < 0) @@ -1190,34 +1198,126 @@ static inline double u32Pow(float a1, int a2) {  	return v4;  } -#endif + +int LogicHEsoccer::op_sub5(int a1, int a2, int a3) { +	byte *v9 = _array1013 + 44 * a2; + +	*((uint32 *)v9 + 4) = a3; +	*((uint32 *)v9) = a2; + +	if (a1 > 2) { +		// Casual observation: 585 is also the size of _byteArray2 +		*((uint32 *)v9 + 40) = 8 * a2 - 585; +		for (int i = 0; i < 8; i++) +			*((uint32 *)v9 + 4 * i + 8) = 0xffffffff; +	} else { +		for (int i = 0; i < 8; i++) +			*((uint32 *)v9 + 4 * i + 8) = op_sub5(a1 + 1, i + 8 * a2 + 1, a2); +	} + +	return a2; +}  int LogicHEsoccer::op_1013(int32 a1, int32 a2, int32 a3) { -	// TODO: Called by op_1007 +	// Creates _array1013 for *some* purpose +	// _array1013Temp is used again op_1014 for some reason... +	// Seems to be used in op_1015 + +	int v4 = (int)((1.0 - u32Pow(8.0, 4)) / -7.0); + +	_array1013 = new byte[v4 * 44]; +	memset(_array1013, 0, v4 * 44); +	_array1013Allocated = true; +	memset(_array1013Temp, 0, 44); + +	for (int i = 0; i < 8; i++) +		_array1013Temp[i + 2] = op_sub5(1, i + 1, 0); + +	// Yes, this is not endian-safe, but should not matter since we're +	// not saving/loading the data anywhere +	memcpy(_array1013, _array1013Temp, 44);  	return 1;  } -int LogicHEsoccer::op_1014(int32 *args) { +int LogicHEsoccer::op_1014(int32 a1, int32 a2, int32 a3, int32 a4, int32 a5, int32 a6, int32 a7, int32 a8, int32 a9, int32 a10, int32 a11, int32 a12, int32 a13, int32 a14) {  	// TODO: Used many times during a match +	// And called from op_1008!  	return 1;  }  int LogicHEsoccer::op_1019(int32 *args) { -	// TODO: Used at the beginning of a match +	// Used at the beginning of a match +	// Initializes some arrays. Player positions? + +	// These two arrays are used in op_1014 and op_1015 +	for (int i = 0; i < 4096; i++) +		_byteArray1[i] = getFromArray(args[1], 0, i); + +	for (int i = 0; i < 585; i++) +		_byteArray2[i] = getFromArray(args[0], 0, i); + +	// Deallocate the two integer arrays +	if (_intArraysAllocated) +		op_1020(); + +	// Reallocate them +	_intArray1 = new uint32[1008]; +	_intArray2 = new uint32[168]; +	_intArraysAllocated = true; + +	memset(_intArray1, 0, 4 * 4); +	memset(_intArray2, 0, 24 * 4); + +	// These two arrays are used in op_1015 +	for (int i = 0; i < 42; i++) { +		for (int j = 0; j < 24; j++) +			_intArray1[j + 24 * i] = getFromArray(args[3], 0, j + 24 * i); + +		for (int j = 0; j < 4; j++) +			_intArray2[j + 4 * i] = getFromArray(args[2], 0, j + 4 * i); +	}  	return 1;  }  int LogicHEsoccer::op_1020() { -	// TODO: Called by several other opcodes. Possibly "stop play"? +	// Deallocate integer arrays +	// The arrays can be allocated in op_1015 or op_1019 + +	delete[] _intArray1; _intArray1 = 0; +	delete[] _intArray2; _intArray2 = 0; +	_intArraysAllocated = false;  	return 1;  } -int LogicHEsoccer::op_1021(int32 *args) { -	// TODO: Used during a match (ball movement?) +int LogicHEsoccer::op_1021(int32 a1, int32 a2, int32 a3, int32 a4, int32 a5, int32 a6, int32 a7) { +	// Used during a match (ball movement?) +	// Also called from op_1008 + +	int v10; +	if (a4 && a5) +		v10 = (int)(((double)a2 - (double)a5 * (double)a1 / (double)a4) * -1.0 * (double)a4 / (double)a5); +	else +		v10 = a1; + +	int v9; +	if (a6 && a5) +		v9 = (int)(((double)a2 - (double)a5 * (double)a3 / (double)a6) * -1.0 * (double)a6 / (double)a5); +	else +		v9 = a3; + +	// The final argument chooses whether to store the results for op_1008 or +	// store them in SCUMM variables. +	if (a7) { +		_var1021[0] = v10; +		_var1021[1] = v9; +	} else { +		writeScummVar(108, v10); +		writeScummVar(109, v9); +	}  	return 1;  } diff --git a/engines/scumm/he/logic_he.h b/engines/scumm/he/logic_he.h index c2ea2b8ec6..d097d37e75 100644 --- a/engines/scumm/he/logic_he.h +++ b/engines/scumm/he/logic_he.h @@ -111,7 +111,6 @@ private:  class LogicHEsoccer : public LogicHE {  private: -	byte *_userData;  	double *_userDataD;  public: @@ -130,21 +129,38 @@ private:  	int op_1002(int32 *args);  	int op_1003(int32 *args);  	int op_1004(int32 *args); -	// op_1006 can be called from other opcodes!  	int op_1006(int32 a1, int32 a2, int32 a3, int32 a4);  	int op_1007(int32 *args);  	int op_1008(int32 *args); -	// op_1011 can be called from other opcodes!  	int op_1011(int32 a1, int32 a2, int32 a3, int32 a4, int32 a5); -	void op_1011_sub(int32 a1, int32 a2, int32 a3, int32 a4);  	int op_1012(int32 *args); -	// op_1013 can be called from other opcodes!  	int op_1013(int32 a1, int32 a2, int32 a3); -	int op_1014(int32 *args); +	int op_1014(int32 a1, int32 a2, int32 a3, int32 a4, int32 a5, int32 a6, int32 a7, int32 a8, int32 a9, int32 a10, int32 a11, int32 a12, int32 a13, int32 a14);  	int op_1019(int32 *args); -	// op_1020 can be called from other opcodes!  	int op_1020(); -	int op_1021(int32 *args); +	int op_1021(int32 a1, int32 a2, int32 a3, int32 a4, int32 a5, int32 a6, int32 a7); + +	// Two integer arrays are used between some functions +	// Originally, these pointers were in _userData, but we keep them separate +	// Also, doing it that would break things on non 32-bit systems... +	bool _intArraysAllocated; +	uint32 *_intArray1, *_intArray2; + +	// op_1007 allocates some arrays +	// they're then filled by op_1019 +	byte _byteArray1[4096], _byteArray2[585]; + +	// op_1011 has a subfunction +	void op_1011_sub(int32 a1, int32 a2, int32 a3, int32 a4); + +	// op_1013 creates some array, purpose unknown +	bool _array1013Allocated; +	byte *_array1013; +	uint32 _array1013Temp[11]; +	int op_sub5(int a1, int a2, int a3); + +	// op_1021 can (optionally) set two variables for use in op_1008 +	uint32 _var1021[2];  };  class LogicHEbaseball2001 : public LogicHE {  | 
