Fixed some of the memory leaks and Clang warnings.

DrMemory and Valgrind work with regular debug builds.
This commit is contained in:
Muzychenko Andrey 2021-09-14 15:33:18 +03:00
parent 28e2417ef9
commit c5b7c0ad16
25 changed files with 74 additions and 97 deletions

View file

@ -1,3 +0,0 @@
rc /Fo.\DrMem\SpaceCadetPinball.res ".\SpaceCadetPinball\SpaceCadetPinball.rc"
cl /Zi /MT /MP /EHsc /O /Ob0 /cgthreads4 /Fo.\DrMem\ /Fe.\DrMem\myapp.exe ".\SpaceCadetPinball\*.cpp" Comctl32.lib Winmm.lib Htmlhelp.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ".\DrMem\SpaceCadetPinball.res"

View file

@ -28,7 +28,7 @@ Compile with Visual Studio; tested with 2019.
On Linux:\ On Linux:\
Install devel packages for `SDL2` and `SDL2_mixer`.\ Install devel packages for `SDL2` and `SDL2_mixer`.\
Compile with CMake; tested with GCC 10. Compile with CMake; tested with GCC 10, Clang 11.
**Plans:** **Plans:**
* ~~Decompile original game~~ * ~~Decompile original game~~

View file

@ -44,9 +44,9 @@ void Sound::PlaySound(Mix_Chunk* wavePtr, int minChannel, int maxChannel, unsign
Mix_PlayChannel(-1, wavePtr, loops); Mix_PlayChannel(-1, wavePtr, loops);
} }
Mix_Chunk* Sound::LoadWaveFile(LPCSTR lpName) Mix_Chunk* Sound::LoadWaveFile(std::string lpName)
{ {
return Mix_LoadWAV(lpName); return Mix_LoadWAV(lpName.c_str());
} }
void Sound::FreeSound(Mix_Chunk* wave) void Sound::FreeSound(Mix_Chunk* wave)

View file

@ -10,7 +10,7 @@ public:
static void Deactivate(); static void Deactivate();
static void Close(); static void Close();
static void PlaySound(Mix_Chunk* wavePtr, int minChannel, int maxChannel, unsigned int dwFlags, int16_t loops); static void PlaySound(Mix_Chunk* wavePtr, int minChannel, int maxChannel, unsigned int dwFlags, int16_t loops);
static Mix_Chunk* LoadWaveFile(LPCSTR lpName); static Mix_Chunk* LoadWaveFile(std::string lpName);
static void FreeSound(Mix_Chunk* wave); static void FreeSound(Mix_Chunk* wave);
private: private:
static int num_channels; static int num_channels;

View file

@ -29,22 +29,22 @@ TEdgeManager::~TEdgeManager()
int TEdgeManager::box_x(float x) int TEdgeManager::box_x(float x)
{ {
return static_cast<int>((max(0, min(floor((x - X) * AdvanceXInv), (MaxBoxX - 1))))); return std::max(0, std::min(static_cast<int>(floor((x - X) * AdvanceXInv)), MaxBoxX - 1));
} }
int TEdgeManager::box_y(float y) int TEdgeManager::box_y(float y)
{ {
return static_cast<int>((max(0, min(floor((y - Y) * AdvanceYInv), (MaxBoxY - 1))))); return std::max(0, std::min(static_cast<int>(floor((y - Y) * AdvanceYInv)), MaxBoxY - 1));
} }
int TEdgeManager::increment_box_x(int x) int TEdgeManager::increment_box_x(int x)
{ {
return min(x + 1, MaxBoxX - 1); return std::min(x + 1, MaxBoxX - 1);
} }
int TEdgeManager::increment_box_y(int y) int TEdgeManager::increment_box_y(int y)
{ {
return min(y + 1, MaxBoxY - 1); return std::min(y + 1, MaxBoxY - 1);
} }
void TEdgeManager::add_edge_to_box(int x, int y, TEdgeSegment* edge) void TEdgeManager::add_edge_to_box(int x, int y, TEdgeSegment* edge)

View file

