Skip to content

Commit

Permalink
fix various engine inaccuracies
Browse files Browse the repository at this point in the history
  • Loading branch information
LittlePlanetCD committed Jul 21, 2024
1 parent d9b8afe commit 0fdac18
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 199 deletions.
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,6 @@ CXXFLAGS_ALL += $(CXXFLAGS) \
LDFLAGS_ALL = $(LDFLAGS)
LIBS_ALL += -pthread $(LIBS)

ifneq ($(FORCE_CASE_INSENSITIVE),)
CXXFLAGS_ALL += -DFORCE_CASE_INSENSITIVE
SOURCES += RSDKv4/fcaseopen.c
endif

ifeq ($(PROFILE),1)
CXXFLAGS_ALL += -pg -g -fno-inline-functions -fno-inline-functions-called-once -fno-optimize-sibling-calls -fno-default-inline
endif
Expand Down Expand Up @@ -121,6 +116,11 @@ SOURCES = \
RSDKv4/NativeObjects/All \
dependencies/all/theoraplay/theoraplay \
dependencies/all/tinyxml2/tinyxml2

ifneq ($(FORCE_CASE_INSENSITIVE),)
CXXFLAGS_ALL += -DFORCE_CASE_INSENSITIVE
SOURCES += RSDKv4/fcaseopen
endif

PKGSUFFIX ?= $(SUFFIX)

Expand Down
19 changes: 10 additions & 9 deletions RSDKv4/Drawing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2557,8 +2557,8 @@ void Draw3DFloorLayer(int layerID)
int layerZPos = layer->zpos;
int sinValue = sinM7LookupTable[layer->angle];
int cosValue = cosM7LookupTable[layer->angle];
byte *gfxLineBufferPtr = &gfxLineBuffer[((SCREEN_YSIZE / 2) + 12) * GFX_LINESIZE];
ushort *frameBufferPtr = &Engine.frameBuffer[132 * GFX_LINESIZE];
byte *gfxLineBufferPtr = &gfxLineBuffer[(SCREEN_YSIZE / 2) + 12];
ushort *frameBufferPtr = &Engine.frameBuffer[((SCREEN_YSIZE / 2) + 12) * GFX_LINESIZE];
int layerXPos = layer->xpos >> 4;
int ZBuffer = layerZPos >> 4;
for (int i = 4; i < 112; ++i) {
Expand Down Expand Up @@ -2612,7 +2612,7 @@ void Draw3DSkyLayer(int layerID)
ushort *frameBufferPtr = &Engine.frameBuffer[((SCREEN_YSIZE / 2) + 12) * GFX_LINESIZE];
ushort *bufferPtr = Engine.frameBuffer2x;
if (!drawStageGFXHQ)
bufferPtr = &Engine.frameBuffer[(SCREEN_YSIZE / 2) + 12];
bufferPtr = &Engine.frameBuffer[((SCREEN_YSIZE / 2) + 12) * GFX_LINESIZE];
byte *gfxLineBufferPtr = &gfxLineBuffer[((SCREEN_YSIZE / 2) + 12)];
int layerXPos = layer->xpos >> 4;
int layerZPos = layer->zpos >> 4;
Expand Down Expand Up @@ -2789,12 +2789,13 @@ void DrawTintRectangle(int XPos, int YPos, int width, int height)
height += YPos;
YPos = 0;
}
if (width <= 0 || height <= 0)

