M4: Simplify globals array holding pointers, gr_series.cpp sysfile pointer

This commit is contained in:
Paul Gilbert 2023-07-20 19:19:31 -07:00 committed by Eugene Sandulenko
parent 5cb61c4e22
commit 57860d338f
15 changed files with 77 additions and 113 deletions

View File

@ -75,6 +75,8 @@ Vars::Vars() {
Inventory *inv = new Inventory();
_inventory = inv;
Common::fill(&_globals[0], &_globals[GLB_SHARED_VARS], 0);
}
Vars::~Vars() {

View File

@ -23,10 +23,4 @@
namespace M4 {
Globals::Globals() {
Common::fill(&_numData[0], &_numData[GLB_SCRATCH_VARS], 0);
Common::fill(&_ptrData[0], &_ptrData[GLB_SCRATCH_VARS], (void *)nullptr);
Common::fill(&_isPtr[0], &_isPtr[GLB_SHARED_VARS], false);
}
} // namespace M4

View File

@ -78,76 +78,12 @@ enum {
GLB_TEMP_31 = 37,
GLB_TEMP_32 = 38,
GLB_SCRATCH_VARS = 7, // 19-16 globals reserved for the compiler
GLB_SCRATCH_VARS = 7, // 19-16 globals reserved for the compiler
GLB_USER_VARS = 17 // 17+ globals for the applications programmer
};
constexpr int GLB_SHARED_VARS = 256;
/**
* Globals array class.
* This design is complicated by the fact that the original sometimes used it
* to store pointers as well as numbers, assuming they were 32-bits. Because of this,
* the new Globals class has to support both
*/
class Globals {
struct Entry {
private:
uint32 &_numValue;
void *&_ptrValue;
bool &_isPtr;
public:
Entry(uint32 &numValue, void *&ptrValue, bool &isPtr) :
_numValue(numValue), _ptrValue(ptrValue), _isPtr(isPtr) {
}
operator uint32() const {
assert(!_isPtr);
return _numValue;
}
template<class T>
operator T *() const {
assert(_isPtr);
return (T *)_ptrValue;
}
Entry &operator=(uint32 val) {
_isPtr = false;
_numValue = val;
return *this;
}
template<class T>
Entry &operator=(T *val) {
_isPtr = true;
_ptrValue = val;
return *this;
}
};
private:
frac16 _numData[GLB_SHARED_VARS];
void *_ptrData[GLB_SHARED_VARS];
bool _isPtr[GLB_SCRATCH_VARS];
public:
Globals();
/**
* Dummy operator to allow for original code that did !globals to see if
* the globals array had been created
*/
bool operator!() const { return false; }
/**
* Accesses the numeric array. Needed by several wscript methods
*/
frac16 *getData() {
return _numData;
}
Entry operator[](uint idx) {
assert(idx < GLB_SHARED_VARS);
return Entry(_numData[idx], _ptrData[idx], _isPtr[idx]);
}
};
} // namespace M4
#endif

View File