@ -78,7 +78,7 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
auto distance1 = sqrt(dy * dy + dx * dx) + table->CollisionCompOffset + vecT1->Z; auto distance1 = sqrt(dy * dy + dx * dx) + table->CollisionCompOffset + vecT1->Z;
DistanceDivSq = distance1 * distance1; DistanceDivSq = distance1 * distance1;
float bmpCoef = min(BmpCoef1, BmpCoef2); float bmpCoef = std::min(BmpCoef1, BmpCoef2);
auto distance = maths::Distance(vecT1, vecT2); auto distance = maths::Distance(vecT1, vecT2);
CollisionTimeAdvance = bmpCoef / (distance / CircleT1Radius + distance / CircleT1Radius); CollisionTimeAdvance = bmpCoef / (distance / CircleT1Radius + distance / CircleT1Radius);
@ -428,7 +428,7 @@ float TFlipperEdge::flipper_angle(float timeNow)
else else
angle = 1.0; angle = 1.0;
angle = min(1, max(angle, 0)); angle = std::min(1.0f, std::max(angle, 0.0f));
if (FlipperFlag == 2) if (FlipperFlag == 2)
angle = 1.0f - angle; angle = 1.0f - angle;
return angle * AngleMax; return angle * AngleMax;

View file

@ -90,10 +90,10 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
auto pVec2 = reinterpret_cast<vector_type*>(&plane->V2); auto pVec2 = reinterpret_cast<vector_type*>(&plane->V2);
auto pVec3 = reinterpret_cast<vector_type*>(&plane->V3); auto pVec3 = reinterpret_cast<vector_type*>(&plane->V3);
xMin = min(min(min(plane->V3.X, plane->V1.X), plane->V2.X), xMin); xMin = std::min(std::min(std::min(plane->V3.X, plane->V1.X), plane->V2.X), xMin);
yMin = min(min(min(plane->V3.Y, plane->V1.Y), plane->V2.Y), xMin); // Sic yMin = std::min(std::min(std::min(plane->V3.Y, plane->V1.Y), plane->V2.Y), xMin); // Sic
xMax = max(max(max(plane->V3.X, plane->V1.X), plane->V2.X), xMin); xMax = std::max(std::max(std::max(plane->V3.X, plane->V1.X), plane->V2.X), xMin);
yMax = max(max(max(plane->V3.Y, plane->V1.Y), plane->V2.Y), xMin); yMax = std::max(std::max(std::max(plane->V3.Y, plane->V1.Y), plane->V2.Y), xMin);
vector_type* pointOrder[4] = {pVec1, pVec2, pVec3, pVec1}; vector_type* pointOrder[4] = {pVec1, pVec2, pVec3, pVec1};
for (auto pt = 0; pt < 3; pt++) for (auto pt = 0; pt < 3; pt++)

View file

@ -71,10 +71,10 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
Boost = 15.0f; Boost = 15.0f;
auto visArrPtr = visual.FloatArr; auto visArrPtr = visual.FloatArr;
Unknown1F = min(visArrPtr[0], min(visArrPtr[2], visArrPtr[4])); Unknown1F = std::min(visArrPtr[0], std::min(visArrPtr[2], visArrPtr[4]));
Unknown2F = min(visArrPtr[1], min(visArrPtr[3], visArrPtr[5])); Unknown2F = std::min(visArrPtr[1], std::min(visArrPtr[3], visArrPtr[5]));
Unknown3F = max(visArrPtr[0], max(visArrPtr[2], visArrPtr[4])); Unknown3F = std::max(visArrPtr[0], std::max(visArrPtr[2], visArrPtr[4]));
Unknown4F = max(visArrPtr[1], max(visArrPtr[3], visArrPtr[5])); Unknown4F = std::max(visArrPtr[1], std::max(visArrPtr[3], visArrPtr[5]));
auto a2 = Unknown4F - Unknown2F; auto a2 = Unknown4F - Unknown2F;
auto a1 = Unknown3F - Unknown1F; auto a1 = Unknown3F - Unknown1F;
edge_manager = new TEdgeManager(Unknown1F, Unknown2F, a1, a2); edge_manager = new TEdgeManager(Unknown1F, Unknown2F, a1, a2);

