Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

## Question and Answers
### How to update Submarine Titans to version 1.1?
> Window: https://steamcommunity.com/sharedfiles/filedetails/?id=2129291420 \
> Windows: https://steamcommunity.com/sharedfiles/filedetails/?id=2129291420 \
> Linux: See [PROTON-v1_0-v_1_1.md](PROTON-v1_0-v1_1.md)

### Why am I getting MSVCP140.dll errors?
Expand All @@ -59,7 +59,7 @@

### How do I use the mission skip cheat?
> Load the mission you want to skip and write 'orbiton' without quotes in the chatbox. \
> Exit to the menu and select a random campaign to start the next mission. \
> Exit to the menu and select a random campaign to start the next mission.

### How do I uninstall the patch?
> Deleting SubTitans.dll will disable the in-game patches.
Expand Down
2 changes: 1 addition & 1 deletion subtitans/iddraw4.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace DDraw {
uint32_t colorKeyCaps;
uint32_t effectCaps;
uint32_t effectAlphaCaps;
uint32_t palleteCaps;
uint32_t paletteCaps;
uint32_t stereoVisionCaps;
uint32_t alphaBltConstantBitDepth;
uint32_t alphaBltPixelBitDepth;
Expand Down
59 changes: 37 additions & 22 deletions subtitans/openglrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ uint32_t CreateShader(const char* fragmentShader)

char errorBuffer[1024 - 16];
glGetShaderInfoLog(vertexShaderId, sizeof(errorBuffer), NULL, errorBuffer);
GetLogger()->Error(errorBuffer);
GetLogger()->Error("%s", errorBuffer);

return 0;
}
Expand All @@ -337,7 +337,7 @@ uint32_t CreateShader(const char* fragmentShader)

char errorBuffer[1024 - 16];
glGetShaderInfoLog(fragmentShaderId, sizeof(errorBuffer), NULL, errorBuffer);
GetLogger()->Error(errorBuffer);
GetLogger()->Error("%s", errorBuffer);

return 0;
}
Expand All @@ -353,7 +353,7 @@ uint32_t CreateShader(const char* fragmentShader)

char errorBuffer[1024 - 16];
glGetProgramInfoLog(shaderProgramId, sizeof(errorBuffer), NULL, errorBuffer);
GetLogger()->Error(errorBuffer);
GetLogger()->Error("%s", errorBuffer);

return 0;
}
Expand Down Expand Up @@ -445,6 +445,17 @@ void OpenGLRenderer::Run()
glGenTextures(1, &surfaceTextureId);
glGenTextures(1, &paletteTextureId);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, surfaceTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, paletteTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);

glViewport(0, 0, Global::MonitorWidth, Global::MonitorHeight);

uint32_t vboId = 0;
Expand All @@ -459,6 +470,9 @@ void OpenGLRenderer::Run()
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)(12 * sizeof(float)));

GetLogger()->Informational("%s %s\n", __FUNCTION__, "is running");

InitImGui();
Expand All @@ -474,6 +488,7 @@ void OpenGLRenderer::Run()
int32_t currentWidth = 0;
int32_t currentHeight = 0;
int32_t currentBitsPerPixel = 0;
bool refreshGLTexture = false;

Mutex.lock();
while (IsThreadRunning)
Expand All @@ -483,42 +498,39 @@ void OpenGLRenderer::Run()
uint32_t drawTime = timeGetTime();

// Clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT);

if (surfaceBuffer)
{
// Set images
// Upload the surface. Re-allocate only when the resolution or bit depth changed
if (currentBitsPerPixel == 8 && paletteBuffer)
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, surfaceTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, currentWidth, currentHeight, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, surfaceBuffer);
if (refreshGLTexture)
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, currentWidth, currentHeight, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, surfaceBuffer);
else
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, currentWidth, currentHeight, GL_RED_INTEGER, GL_UNSIGNED_BYTE, surfaceBuffer);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, paletteTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 1, 0, GL_BGRA, GL_UNSIGNED_BYTE, paletteBuffer);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 1, GL_BGRA, GL_UNSIGNED_BYTE, paletteBuffer);
}
else if (currentBitsPerPixel == 32)
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, surfaceTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, currentWidth, currentHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, surfaceBuffer);
if (refreshGLTexture)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, currentWidth, currentHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, surfaceBuffer);
else
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, currentWidth, currentHeight, GL_BGRA, GL_UNSIGNED_BYTE, surfaceBuffer);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
}

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)(12 * sizeof(float)));

glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
refreshGLTexture = false;
}

#ifdef _IMGUI_ENABLED
Expand Down Expand Up @@ -552,7 +564,7 @@ void OpenGLRenderer::Run()
continue;

// Prevent flickering caused by palette changes
if (PrimarySurface->PrimaryInvalid)
if (!PrimarySurface->IsPrimaryValid)
continue;

// Can't render without palette
Expand All @@ -567,6 +579,7 @@ void OpenGLRenderer::Run()

RecalculateGLSurface();
RecalculateSurface = false;
refreshGLTexture = true;
}
else if (RecalculateSurface)
{
Expand All @@ -580,6 +593,7 @@ void OpenGLRenderer::Run()

RecalculateGLSurface();
RecalculateSurface = false;
refreshGLTexture = true;
}

PrimarySurface->PrimaryDrawMutex.lock();
Expand All @@ -597,9 +611,6 @@ void OpenGLRenderer::Run()

PrimarySurface->PrimaryDrawMutex.unlock();

currentWidth = PrimarySurface->Width;
currentHeight = PrimarySurface->Height;