@ -67,7 +67,7 @@ void f_stream_Shutdown(void) {
}
}
strmRequest *f_stream_Open(StreamFile *srcFile, int32 fileOffset, int32 strmMinBuffSize, int32 strmBuffSize,
strmRequest *f_stream_Open(SysFile *srcFile, int32 fileOffset, int32 strmMinBuffSize, int32 strmBuffSize,
int32 numBlocksToRead, int32 *blockSizeArray, int32 initialRead, bool wrapStream) {
strmRequest *newStream;
@ -168,7 +168,6 @@ got_mem:
// Check if we are to initially read the stream
if (initialRead > 0) {
// If the blockSizeArray exists, then initialRead is the number of blocks to read
if (newStream->blockSizeArray) {
// Calculate the total number of bytes to read in initially
@ -204,7 +203,7 @@ got_mem:
// Read in the initial bytes to read
//bytesRead = fread((void*)newStream->strmHead, 1, bytesToRead, newStream->srcFile);
bufferHandle = newStream->strmHead;
bytesRead = newStream->srcFile->read((Handle)&bufferHandle, bytesToRead);
bytesRead = newStream->srcFile->read((MemHandle)&bufferHandle, bytesToRead);
//did we actually read that many? If not, close the file
if (bytesRead < bytesToRead) {
@ -358,7 +357,7 @@ int32 f_stream_Read(strmRequest *myStream, uint8 **dest, int32 numBytes) {
// Read in the bytesNeeded
bufferHandle = myStream->strmHead;
bytesRead = myStream->srcFile->read((Handle)&bufferHandle, bytesNeeded);
bytesRead = myStream->srcFile->read((MemHandle)&bufferHandle, bytesNeeded);
if (bytesRead < bytesNeeded) {
// If we could not read that much in, close the srcFile
@ -473,7 +472,7 @@ void f_stream_Process(int32 numToProcess) {
((!buffWrap) && (bytesAvail >= nextReadSize))) {
// Read the bytes into the stream buffer
bufferHandle = myStream->strmHead;
bytesRead = myStream->srcFile->read((Handle)&bufferHandle, nextReadSize);
bytesRead = myStream->srcFile->read((MemHandle)&bufferHandle, nextReadSize);
// If we could not read that much in, close the srcFile
if (bytesRead < nextReadSize) {
@ -504,7 +503,7 @@ void f_stream_Process(int32 numToProcess) {
// Read the bytes into the stream buffer
//bytesRead = (int32)fread((void*)myStream->strmBuff, 1, nextReadSize, myStream->srcFile);
bufferHandle = myStream->strmBuff;
bytesRead = myStream->srcFile->read((Handle)&bufferHandle, nextReadSize);
bytesRead = myStream->srcFile->read((MemHandle)&bufferHandle, nextReadSize);
// If we could not read that much in, close the srcFile
if (bytesRead < nextReadSize) {
@ -529,7 +528,7 @@ void f_stream_Process(int32 numToProcess) {
// Read into the end of the buffer
bufferHandle = myStream->strmHead;
bytesRead = (int32)myStream->srcFile->read((Handle)&bufferHandle, buffEndBytesAvail);
bytesRead = (int32)myStream->srcFile->read((MemHandle)&bufferHandle, buffEndBytesAvail);
// If we could not read that much in, close the srcFile and update the head pointer
if (bytesRead < buffEndBytesAvail) {
@ -544,7 +543,7 @@ void f_stream_Process(int32 numToProcess) {
// Read into the beginning of the buffer
bufferHandle = myStream->strmBuff;
bytesRead = myStream->srcFile->read((Handle)&bufferHandle, nextReadSize - buffEndBytesAvail);
bytesRead = myStream->srcFile->read((MemHandle)&bufferHandle, nextReadSize - buffEndBytesAvail);
// If we could not read that much in, close the srcFile
if (bytesRead < (nextReadSize - buffEndBytesAvail)) {

View File

@ -23,6 +23,7 @@
#define M4_FILEIO_FSTREAM_H
#include "common/file.h"
#include "m4/fileio/sys_file.h"
#include "m4/mem/reloc.h"
#include "m4/m4_types.h"
@ -44,7 +45,7 @@ public:
struct strmRequest {
strmRequest *next;
strmRequest *prev;
StreamFile *srcFile;
SysFile *srcFile;
int32 strmSize;
MemHandle strmHandle;
uint8 *strmBuff;
@ -62,7 +63,7 @@ struct strmRequest {
extern bool f_stream_Init();
extern void f_stream_Shutdown();
extern strmRequest *f_stream_Open(StreamFile *srcFile, int32 fileOffset, int32 strmMinBuffSize, int32 strmBuffSize,
extern strmRequest *f_stream_Open(SysFile *srcFile, int32 fileOffset, int32 strmMinBuffSize, int32 strmBuffSize,
int32 numBlocksToRead, int32 *blockSizeArray, int32 initialRead, bool wrapStream);
extern int32 f_stream_Read(strmRequest *myStream, uint8 **dest, int32 numBytes);
extern void f_stream_Close(strmRequest *myStream);

View File

@ -551,7 +551,7 @@ bool SysFile::seek(uint32 pos) {
term_message("fail to fseek");
last_head_pos = rs->pos();
curr_hag_record->hag_pos = curr_hash_record.offset + pos; // change file position
curr_hag_record->hag_pos = curr_hash_record.offset + pos; // Change file position
return true;
} else {
@ -560,6 +560,29 @@ bool SysFile::seek(uint32 pos) {
}
}
bool SysFile::seek_ahead(int32 amount) {
if (!_G(hag).hag_flag) {
return rs()->seek(amount, SEEK_CUR);
} else {
if (hag_success) {
Common::SeekableReadStream *rs = dynamic_cast<Common::SeekableReadStream *>(curr_hag_record->hag_fp);
assert(rs);
if (!rs->seek(amount, SEEK_CUR))
term_message("fail to fseek");
last_head_pos = rs->pos();
curr_hag_record->hag_pos += amount; // Change file position
return true;
} else {
return false;
}
}
}
uint32 SysFile::read(MemHandle bufferHandle) {
int32 bytesToRead;

View File

@ -112,6 +112,11 @@ public:
*/
bool seek(uint32 pos);
/**
* Seek ahaead by a given amount
*/
bool seek_ahead(int32 amount);
/**
* Read data
*/

View File

@ -71,7 +71,7 @@ machine *series_stream(const char *seriesName, int32 frameRate, int32 layer, int
_G(globals)[GLB_TEMP_1] = frameRate << 16;
// Store the SysFile pointer
_G(globals)[GLB_TEMP_4] = sysFile;
_G(globals)[GLB_TEMP_4] = (intptr_t)sysFile;
// Set the callback trigger
_G(globals)[GLB_TEMP_5] = kernel_trigger_create(trigger);

View File

@ -39,7 +39,12 @@ namespace M4 {
typedef void *Ptr;
typedef void *Handle;
typedef uint32 frac16;
/**
* This needs to be intptr_t in ScummVM because series_stream in gr_series.cpp stores
* a pointer as a global. On some systems size(ptr) > sizeof(int)
*/
typedef intptr_t frac16;
typedef uint32 ulong;
typedef uint32 quadchar;
typedef uint32 trigraph;

View File

@ -88,7 +88,7 @@ bool Vars::init() {
gr_font_set(_font_inter);
if (_cheat_keys_enabled) {
if (!dbg_ws_init(_kernel.start_up_with_dbg_ws, _font_tiny_prop, _globals.getData()))
if (!dbg_ws_init(_kernel.start_up_with_dbg_ws, _font_tiny_prop, _globals))
error(FL, 'DWIF');
}
@ -229,7 +229,7 @@ void Vars::fire_up_gui() {
bool Vars::woodscript_init() {
if (!InitWSAssets())
return false;
if (!ws_Initialize(_G(globals).getData()))
if (!ws_Initialize(_G(globals)))
return false;
return true;

View File

@ -95,7 +95,7 @@ public:
Hag_Statics _hag;
SceneDef _currentSceneDef;
Scene_list _scene_list;
Globals _globals;
frac16 _globals[GLB_SHARED_VARS];
Player _player;
PlayerInfo _player_info;
Resources _resources;

View File

@ -1247,7 +1247,7 @@ static void op_OPEN_STREAM_SS(Anim8 *myAnim8) {
ShowCCB(myCCB);
myCCB->flags |= CCB_SKIP;
if (!ws_OpenSSstream((StreamFile *)(*_GWS(myArg1)), myAnim8)) {
if (!ws_OpenSSstream((SysFile *)(*_GWS(myArg1)), myAnim8)) {
ws_Error(myAnim8->myMachine, ERR_SEQU, 0x0258, "open_ss_stream() failed.");
}

View File

@ -1494,26 +1494,26 @@ int32 ws_GetDATACount(uint32 hash) {
}
static int32 GetSSHeaderInfo(StreamFile *stream, uint32 **data, RGB8 *myPalette) {
static int32 GetSSHeaderInfo(SysFile *sysFile, uint32 **data, RGB8 *myPalette) {
uint32 celsType, celsSize, numColors, *myColors;
uint32 *tempPtr, i, j, header, format;
int32 numCels, dataOffset;
bool byteSwap;
void *handlebuffer;
if (!stream) {
if (!sysFile) {
ws_LogErrorMsg(FL, "nullptr FILE POINTER given.");
return -1;
}
// Read in the series header and the format number
handlebuffer = &header;
if (!(*stream).read((Handle)&handlebuffer, 4)) {
if (!(*sysFile).read(&handlebuffer, 4)) {
ws_LogErrorMsg(FL, "Unable to read series header.");
return -1;
}
handlebuffer = &format;
if (!(*stream).read((Handle)&handlebuffer, 4)) {
if (!(*sysFile).read(&handlebuffer, 4)) {
ws_LogErrorMsg(FL, "Unable to read series format.");
return -1;
}
@ -1532,23 +1532,22 @@ static int32 GetSSHeaderInfo(StreamFile *stream, uint32 **data, RGB8 *myPalette)
// Read in the SS chunk type - either PAL or SS info
handlebuffer = &celsType;
if (!(*stream).read((Handle)&handlebuffer, 4)) {
if (!(*sysFile).read(&handlebuffer, 4)) {
ws_LogErrorMsg(FL, "Unable to read series chunk type.");
return -1;
}
if ((celsType == CELS__PAL) || (celsType == CELS_LAP_)) {
//PAL info, read in the size of the PAL chunk
// PAL info, read in the size of the PAL chunk
handlebuffer = &celsSize;
if (!(*stream).read((Handle)&handlebuffer, 4)) {
if (!(*sysFile).read(&handlebuffer, 4)) {
ws_LogErrorMsg(FL, "Unable to read series chunk size.");
return -1;
}
// Now read in the number of colors to be inserted into the PAL
handlebuffer = &numColors;
if (!(*stream).read((Handle)&handlebuffer, 4)) {
if (!(*sysFile).read(&handlebuffer, 4)) {
ws_LogErrorMsg(FL, "Unable to read number of colors in PAL chunk.");
return -1;
}
@ -1571,7 +1570,7 @@ static int32 GetSSHeaderInfo(StreamFile *stream, uint32 **data, RGB8 *myPalette)
// Read in the color info into a temp buffer
handlebuffer = myColors;
if (!(*stream).read((Handle)&handlebuffer, numColors << 2)) {
if (!(*sysFile).read(&handlebuffer, numColors << 2)) {
ws_LogErrorMsg(FL, "Failed to read in the PAL color info.");
return -1;
}
@ -1587,7 +1586,7 @@ static int32 GetSSHeaderInfo(StreamFile *stream, uint32 **data, RGB8 *myPalette)
}
}
//If we have a place to store the color info
// If we have a place to store the color info
if (myPalette) {
tempPtr = (uint32 *)(&myColors[0]);
for (i = 0; i < numColors; i++) {
@ -1605,7 +1604,7 @@ static int32 GetSSHeaderInfo(StreamFile *stream, uint32 **data, RGB8 *myPalette)
// Read in the next chunk type
handlebuffer = &celsType;
if (!(*stream).read((Handle)&handlebuffer, 4)) {
if (!(*sysFile).read(&handlebuffer, 4)) {
ws_LogErrorMsg(FL, "Failed to read in series chunk type.");
return -1;
}
@ -1619,7 +1618,7 @@ static int32 GetSSHeaderInfo(StreamFile *stream, uint32 **data, RGB8 *myPalette)
// Read in the size of the entire chunk
handlebuffer = &celsSize;
if (!(*stream).read((Handle)&handlebuffer, 4)) {
if (!(*sysFile).read(&handlebuffer, 4)) {
ws_LogErrorMsg(FL, "Failed to read in series chunk size.");
return -1;
}
@ -1631,14 +1630,14 @@ static int32 GetSSHeaderInfo(StreamFile *stream, uint32 **data, RGB8 *myPalette)
// *data contains header + offsets, therefore, we must scan ahead
// and find out how many cels are here...
if (!(*stream).seek_ahead((CELS_COUNT - CELS_SRC_SIZE - 1) << 2)) {
if (!(*sysFile).seek_ahead((CELS_COUNT - CELS_SRC_SIZE - 1) << 2)) {
ws_LogErrorMsg(FL, "Failed to seek ahead in the stream.");
return -1;
}
// Read how many sprites are in the series
handlebuffer = &numCels;
if (!(*stream).read((Handle)&handlebuffer, 4)) {
if (!(*sysFile).read(&handlebuffer, 4)) {
ws_LogErrorMsg(FL, "Failed to read the number of sprites in the series.");
return -1;
}
@ -1649,7 +1648,7 @@ static int32 GetSSHeaderInfo(StreamFile *stream, uint32 **data, RGB8 *myPalette)
}
// Now, seek backwards to where we left off
if (!(*stream).seek_ahead((CELS_SRC_SIZE - CELS_COUNT) * 4)) {
if (!(*sysFile).seek_ahead((CELS_SRC_SIZE - CELS_COUNT) * 4)) {
ws_LogErrorMsg(FL, "Failed to seek backwards in the stream.");
return -1;
}
@ -1663,7 +1662,7 @@ static int32 GetSSHeaderInfo(StreamFile *stream, uint32 **data, RGB8 *myPalette)
// Read in the series header and the sprite offset table
// Since we already read in celsType and celsSize, SS_HEAD_SIZE-2
handlebuffer = &((*data)[2]);
if (!(*stream).read((Handle)&handlebuffer, (SS_HEAD_SIZE + numCels - 2) << 2)) {
if (!(*sysFile).read(&handlebuffer, (SS_HEAD_SIZE + numCels - 2) << 2)) {
ws_LogErrorMsg(FL, "Failed to read the series header and the sprite offset table.");
return -1;
}
@ -1681,11 +1680,11 @@ static int32 GetSSHeaderInfo(StreamFile *stream, uint32 **data, RGB8 *myPalette)
}
// Find out how far into the stream we are, and return that value
dataOffset = (*stream).get_pos();
dataOffset = (*sysFile).get_pos();
return dataOffset;
}
bool ws_OpenSSstream(StreamFile *streamFile, Anim8 *anim8) {
bool ws_OpenSSstream(SysFile *sysFile, Anim8 *anim8) {
CCB *myCCB;
frac16 *myRegs;
uint32 *celsPtr, *offsets;
@ -1694,7 +1693,7 @@ bool ws_OpenSSstream(StreamFile *streamFile, Anim8 *anim8) {
uint32 maxFrameSize;
// Verify the parameters
if (!streamFile || !anim8 || !anim8->myCCB) {
if (!sysFile || !anim8 || !anim8->myCCB) {
ws_LogErrorMsg(FL, "SysFile* streamFile invalid.");
return false;
}
@ -1704,7 +1703,7 @@ bool ws_OpenSSstream(StreamFile *streamFile, Anim8 *anim8) {
ssDataOffset = 0;
// Read in the SS stream header
if ((ssDataOffset = GetSSHeaderInfo(streamFile, &(myCCB->streamSSHeader), &_G(master_palette)[0])) <= 0) {
if ((ssDataOffset = GetSSHeaderInfo(sysFile, &(myCCB->streamSSHeader), &_G(master_palette)[0])) <= 0) {
return false;
}
@ -1751,7 +1750,7 @@ bool ws_OpenSSstream(StreamFile *streamFile, Anim8 *anim8) {
term_message("Biggest frame was: %ld, size: %ld bytes (compressed)", obesest_frame, maxFrameSize);
// Access the streamer to recognize the new client
if ((myCCB->myStream = (void *)f_stream_Open(streamFile, ssDataOffset, maxFrameSize, maxFrameSize << 4, numSprites, (int32 *)offsets, 4, false)) == nullptr) {
if ((myCCB->myStream = (void *)f_stream_Open(sysFile, ssDataOffset, maxFrameSize, maxFrameSize << 4, numSprites, (int32 *)offsets, 4, false)) == nullptr) {
ws_LogErrorMsg(FL, "Failed to open a stream.");
return false;
}

View File

@ -24,7 +24,7 @@
#define M4_WSCRIPT_WS_LOAD_H
#include "m4/m4_types.h"
#include "m4/fileio/fstream.h"
#include "m4/fileio/sys_file.h"
#include "m4/mem/reloc.h"
#include "m4/wscript/ws_machine.h"
#include "m4/wscript/ws_univ.h"
@ -104,7 +104,7 @@ extern int32 LoadSpriteSeriesDirect(const char *assetName, MemHandle *seriesHand
extern M4sprite *CreateSprite(MemHandle resourceHandle, int32 handleOffset, int32 index, M4sprite *mySprite, bool *streamSeries);
// WOODSCRIPT STREAMING API
extern bool ws_OpenSSstream(StreamFile *streamFile, Anim8 *anim8);
extern bool ws_OpenSSstream(SysFile *streamFile, Anim8 *anim8);
extern bool ws_GetNextSSstreamCel(Anim8 *anim8);
extern void ws_CloseSSstream(CCB *myCCB);

View File

@ -1045,7 +1045,7 @@ static bool SearchMsgList(uint32 msgHash, uint32 msgValue, machine *recvM, int32
// Search through the message list
while (myMsg && (!found)) {
// Check if we've found the msg we're looking for
if ((myMsg->msgHash == msgHash) && (myMsg->msgValue == msgValue)) {
if ((myMsg->msgHash == msgHash) && ((uint32)myMsg->msgValue == msgValue)) {
// Set found bool
found = true;