if (width < 0 || height < 0)
return;
int yOffset = GFX_LINESIZE - width;
for (ushort *frameBufferPtr = &Engine.frameBuffer[XPos + GFX_LINESIZE * YPos];; frameBufferPtr += yOffset) {
height--;
if (!height)
if (height < 0)
break;
int w = width;
while (w--) {
Expand Down Expand Up @@ -2865,7 +2866,7 @@ void DrawScaledTintMask(int direction, int XPos, int YPos, int pivotX, int pivot
int w = width;
while (w--) {
if (*gfxDataPtr > 0)
*frameBufferPtr = tintLookupTable[*gfxDataPtr];
*frameBufferPtr = tintLookupTable[*frameBufferPtr];
int offsetX = finalscaleX + roundXPos;
gfxDataPtr -= offsetX >> 11;
gfxPitch += offsetX >> 11;
Expand All @@ -2887,7 +2888,7 @@ void DrawScaledTintMask(int direction, int XPos, int YPos, int pivotX, int pivot
int w = width;
while (w--) {
if (*gfxData > 0)
*frameBufferPtr = tintLookupTable[*gfxData];
*frameBufferPtr = tintLookupTable[*frameBufferPtr];
int offsetX = finalscaleX + roundXPos;
gfxData += offsetX >> 11;
gfxPitch += offsetX >> 11;
Expand Down Expand Up @@ -4950,7 +4951,7 @@ void DrawTexturedFace(void *v, byte sheetID)
}
ushort *fbPtr = &frameBufferPtr[startX];
frameBufferPtr += GFX_LINESIZE;
int counter = posDifference + 1;
int counter = posDifference;
while (counter--) {
if (UPos < 0)
UPos = 0;
Expand Down Expand Up @@ -5176,7 +5177,7 @@ void DrawTextMenu(void *menu, int XPos, int YPos)

if (tMenu->selectionCount == 3) {
tMenu->selection2 = -1;
for (int i = 0; i < tMenu->selection1 + 1; ++i) {
for (int i = 0; i <= tMenu->selection1; ++i) {
if (tMenu->entryHighlight[i]) {
tMenu->selection2 = i;
}
Expand Down
2 changes: 1 addition & 1 deletion RSDKv4/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ void ProcessFrozenObjects()
default: break;
}

if (entity->type > OBJ_TYPE_BLANKOBJECT) {
if (processObjectFlag[objectEntityPos] && entity->type > OBJ_TYPE_BLANKOBJECT) {
ObjectScript *scriptInfo = &objectScriptList[entity->type];
if (scriptData[scriptInfo->eventMain.scriptCodePtr] > 0 && entity->priority == PRIORITY_ACTIVE_PAUSED)
ProcessScript(scriptInfo->eventMain.scriptCodePtr, scriptInfo->eventMain.jumpTablePtr, EVENT_MAIN);
Expand Down
4 changes: 2 additions & 2 deletions RSDKv4/Palette.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void SetLimitedFade(byte paletteID, byte R, byte G, byte B, ushort alpha, int st
return;

uint alpha2 = 0xFF - alpha;
for (int i = startIndex; i < endIndex; ++i) {
for (int i = startIndex; i <= endIndex; ++i) {
PACK_RGB888(activePalette[i], (byte)((ushort)(R * alpha + alpha2 * activePalette32[i].r) >> 8),
(byte)((ushort)(G * alpha + alpha2 * activePalette32[i].g) >> 8),
(byte)((ushort)(B * alpha + alpha2 * activePalette32[i].b) >> 8));
Expand All @@ -96,7 +96,7 @@ void SetPaletteFade(byte destPaletteID, byte srcPaletteA, byte srcPaletteB, usho
uint blendA = 0xFF - blendAmount;
ushort *dst = &fullPalette[destPaletteID][startIndex];
PaletteEntry *dst32 = &fullPalette32[destPaletteID][startIndex];
for (int l = startIndex; l < endIndex; ++l) {
for (int l = startIndex; l <= endIndex; ++l) {
*dst = PACK_RGB888((byte)((ushort)(fullPalette32[srcPaletteB][l].r * blendAmount + blendA * fullPalette32[srcPaletteA][l].r) >> 8),
(byte)((ushort)(fullPalette32[srcPaletteB][l].g * blendAmount + blendA * fullPalette32[srcPaletteA][l].g) >> 8),
(byte)((ushort)(fullPalette32[srcPaletteB][l].b * blendAmount + blendA * fullPalette32[srcPaletteA][l].b) >> 8));
Expand Down
157 changes: 113 additions & 44 deletions RSDKv4/Reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,19 @@ bool CheckRSDKFile(const char *filePath)

StrCopy(rsdkContainer.packNames[rsdkContainer.packCount], filePathBuffer);

ushort fileCount = 0;
fRead(&fileCount, 2, 1, cFileHandle);
byte b[4];
fRead(&b, 2, 1, cFileHandle);
ushort fileCount = (b[1] << 8) | (b[0] << 0);
for (int f = 0; f < fileCount; ++f) {
for (int y = 0; y < 16; y += 4) {
fRead(&rsdkContainer.files[f].hash[y + 3], 1, 1, cFileHandle);
fRead(&rsdkContainer.files[f].hash[y + 2], 1, 1, cFileHandle);
fRead(&rsdkContainer.files[f].hash[y + 1], 1, 1, cFileHandle);
fRead(&rsdkContainer.files[f].hash[y + 0], 1, 1, cFileHandle);
for (int y = 0; y < 4; ++y) {
fRead(b, 1, 4, cFileHandle);
rsdkContainer.files[f].hash[y] = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3] << 0);
}

fRead(&rsdkContainer.files[f].offset, 4, 1, cFileHandle);
fRead(&rsdkContainer.files[f].filesize, 4, 1, cFileHandle);
fRead(b, 4, 1, cFileHandle);
rsdkContainer.files[f].offset = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0] << 0);
fRead(b, 4, 1, cFileHandle);
rsdkContainer.files[f].filesize = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0] << 0);

rsdkContainer.files[f].encrypted = (rsdkContainer.files[f].filesize & 0x80000000);
rsdkContainer.files[f].filesize &= 0x7FFFFFFF;
Expand Down Expand Up @@ -102,17 +103,17 @@ bool CheckRSDKFile(const char *filePath)
int CheckFileInfo(const char *filepath)
{
char pathBuf[0x100];
StringLowerCase(pathBuf, filepath);
byte buffer[0x10];
StrCopy(pathBuf, filepath);
uint hash[4];
int len = StrLength(pathBuf);
GenerateMD5FromString(pathBuf, len, buffer);
GenerateMD5FromString(pathBuf, len, &hash[0], &hash[1], &hash[2], &hash[3]);

for (int f = 0; f < rsdkContainer.fileCount; ++f) {
RSDKFileInfo *file = &rsdkContainer.files[f];

bool match = true;
for (int h = 0; h < 0x10; ++h) {
if (buffer[h] != file->hash[h]) {
for (int h = 0; h < 4; ++h) {
if (hash[h] != file->hash[h]) {
match = false;
break;
}
Expand All @@ -124,6 +125,13 @@ int CheckFileInfo(const char *filepath)
}
return -1;
}

inline bool ends_with(std::string const &value, std::string const &ending)
{
if (ending.size() > value.size())
return false;
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
}
#endif

bool LoadFile(const char *filePath, FileInfo *fileInfo)
Expand All @@ -145,25 +153,31 @@ bool LoadFile(const char *filePath, FileInfo *fileInfo)
}

bool addPath = true;
if (activeMod != -1) {
char buf[0x100];
sprintf(buf, "%s", filePathBuf);
sprintf(filePathBuf, "%smods/%s/%s", modsPath, modList[activeMod].folder.c_str(), buf);
forceFolder = true;
addPath = false;
}
else {
for (int m = 0; m < modList.size(); ++m) {
if (modList[m].active) {
std::map<std::string, std::string>::const_iterator iter = modList[m].fileMap.find(pathLower);
if (iter != modList[m].fileMap.cend()) {
StrCopy(filePathBuf, iter->second.c_str());
forceFolder = true;
addPath = false;
break;
}
int m = activeMod != -1 ? activeMod : 0;
for (; m < modList.size(); ++m) {
if (modList[m].active) {
std::map<std::string, std::string>::const_iterator iter = modList[m].fileMap.find(pathLower);
if (iter != modList[m].fileMap.cend()) {
StrCopy(filePathBuf, iter->second.c_str());
forceFolder = true;
addPath = false;
break;
}
}
if (activeMod != -1)
break;
}

if (forceUseScripts && !forceFolder) {
if (std::string(filePathBuf).rfind("Data/Scripts/", 0) == 0 && ends_with(std::string(filePathBuf), "txt")) {
// is a script, since those dont exist normally, load them from "scripts/"
forceFolder = true;
Engine.usingDataFile = false;
addPath = true;
std::string fStr = std::string(filePathBuf);
fStr.erase(fStr.begin(), fStr.begin() + 5); // remove "Data/"
StrCopy(filePathBuf, fStr.c_str());
}
}
#endif

Expand All @@ -181,22 +195,70 @@ bool LoadFile(const char *filePath, FileInfo *fileInfo)

cFileHandle = NULL;
#if !RETRO_USE_ORIGINAL_CODE
if (CheckFileInfo(filePath) != -1 && !forceFolder) {
StringLowerCase(fileInfo->fileName, filePath);
StrCopy(fileName, fileInfo->fileName);

int fileIndex = CheckFileInfo(fileName);
if (fileIndex != -1 && !forceFolder) {
RSDKFileInfo *file = &rsdkContainer.files[fileIndex];
packID = file->packID;
cFileHandle = fOpen(rsdkContainer.packNames[file->packID], "rb");
if (cFileHandle) {
fSeek(cFileHandle, 0, SEEK_END);
fileSize = (int)fTell(cFileHandle);

vFileSize = file->filesize;
virtualFileOffset = file->offset;
readPos = file->offset;
readSize = 0;
bufferPosition = 0;
fSeek(cFileHandle, virtualFileOffset, SEEK_SET);

useEncryption = file->encrypted;
memset(fileInfo->encryptionStringA, 0, 0x10 * sizeof(byte));
memset(fileInfo->encryptionStringB, 0, 0x10 * sizeof(byte));
if (useEncryption) {
GenerateELoadKeys(vFileSize, (vFileSize >> 1) + 1);
eStringNo = (vFileSize & 0x1FC) >> 2;
eStringPosA = 0;
eStringPosB = 8;
eNybbleSwap = 0;
memcpy(fileInfo->encryptionStringA, encryptionStringA, 0x10 * sizeof(byte));
memcpy(fileInfo->encryptionStringB, encryptionStringB, 0x10 * sizeof(byte));
}

fileInfo->readPos = readPos;
fileInfo->fileSize = fileSize;
fileInfo->vfileSize = vFileSize;
fileInfo->virtualFileOffset = virtualFileOffset;
fileInfo->eStringNo = eStringNo;
fileInfo->eStringPosB = eStringPosB;
fileInfo->eStringPosA = eStringPosA;
fileInfo->eNybbleSwap = eNybbleSwap;
fileInfo->bufferPosition = bufferPosition;
fileInfo->useEncryption = useEncryption;
fileInfo->packID = packID;
fileInfo->usingDataPack = true;
PrintLog("Loaded Data File '%s'", filePath);

Engine.usingDataFile = true;

return true;
}
#else
if (Engine.usingDataFile) {
#endif
StringLowerCase(fileInfo->fileName, filePath);
StrCopy(fileName, fileInfo->fileName);
byte buffer[0x10];
uint hash[4];
int len = StrLength(fileInfo->fileName);
GenerateMD5FromString(fileInfo->fileName, len, buffer);
GenerateMD5FromString(fileInfo->fileName, len, &hash[0], &hash[1], &hash[2], &hash[3]);

for (int f = 0; f < rsdkContainer.fileCount; ++f) {
RSDKFileInfo *file = &rsdkContainer.files[f];

bool match = true;
for (int h = 0; h < 0x10; ++h) {
if (buffer[h] != file->hash[h]) {
for (int h = 0; h < 4; ++h) {
if (hash[h] != file->hash[h]) {
match = false;
break;
}
Expand Down Expand Up @@ -244,16 +306,13 @@ bool LoadFile(const char *filePath, FileInfo *fileInfo)
fileInfo->usingDataPack = true;
PrintLog("Loaded Data File '%s'", filePath);

#if !RETRO_USE_ORIGINAL_CODE
Engine.usingDataFile = true;
#endif

return true;
}
else {
break;
}
}
#endif
PrintLog("Couldn't load file '%s'", filePath);
return false;
}
Expand Down Expand Up @@ -291,31 +350,41 @@ bool LoadFile(const char *filePath, FileInfo *fileInfo)
void GenerateELoadKeys(uint key1, uint key2)
{
char buffer[0x20];
byte hash[0x10];
uint hash[0x4];

// StringA
ConvertIntegerToString(buffer, key1);
int len = StrLength(buffer);
GenerateMD5FromString(buffer, len, hash);
GenerateMD5FromString(buffer, len, &hash[0], &hash[1], &hash[2], &hash[3]);

#if !RETRO_USE_ORIGINAL_CODE
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j) encryptionStringA[i * 4 + j] = (hash[i] >> (8 * (j ^ 3))) & 0xFF;
#else
for (int y = 0; y < 0x10; y += 4) {
encryptionStringA[y + 3] = hash[y + 0];
encryptionStringA[y + 2] = hash[y + 1];
encryptionStringA[y + 1] = hash[y + 2];
encryptionStringA[y + 0] = hash[y + 3];
}
#endif

// StringB
ConvertIntegerToString(buffer, key2);
len = StrLength(buffer);
GenerateMD5FromString(buffer, len, hash);
GenerateMD5FromString(buffer, len, &hash[0], &hash[1], &hash[2], &hash[3]);

#if !RETRO_USE_ORIGINAL_CODE
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j) encryptionStringB[i * 4 + j] = (hash[i] >> (8 * (j ^ 3))) & 0xFF;
#else
for (int y = 0; y < 0x10; y += 4) {
encryptionStringB[y + 3] = hash[y + 0];
encryptionStringB[y + 2] = hash[y + 1];
encryptionStringB[y + 1] = hash[y + 2];
encryptionStringB[y + 0] = hash[y + 3];
}
#endif
}

const uint ENC_KEY_2 = 0x24924925;
Expand Down
2 changes: 1 addition & 1 deletion RSDKv4/Reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct FileInfo {
};

struct RSDKFileInfo {
byte hash[0x10];
uint hash[4];
int offset;
int filesize;
bool encrypted;
Expand Down
Loading

0 comments on commit 0fdac18

Please sign in to comment.