if (currentBitsPerPixel != PrimarySurface->BitsPerPixel)
{
// BBP switched
Expand All @@ -616,8 +627,12 @@ void OpenGLRenderer::Run()

glUniform1i(glGetUniformLocation(shaderProgram32BitId, "surface"), 0);
}

refreshGLTexture = true;
}

currentWidth = PrimarySurface->Width;
currentHeight = PrimarySurface->Height;
currentBitsPerPixel = PrimarySurface->BitsPerPixel;
}
Mutex.unlock();
Expand Down
14 changes: 13 additions & 1 deletion subtitans/palette.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,18 @@ uint32_t __stdcall Palette::GetEntries(uint32_t shouldBeZero, uint32_t index, ui
return ResultCode::InvalidArgument;
}

if (index > 255 || count > 256 - index)
{
GetLogger()->Error("%s %s index:%i count:%i\n", __FUNCTION__, "requested palette range is out of bounds", index, count);
return ResultCode::InvalidArgument;
}

Mutex.lock();

// BGR -> RGB
for (uint32_t i = 0; i < count; ++i)
{
const uint32_t pixel = RawPalette[i];
const uint32_t pixel = RawPalette[index + i];
result[i] = (pixel & 0xFF00FF00)
| ((pixel << 16) & 0x00FF0000)
| ((pixel >> 16) & 0x000000FF);
Expand All @@ -83,6 +89,12 @@ uint32_t __stdcall Palette::SetEntries(uint32_t shouldBeZero, uint32_t index, ui
return ResultCode::InvalidArgument;
}

if (index > 255 || count > 256 - index)
{
GetLogger()->Error("%s %s index:%i count:%i\n", __FUNCTION__, "requested palette range is out of bounds", index, count);
return ResultCode::InvalidArgument;
}

Mutex.lock();

// RGB -> BGR
Expand Down
4 changes: 2 additions & 2 deletions subtitans/pescalpel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static bool UpdateChecksum(const wchar_t* applicationPath, BYTE* base)
return false;
}

GetLogger()->Debug("Header sum: %i, Check sum: %i\n", &headerSum, &checkSum);
GetLogger()->Debug("Header sum: 0x%08X, Check sum: 0x%08X\n", headerSum, checkSum);

IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)base;
if (dos->e_magic != IMAGE_DOS_SIGNATURE)
Expand All @@ -81,7 +81,7 @@ static bool UpdateChecksum(const wchar_t* applicationPath, BYTE* base)
return false;
}

GetLogger()->Debug("PE header check sum: %i\n", nt->OptionalHeader.CheckSum);
GetLogger()->Debug("PE header check sum: 0x%08X\n", nt->OptionalHeader.CheckSum);

// Original PE contains a value of 0, GOG seems to contain an incorrect value?
// For now we'll just skip updating the check sum...
Expand Down
2 changes: 1 addition & 1 deletion subtitans/softwarerenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ void SoftwareRenderer::Run()
continue;

// Prevent flickering caused by palette changes
if (PrimarySurface->PrimaryInvalid)
if (!PrimarySurface->IsPrimaryValid)
continue;

if (PrimarySurface->BitsPerPixel == 8)
Expand Down
23 changes: 16 additions & 7 deletions subtitans/subtitans.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static void StackTrace()

while (ebpRegister != nullptr)
{
if ((uint32_t)ebpRegister >= (uint32_t)stackHighLimit || (uint32_t)ebpRegister < (uint32_t)stackLowLimit)
if ((uint32_t)ebpRegister + 8 >= (uint32_t)stackHighLimit || (uint32_t)ebpRegister < (uint32_t)stackLowLimit)
{
GetLogger()->Informational("Address out of range!\n");
break;
Expand All @@ -76,29 +76,38 @@ static void StackTrace()
&& _splitpath_s(modulePath, nullptr, 0, nullptr, 0, name, _MAX_FNAME, ext, _MAX_EXT) == 0)
{
modulePaths.push_back(std::make_pair(std::string(name) + ext, modulePath));
GetLogger()->Informational("[%i] Absolute 0x%04X Relative 0x%04X (%s%s)\n", depth++, returnAddress, returnAddress - (uint32_t)hMod, name, ext);
GetLogger()->Informational("[%i] Absolute 0x%08X Relative 0x%08X (%s%s)\n", depth++, returnAddress, returnAddress - (uint32_t)hMod, name, ext);
}
else
{
GetLogger()->Informational("[%i] Absolute 0x%04X Relative 0x%04X\n", depth++, returnAddress, returnAddress - (uint32_t)hMod);
GetLogger()->Informational("[%i] Absolute 0x%08X Relative 0x%08X\n", depth++, returnAddress, returnAddress - (uint32_t)hMod);
}
}
else
{
GetLogger()->Informational("[%i] Address 0x%04X\n", depth++, returnAddress);
GetLogger()->Informational("[%i] Address 0x%08X\n", depth++, returnAddress);
}

ebpRegister = (uint32_t*)(*ebpRegister);
if (ebpRegister == nullptr)
uint32_t* nextEbp = (uint32_t*)(*ebpRegister);
if ((uint32_t)nextEbp <= (uint32_t)ebpRegister)
{
if (nextEbp == nullptr)
GetLogger()->Informational("Reached base of stack\n");
else
GetLogger()->Informational("Possible stack corruption\n");

break;
}

ebpRegister = nextEbp;
}

GetLogger()->Informational("End of stack trace\n");

for (const auto& modulePath : modulePaths)
{
uint32_t checksum = File::CalculateChecksumA(modulePath.second.c_str());
GetLogger()->Informational("%s CRC32 %04X\n", modulePath.first.c_str(), checksum);
GetLogger()->Informational("%s CRC32 %08X\n", modulePath.first.c_str(), checksum);
}
}

Expand Down
Loading
Loading