View file

@ -183,7 +183,7 @@ void TTextBox::Draw()
} }
else if (Message1->TimeLeft() >= -2.0f) else if (Message1->TimeLeft() >= -2.0f)
{ {
Timer = timer::set(max(Message1->TimeLeft(), 0.25f), this, TimerExpired); Timer = timer::set(std::max(Message1->TimeLeft(), 0.25f), this, TimerExpired);
display = true; display = true;
break; break;
} }

View file

@ -1929,7 +1929,7 @@ void control::GravityWellKickoutControl(int code, TPinballComponent* caller)
} }
else else
{ {
snprintf(Buffer, sizeof Buffer, pinball::get_rc_string(45, 0)); snprintf(Buffer, sizeof Buffer, "%s", pinball::get_rc_string(45, 0));
} }
control_info_text_box_tag.Component->Display(Buffer, 2.0); control_info_text_box_tag.Component->Display(Buffer, 2.0);
control_lite62_tag.Component->Message(4, 0.0); control_lite62_tag.Component->Message(4, 0.0);

View file

@ -93,12 +93,12 @@ int fullscrn::GetResolution()
return resolution; return resolution;
} }
void fullscrn::SetResolution(int resolution) void fullscrn::SetResolution(int value)
{ {
if (!pb::FullTiltMode) if (!pb::FullTiltMode)
resolution = 0; value = 0;
assertm(resolution >= 0 && resolution <= 2, "Resolution value out of bounds"); assertm(value >= 0 && value <= 2, "Resolution value out of bounds");
fullscrn::resolution = resolution; resolution = value;
} }
int fullscrn::GetMaxResolution() int fullscrn::GetMaxResolution()
@ -106,10 +106,10 @@ int fullscrn::GetMaxResolution()
return maxResolution; return maxResolution;
} }
void fullscrn::SetMaxResolution(int resolution) void fullscrn::SetMaxResolution(int value)
{ {
assertm(resolution >= 0 && resolution <= 2, "Resolution value out of bounds"); assertm(value >= 0 && value <= 2, "Resolution value out of bounds");
maxResolution = resolution; maxResolution = value;
} }
int fullscrn::get_max_supported_resolution() int fullscrn::get_max_supported_resolution()
@ -153,7 +153,7 @@ void fullscrn::window_size_changed()
if (options::Options.UniformScaling) if (options::Options.UniformScaling)
{ {
ScaleY = ScaleX = min(ScaleX, ScaleY); ScaleY = ScaleX = std::min(ScaleX, ScaleY);
OffsetX = static_cast<int>(floor((width - res->TableWidth * ScaleX) / 2)); OffsetX = static_cast<int>(floor((width - res->TableWidth * ScaleX) / 2));
OffsetY = static_cast<int>(floor((height - res->TableHeight * ScaleY) / 2)); OffsetY = static_cast<int>(floor((height - res->TableHeight * ScaleY) / 2));
} }

View file

@ -25,9 +25,9 @@ public:
static int set_screen_mode(int isFullscreen); static int set_screen_mode(int isFullscreen);
static void activate(int flag); static void activate(int flag);
static int GetResolution(); static int GetResolution();
static void SetResolution(int resolution); static void SetResolution(int value);
static int GetMaxResolution(); static int GetMaxResolution();
static void SetMaxResolution(int resolution); static void SetMaxResolution(int value);
static int get_max_supported_resolution(); static int get_max_supported_resolution();
static int get_screen_resolution(int* width, int* height); static int get_screen_resolution(int* width, int* height);
static void window_size_changed(); static void window_size_changed();

View file

@ -1,9 +1,7 @@
#include "pch.h" #include "pch.h"
#include "gdrv.h" #include "gdrv.h"
#include "fullscrn.h"
#include "memory.h" #include "memory.h"
#include "render.h"
#include "winmain.h" #include "winmain.h"
SDL_Texture* gdrv::vScreenTex = nullptr; SDL_Texture* gdrv::vScreenTex = nullptr;
@ -239,8 +237,8 @@ int gdrv::StretchDIBitsScaled(int xSrc, int ySrc, int xDst, int yDst,
int width, int height, gdrv_bitmap8* bmp) int width, int height, gdrv_bitmap8* bmp)
{ {
// Y is inverted, X normal left to right // Y is inverted, X normal left to right
ySrc = max(0, min(bmp->Height - height, bmp->Height)) - ySrc; ySrc = std::max(0, std::min(bmp->Height - height, bmp->Height)) - ySrc;
yDst = max(0, min(vScreenHeight - height, vScreenHeight)) - yDst; yDst = std::max(0, std::min(vScreenHeight - height, vScreenHeight)) - yDst;
// Negative dst == positive src offset // Negative dst == positive src offset
if (xDst < 0) if (xDst < 0)
@ -255,15 +253,15 @@ int gdrv::StretchDIBitsScaled(int xSrc, int ySrc, int xDst, int yDst,
} }
// Clamp out of bounds rectangles // Clamp out of bounds rectangles
xSrc = max(0, min(xSrc, bmp->Width)); xSrc = std::max(0, std::min(xSrc, bmp->Width));
ySrc = max(0, min(ySrc, bmp->Height)); ySrc = std::max(0, std::min(ySrc, bmp->Height));
if (xSrc + width > bmp->Width) if (xSrc + width > bmp->Width)
width = bmp->Width - xSrc; width = bmp->Width - xSrc;
if (ySrc + height > bmp->Height) if (ySrc + height > bmp->Height)
height = bmp->Height - ySrc; height = bmp->Height - ySrc;
xDst = max(0, min(xDst, vScreenWidth)); xDst = std::max(0, std::min(xDst, vScreenWidth));
yDst = max(0, min(yDst, vScreenHeight)); yDst = std::max(0, std::min(yDst, vScreenHeight));
if (xDst + width > vScreenWidth) if (xDst + width > vScreenWidth)
width = vScreenWidth - xDst; width = vScreenWidth - xDst;
if (yDst + height > vScreenHeight) if (yDst + height > vScreenHeight)
@ -288,7 +286,6 @@ int gdrv::StretchDIBitsScaled(int xSrc, int ySrc, int xDst, int yDst,
void gdrv::BlitScreen() void gdrv::BlitScreen()
{ {
auto bmp = &render::vscreen;
unsigned char* lockedPixels = nullptr; unsigned char* lockedPixels = nullptr;
int pitch = 0; int pitch = 0;
SDL_LockTexture SDL_LockTexture

View file

@ -1,11 +1,8 @@
#include "pch.h" #include "pch.h"
#include "high_score.h" #include "high_score.h"
#include "fullscrn.h"
#include "memory.h" #include "memory.h"
#include "options.h" #include "options.h"
#include "resource.h"
#include "winmain.h"
int high_score::dlg_enter_name; int high_score::dlg_enter_name;
int high_score::dlg_score; int high_score::dlg_score;

View file

@ -145,7 +145,6 @@ int loader::get_sound_id(int groupIndex)
datFieldTypes::ShortValue)); datFieldTypes::ShortValue));
if (value && *value == 202) if (value && *value == 202)
{ {
char filePath[300]{};
std::string fileName = partman::field(loader_table, soundGroupId, datFieldTypes::String); std::string fileName = partman::field(loader_table, soundGroupId, datFieldTypes::String);
// File name is in lower case, while game data is in upper case. // File name is in lower case, while game data is in upper case.
@ -157,9 +156,8 @@ int loader::get_sound_id(int groupIndex)
fileName.insert(0, "SOUND"); fileName.insert(0, "SOUND");
} }
pinball::make_path_name(filePath, fileName.c_str()); auto filePath = pinball::make_path_name(fileName);
auto file = fopen(filePath.c_str(), "rb");
FILE* file = fopen(filePath, "rb");
if (file) if (file)
{ {
fread(&wavHeader, 1, sizeof wavHeader, file); fread(&wavHeader, 1, sizeof wavHeader, file);

View file

@ -7,7 +7,10 @@
Mix_Music* midi::currentMidi; Mix_Music* midi::currentMidi;
#define FOURCC(a,b,c,d) ( (uint32_t) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) ) constexpr uint32_t FOURCC(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
return static_cast<uint32_t>((d << 24) | (c << 16) | (b << 8) | a);
}
int ToVariableLen(uint32_t value, uint32_t& dst) int ToVariableLen(uint32_t value, uint32_t& dst)
{ {
@ -107,7 +110,7 @@ void midi::music_shutdown_ft()
Mix_Music* midi::load_track(std::string fileName) Mix_Music* midi::load_track(std::string fileName)
{ {
char filePath[256]; auto origFile = fileName;
// File name is in lower case, while game data is in upper case. // File name is in lower case, while game data is in upper case.
std::transform(fileName.begin(), fileName.end(), fileName.begin(), [](unsigned char c) { return std::toupper(c); }); std::transform(fileName.begin(), fileName.end(), fileName.begin(), [](unsigned char c) { return std::toupper(c); });
@ -119,24 +122,22 @@ Mix_Music* midi::load_track(std::string fileName)
} }
fileName += ".MDS"; fileName += ".MDS";
pinball::make_path_name(filePath, fileName.c_str(), 254u); auto filePath = pinball::make_path_name(fileName);
auto midi = MdsToMidi(filePath); auto midi = MdsToMidi(filePath);
if (!midi) if (!midi)
return nullptr; return nullptr;
// Dump converted MIDI file
/*origFile += ".midi";
FILE* fileHandle = fopen(origFile.c_str(), "wb");
fwrite(midi->data(), 1, midi->size(), fileHandle);
fclose(fileHandle);*/
auto rw = SDL_RWFromMem(midi->data(), static_cast<int>(midi->size())); auto rw = SDL_RWFromMem(midi->data(), static_cast<int>(midi->size()));
auto audio = Mix_LoadMUS_RW(rw, 0); auto audio = Mix_LoadMUS_RW(rw, 1); // This call seems to leak memory no matter what.
SDL_FreeRW(rw);
delete midi; delete midi;
if (!audio) if (!audio)
return nullptr; return nullptr;
// Dump converted MIDI file
/*strncpy(fileName2, fileName, sizeof fileName2);
strcat(fileName2, ".midi");
FILE* fileHandle = fopen(fileName2, "wb");
fwrite(midi->data(), 1, midi->size(), fileHandle);
fclose(fileHandle);*/
TrackList->Add(audio); TrackList->Add(audio);
return audio; return audio;
@ -181,9 +182,9 @@ int midi::stop_ft()
/// </summary> /// </summary>
/// <param name="file">Path to .MDS file</param> /// <param name="file">Path to .MDS file</param>
/// <returns>Vector that contains MIDI file</returns> /// <returns>Vector that contains MIDI file</returns>
std::vector<uint8_t>* midi::MdsToMidi(char* file) std::vector<uint8_t>* midi::MdsToMidi(std::string file)
{ {
FILE* fileHandle = fopen(file, "rb"); auto fileHandle = fopen(file.c_str(), "rb");
if (!fileHandle) if (!fileHandle)
return nullptr; return nullptr;
@ -328,7 +329,9 @@ std::vector<uint8_t>* midi::MdsToMidi(char* file)
midiBytes.insert(midiBytes.end(), metaEndTrack, metaEndTrack + 4); midiBytes.insert(midiBytes.end(), metaEndTrack, metaEndTrack + 4);
// Set final MTrk size // Set final MTrk size
*(uint32_t*)&midiBytes[lengthPos] = SwapByteOrderInt((uint32_t)midiBytes.size() - sizeof header - sizeof track); auto lengthBE = SwapByteOrderInt((uint32_t)midiBytes.size() - sizeof header - sizeof track);
auto lengthData = reinterpret_cast<const uint8_t*>(&lengthBE);
std::copy_n(lengthData, 4, midiBytes.begin() + lengthPos);
} }
while (false); while (false);

View file

@ -102,5 +102,5 @@ private:
static Mix_Music* load_track(std::string fileName); static Mix_Music* load_track(std::string fileName);
static int play_ft(Mix_Music* midi); static int play_ft(Mix_Music* midi);
static int stop_ft(); static int stop_ft();
static std::vector<uint8_t>* MdsToMidi(char* file); static std::vector<uint8_t>* MdsToMidi(std::string file);
}; };

View file

@ -15,7 +15,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool ful
dat8BitBmpHeader bmpHeader{}; dat8BitBmpHeader bmpHeader{};
dat16BitBmpHeader zMapHeader{}; dat16BitBmpHeader zMapHeader{};
FILE* fileHandle = fopen(lpFileName, "rb"); auto fileHandle = fopen(lpFileName, "rb");
if (fileHandle == nullptr) if (fileHandle == nullptr)
return nullptr; return nullptr;
fread(&header, 1, sizeof header, fileHandle); fread(&header, 1, sizeof header, fileHandle);

View file

@ -36,13 +36,10 @@ bool pb::FullTiltMode = false;
int pb::init() int pb::init()
{ {
float projMat[12], zMin = 0, zScaler = 0; float projMat[12], zMin = 0, zScaler = 0;
char datFileName[300];
char dataFilePath[300];
++memory::critical_allocation; ++memory::critical_allocation;
strncpy(datFileName, winmain::DatFileName, sizeof datFileName); auto dataFilePath = pinball::make_path_name(winmain::DatFileName);
pinball::make_path_name(dataFilePath, datFileName, 300); record_table = partman::load_records(dataFilePath.c_str(), fullscrn::GetResolution(), FullTiltMode);
record_table = partman::load_records(dataFilePath, fullscrn::GetResolution(), FullTiltMode);
auto useBmpFont = 0; auto useBmpFont = 0;
pinball::get_rc_int(158, &useBmpFont); pinball::get_rc_int(158, &useBmpFont);

View file

@ -42,12 +42,6 @@ typedef uint32_t DWORD;
typedef char* LPSTR; typedef char* LPSTR;
typedef const char* LPCSTR; typedef const char* LPCSTR;
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
//
//#define min(a,b) (((a)<(b))?(a):(b))
//#define max(a,b) (((a)>(b))?(a):(b))
constexpr char PathSeparator = constexpr char PathSeparator =
#ifdef _WIN32 #ifdef _WIN32
'\\'; '\\';
@ -70,7 +64,7 @@ inline size_t pgm_save(int width, int height, char* data, FILE* outfile)
inline float RandFloat() inline float RandFloat()
{ {
return static_cast<float>(std::rand()) / (RAND_MAX); return static_cast<float>(std::rand() / static_cast<double>(RAND_MAX));
} }
#endif //PCH_H #endif //PCH_H

View file

@ -246,15 +246,7 @@ int pinball::get_rc_int(int uID, int* dst)
return 1; return 1;
} }
int pinball::make_path_name(LPSTR lpFilename, LPCSTR lpString2, int nSize) std::string pinball::make_path_name(const std::string& fileName)
{ {
auto base_path = SDL_GetBasePath(); return winmain::BasePath + fileName;
if (!base_path)
{
strcat(lpFilename,"?");
return 1;
}
strncpy(lpFilename, base_path, nSize);
strcat(lpFilename, lpString2);
return 0;
} }

View file

@ -18,7 +18,7 @@ public:
static char* get_rc_string(int uID, int a2); static char* get_rc_string(int uID, int a2);
static int get_rc_int(int uID, int* dst); static int get_rc_int(int uID, int* dst);
static int make_path_name(LPSTR lpFilename, LPCSTR lpString2, int nSize = 0x12Cu); static std::string make_path_name(const std::string& fileName);
private: private:
static char getRcBuffer[256 * 6]; static char getRcBuffer[256 * 6];
static int rc_string_slot; static int rc_string_slot;

View file

@ -288,13 +288,13 @@ void score::string_format(int score, char* str)
if (static_cast<int>(scoreMillions) <= 0) if (static_cast<int>(scoreMillions) <= 0)
{ {
if (score % 1000000 / 1000 <= 0) if (score % 1000000 / 1000 <= 0)
snprintf(str, 36, "%ld", score); snprintf(str, 36, "%d", score);
else else
snprintf(str, 36, "%ld%s%03ld", score % 1000000 / 1000, separator, score % 1000); snprintf(str, 36, "%d%s%03d", score % 1000000 / 1000, separator, score % 1000);
} }
else else
{ {
snprintf(str, 36, "%ld%s%03ld%s%03ld", scoreMillions, separator, score % 1000000 / 1000, separator, snprintf(str, 36, "%d%s%03d%s%03d", scoreMillions, separator, score % 1000000 / 1000, separator,
score % 1000); score % 1000);
} }
} }
@ -303,7 +303,7 @@ void score::string_format(int score, char* str)
snprintf( snprintf(
str, str,
36, 36,
"%ld%s%03ld%s%03ld%s%03ld", "%d%s%03d%s%03d%s%03d",
score / 1000000000, score / 1000000000,
separator, separator,
scoreMillions, scoreMillions,

View file

@ -39,6 +39,7 @@ bool winmain::ShowImGuiDemo = false;
bool winmain::LaunchBallEnabled = true; bool winmain::LaunchBallEnabled = true;
bool winmain::HighScoresEnabled = true; bool winmain::HighScoresEnabled = true;
bool winmain::DemoActive = false; bool winmain::DemoActive = false;
char* winmain::BasePath;
uint32_t timeGetTimeAlt() uint32_t timeGetTimeAlt()
@ -64,15 +65,15 @@ int winmain::WinMain(LPCSTR lpCmdLine)
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not initialize SDL2", SDL_GetError(), nullptr); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not initialize SDL2", SDL_GetError(), nullptr);
return 1; return 1;
} }
BasePath = SDL_GetBasePath();
pinball::quickFlag = strstr(lpCmdLine, "-quick") != nullptr; pinball::quickFlag = strstr(lpCmdLine, "-quick") != nullptr;
auto regSpaceCadet = pinball::get_rc_string(166, 0); auto regSpaceCadet = pinball::get_rc_string(166, 0);
options::get_string(regSpaceCadet, "Pinball Data", DatFileName, pinball::get_rc_string(168, 0), 300); options::get_string(regSpaceCadet, "Pinball Data", DatFileName, pinball::get_rc_string(168, 0), 300);
/*Check for full tilt .dat file and switch to it automatically*/ /*Check for full tilt .dat file and switch to it automatically*/
char cadetFilePath[300]{}; auto cadetFilePath = pinball::make_path_name("CADET.DAT");
pinball::make_path_name(cadetFilePath, "CADET.DAT", 300); auto cadetDat = fopen(cadetFilePath.c_str(), "r");
FILE* cadetDat = fopen(cadetFilePath, "r");
if (cadetDat) if (cadetDat)
{ {
fclose(cadetDat); fclose(cadetDat);
@ -270,7 +271,7 @@ int winmain::WinMain(LPCSTR lpCmdLine)
if (elapsedMs >= TargetFrameTime) if (elapsedMs >= TargetFrameTime)
{ {
// Keep track of remainder, limited to one frame time. // Keep track of remainder, limited to one frame time.
frameStart = frameEnd - min(elapsedMs - TargetFrameTime, TargetFrameTime) / sdlTimerResMs; frameStart = frameEnd - std::min(elapsedMs - TargetFrameTime, TargetFrameTime) / sdlTimerResMs;
ImGui_ImplSDL2_NewFrame(); ImGui_ImplSDL2_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();

View file

@ -12,6 +12,7 @@ public:
static bool LaunchBallEnabled; static bool LaunchBallEnabled;
static bool HighScoresEnabled; static bool HighScoresEnabled;
static bool DemoActive; static bool DemoActive;
static char* BasePath;
static int WinMain(LPCSTR lpCmdLine); static int WinMain(LPCSTR lpCmdLine);
static int event_handler(const SDL_Event* event); static int event_handler(const SDL_Event* event);