src: Change from using asprintf-based code to using std::string-based code

Signed-off-by: Gabriel Ravier <gabravier@gmail.com>
This commit is contained in:
Gabriel Ravier 2020-06-29 16:13:14 +02:00
parent 32a879ca58
commit 564d42dbd2
31 changed files with 99 additions and 398 deletions

View file

@ -171,14 +171,6 @@ add_executable(CSE2 WIN32
"src/Backends/Controller.h" "src/Backends/Controller.h"
"src/Backends/Misc.h" "src/Backends/Misc.h"
"src/Backends/Rendering.h" "src/Backends/Rendering.h"
"src/Helpers/Asprintf.cpp"
"src/Helpers/Asprintf.h"
"src/Helpers/Vasprintf.cpp"
"src/Helpers/Vasprintf.h"
"src/Helpers/FopenFormatted.cpp"
"src/Helpers/FopenFormatted.h"
"src/Helpers/Strdup.cpp"
"src/Helpers/Strdup.h"
) )
set(RESOURCES set(RESOURCES

View file

@ -416,12 +416,9 @@ void PutCampObject(void)
int CampLoop(void) int CampLoop(void)
{ {
RECT rcView = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT}; RECT rcView = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT};
int ret = enum_ESCRETURN_continue;
// Save the current script path (to restore it when we get out of the inventory) // Save the current script path (to restore it when we get out of the inventory)
char *old_script_path = GetTextScriptPath(); std::string old_script_path = GetTextScriptPath();
if (old_script_path == NULL)
return enum_ESCRETURN_exit;
// Load the inventory script // Load the inventory script
LoadTextScript2("ArmsItem.tsc"); LoadTextScript2("ArmsItem.tsc");
@ -452,11 +449,9 @@ int CampLoop(void)
switch (Call_Escape()) switch (Call_Escape())
{ {
case enum_ESCRETURN_exit: case enum_ESCRETURN_exit:
free(old_script_path);
return enum_ESCRETURN_exit; return enum_ESCRETURN_exit;
case enum_ESCRETURN_restart: case enum_ESCRETURN_restart:
free(old_script_path);
return enum_ESCRETURN_restart; return enum_ESCRETURN_restart;
} }
} }
@ -467,11 +462,9 @@ int CampLoop(void)
switch (TextScriptProc()) switch (TextScriptProc())
{ {
case enum_ESCRETURN_exit: case enum_ESCRETURN_exit:
free(old_script_path);
return enum_ESCRETURN_exit; return enum_ESCRETURN_exit;
case enum_ESCRETURN_restart: case enum_ESCRETURN_restart:
free(old_script_path);
return enum_ESCRETURN_restart; return enum_ESCRETURN_restart;
} }
@ -500,16 +493,12 @@ int CampLoop(void)
} }
if (!Flip_SystemTask()) if (!Flip_SystemTask())
{
free(old_script_path);
return enum_ESCRETURN_exit; return enum_ESCRETURN_exit;
}
} }
// Resume original script // Resume original script
LoadTextScript_Stage(old_script_path); LoadTextScript_Stage(old_script_path.c_str());
gArmsEnergyX = 32; // Displays weapon rotation animation in case the weapon was changed gArmsEnergyX = 32; // Displays weapon rotation animation in case the weapon was changed
free(old_script_path);
return enum_ESCRETURN_continue; return enum_ESCRETURN_continue;
} }

View file

@ -13,7 +13,6 @@
#include "Main.h" #include "Main.h"
#include "Map.h" #include "Map.h"
#include "Stage.h" #include "Stage.h"
#include "Helpers/FopenFormatted.h"
BACK gBack; BACK gBack;
int gWaterY; int gWaterY;
@ -26,7 +25,7 @@ BOOL InitBack(const char *fName, int type)
color_black = GetCortBoxColor(RGB(0, 0, 0x10)); color_black = GetCortBoxColor(RGB(0, 0, 0x10));
// Get width and height // Get width and height
FILE *fp = fopenFormatted("rb", "%s/%s.pbm", gDataPath, fName); FILE *fp = fopen((gDataPath + '/' + fName + ".pbm").c_str(), "rb");
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "../Attributes.h" #include "../Attributes.h"
#include <string>
enum enum
{ {
@ -86,7 +87,7 @@ enum
bool Backend_Init(void); bool Backend_Init(void);
void Backend_Deinit(void); void Backend_Deinit(void);
void Backend_PostWindowCreation(void); void Backend_PostWindowCreation(void);
bool Backend_GetBasePath(char **string_buffer); bool Backend_GetBasePath(std::string *string_buffer);
void Backend_HideMouse(void); void Backend_HideMouse(void);
void Backend_SetWindowIcon(const unsigned char *rgb_pixels, unsigned int width, unsigned int height); void Backend_SetWindowIcon(const unsigned char *rgb_pixels, unsigned int width, unsigned int height);
void Backend_SetCursor(const unsigned char *rgb_pixels, unsigned int width, unsigned int height); void Backend_SetCursor(const unsigned char *rgb_pixels, unsigned int width, unsigned int height);

View file

@ -181,7 +181,7 @@ void Backend_PostWindowCreation(void)
glfwSetWindowSizeCallback(window, WindowSizeCallback); glfwSetWindowSizeCallback(window, WindowSizeCallback);
} }
bool Backend_GetBasePath(char **string_buffer) bool Backend_GetBasePath(std::string *string_buffer)
{ {
(void)string_buffer; (void)string_buffer;

View file

@ -1,4 +1,5 @@
#include "../Misc.h" #include "../Misc.h"
#include <string>
bool Backend_Init(void) bool Backend_Init(void)
{ {
@ -15,7 +16,7 @@ void Backend_PostWindowCreation(void)
} }
bool Backend_GetBasePath(char **string_buffer) bool Backend_GetBasePath(std::string *string_buffer)
{ {
(void)string_buffer; (void)string_buffer;

View file

@ -13,7 +13,6 @@
#include "../../Organya.h" #include "../../Organya.h"
#include "../../Profile.h" #include "../../Profile.h"
#include "../../Resource.h" #include "../../Resource.h"
#include "../../Helpers/Strdup.h"
#define DO_KEY(SDL_KEY, BACKEND_KEY) \ #define DO_KEY(SDL_KEY, BACKEND_KEY) \
case SDL_KEY: \ case SDL_KEY: \
@ -85,13 +84,15 @@ void Backend_PostWindowCreation(void)
} }
bool Backend_GetBasePath(char **string_buffer) bool Backend_GetBasePath(std::string *string_buffer)
{ {
#ifdef _WIN32 #ifdef _WIN32
// SDL_GetBasePath returns a UTF-8 string, but Windows' fopen uses (extended?) ASCII. // SDL_GetBasePath returns a UTF-8 string, but Windows' fopen uses (extended?) ASCII.
// This is apparently a problem for accented characters, as they will make fopen fail. // This is apparently a problem for accented characters, as they will make fopen fail.
// So, instead, we rely on argv[0], as that will put the accented characters in a // So, instead, we rely on argv[0], as that will put the accented characters in a
// format Windows will understand. // format Windows will understand.
(void)string_buffer;
return false; return false;
#else #else
char *base_path = SDL_GetBasePath(); char *base_path = SDL_GetBasePath();
@ -101,7 +102,7 @@ bool Backend_GetBasePath(char **string_buffer)
// Trim the trailing '/' // Trim the trailing '/'
size_t base_path_length = strlen(base_path); size_t base_path_length = strlen(base_path);
base_path[base_path_length - 1] = '\0'; base_path[base_path_length - 1] = '\0';
*string_buffer = strdup(base_path); *string_buffer = base_path;
SDL_free(base_path); SDL_free(base_path);
return true; return true;

View file

@ -56,12 +56,12 @@ void Backend_PostWindowCreation(void)
} }
bool Backend_GetBasePath(char **string_buffer) bool Backend_GetBasePath(std::string *string_buffer)
{ {
#ifdef JAPANESE #ifdef JAPANESE
*string_buffer = asprintf("%s/CSE-portable-jp", WHBGetSdCardMountPath()); *string_buffer = std::string{WHBGetSdCardMountPath()} + "/CSE-portable-jp";
#else #else
*string_buffer = asprintf("%s/CSE-portable-en", WHBGetSdCardMountPath()); *string_buffer = std::string{WHBGetSdCardMountPath()} + "/CSE-portable-en";
#endif #endif
return true; return true;
} }

View file

@ -7,7 +7,6 @@
#include "Config.h" #include "Config.h"
#include "File.h" #include "File.h"
#include "Main.h" #include "Main.h"
#include "Helpers/FopenFormatted.h"
const char* const gConfigName = "Config.dat"; const char* const gConfigName = "Config.dat";
const char* const gProof = "DOUKUTSU20041206"; const char* const gProof = "DOUKUTSU20041206";
@ -18,7 +17,7 @@ BOOL LoadConfigData(CONFIG *conf)
memset(conf, 0, sizeof(CONFIG)); memset(conf, 0, sizeof(CONFIG));
// Open file // Open file
FILE *fp = fopenFormatted("rb", "%s/%s", gModulePath, gConfigName); FILE *fp = fopen((gModulePath + '/' + gConfigName).c_str(), "rb");
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;

View file

@ -18,7 +18,6 @@
#include "MapName.h" #include "MapName.h"
#include "Resource.h" #include "Resource.h"
#include "TextScr.h" #include "TextScr.h"
#include "Helpers/Asprintf.h"
typedef enum SurfaceType typedef enum SurfaceType
{ {
@ -251,15 +250,11 @@ BOOL MakeSurface_Resource(const char *name, SurfaceID surf_no)
// TODO - Inaccurate stack frame // TODO - Inaccurate stack frame
BOOL MakeSurface_File(const char *name, SurfaceID surf_no) BOOL MakeSurface_File(const char *name, SurfaceID surf_no)
{ {
char *path; std::string path = gDataPath + '/' + name + ".pbm";
if (asprintf(&path, "%s/%s.pbm", gDataPath, name) < 0) if (!IsEnableBitmap(path.c_str()))
return FALSE;
if (!IsEnableBitmap(path))
{ {
ErrorLog(path, 0); ErrorLog(path.c_str(), 0);
free(path);
return FALSE; return FALSE;
} }
@ -270,27 +265,23 @@ BOOL MakeSurface_File(const char *name, SurfaceID surf_no)
#endif #endif
{ {
ErrorLog("surface no", surf_no); ErrorLog("surface no", surf_no);
free(path);
return FALSE; return FALSE;
} }
if (surf[surf_no] != NULL) if (surf[surf_no] != NULL)
{ {
ErrorLog("existing", surf_no); ErrorLog("existing", surf_no);
free(path);
return FALSE; return FALSE;
} }
unsigned int width, height; unsigned int width, height;
unsigned char *image_buffer = DecodeBitmapFromFile(path, &width, &height); unsigned char *image_buffer = DecodeBitmapFromFile(path.c_str(), &width, &height);
if (image_buffer == NULL) if (image_buffer == NULL)
{ {
ErrorLog(path, 1); ErrorLog(path.c_str(), 1);
free(path);
return FALSE; return FALSE;
} }
free(path);
surf[surf_no] = RenderBackend_CreateSurface(width * mag, height * mag, false); surf[surf_no] = RenderBackend_CreateSurface(width * mag, height * mag, false);
@ -349,14 +340,11 @@ BOOL ReloadBitmap_Resource(const char *name, SurfaceID surf_no)
// TODO - Inaccurate stack frame // TODO - Inaccurate stack frame
BOOL ReloadBitmap_File(const char *name, SurfaceID surf_no) BOOL ReloadBitmap_File(const char *name, SurfaceID surf_no)
{ {
char *path; std::string path = gDataPath + '/' + name + ".pbm";
if (asprintf(&path, "%s/%s.pbm", gDataPath, name) < 0)
return FALSE;
if (!IsEnableBitmap(path)) if (!IsEnableBitmap(path.c_str()))
{ {
ErrorLog(path, 0); ErrorLog(path.c_str(), 0);
free(path);
return FALSE; return FALSE;
} }
@ -367,20 +355,17 @@ BOOL ReloadBitmap_File(const char *name, SurfaceID surf_no)
#endif #endif
{ {
ErrorLog("surface no", surf_no); ErrorLog("surface no", surf_no);
free(path);
return FALSE; return FALSE;
} }
unsigned int width, height; unsigned int width, height;
unsigned char *image_buffer = DecodeBitmapFromFile(path, &width, &height); unsigned char *image_buffer = DecodeBitmapFromFile(path.c_str(), &width, &height);
if (image_buffer == NULL) if (image_buffer == NULL)
{ {
ErrorLog(path, 1); ErrorLog(path.c_str(), 1);
free(path);
return FALSE; return FALSE;
} }
free(path);
if (!ScaleAndUploadSurface(image_buffer, width, height, surf_no)) if (!ScaleAndUploadSurface(image_buffer, width, height, surf_no))
{ {
@ -659,10 +644,6 @@ void InitTextObject(const char *name)
{ {
(void)name; // Unused in this branch (void)name; // Unused in this branch
char *path;
if (asprintf(&path, "%s/Font/font", gDataPath) < 0)
return;
// Get font size // Get font size
unsigned int width, height; unsigned int width, height;
@ -679,7 +660,7 @@ void InitTextObject(const char *name)
break; break;
} }
font = LoadFont(path, width, height); font = LoadFont((gDataPath + "/Font/font").c_str(), width, height);
} }
void PutText(int x, int y, const char *text, unsigned long color) void PutText(int x, int y, const char *text, unsigned long color)

View file

@ -16,7 +16,6 @@
#include "Organya.h" #include "Organya.h"
#include "Stage.h" #include "Stage.h"
#include "TextScr.h" #include "TextScr.h"
#include "Helpers/Asprintf.h"
struct CREDIT struct CREDIT
{ {
@ -226,27 +225,17 @@ BOOL StartCreditScript(void)
} }
// Open file // Open file
char *path; std::string path = gDataPath + '/' + credit_script;
if (asprintf(&path, "%s/%s", gDataPath, credit_script) < 0) Credit.size = GetFileSizeLong(path.c_str());
return FALSE;
Credit.size = GetFileSizeLong(path);
if (Credit.size == -1) if (Credit.size == -1)
{
free(path);
return FALSE; return FALSE;
}
// Allocate buffer data // Allocate buffer data
Credit.pData = (char*)malloc(Credit.size); Credit.pData = (char*)malloc(Credit.size);
if (Credit.pData == NULL) if (Credit.pData == NULL)
{
free(path);
return FALSE; return FALSE;
}
fp = fopen(path, "rb"); fp = fopen(path.c_str(), "rb");
free(path);
if (fp == NULL) if (fp == NULL)
{ {
free(Credit.pData); free(Credit.pData);

View file

@ -44,7 +44,6 @@
#include "Star.h" #include "Star.h"
#include "TextScr.h" #include "TextScr.h"
#include "ValueView.h" #include "ValueView.h"
#include "Helpers/Asprintf.h"
int g_GameFlags; int g_GameFlags;
int gCounter; int gCounter;
@ -702,13 +701,9 @@ BOOL Game(void)
PlaySoundObject(7, -1); PlaySoundObject(7, -1);
char *path; std::string path = gDataPath + "/npc.tbl";
if (asprintf(&path, "%s/npc.tbl", gDataPath) < 0)
return FALSE;
BOOL load_npc_table_succeeded = LoadNpcTable(path); if (!LoadNpcTable(path.c_str()))
free(path);
if (!load_npc_table_succeeded)
{ {
#ifdef JAPANESE #ifdef JAPANESE
Backend_ShowMessageBox("エラー", "NPCテーブルが読めない"); Backend_ShowMessageBox("エラー", "NPCテーブルが読めない");

View file

@ -8,8 +8,6 @@
#include "WindowsWrapper.h" #include "WindowsWrapper.h"
#include "Main.h" #include "Main.h"
#include "Helpers/Asprintf.h"
#include "Helpers/FopenFormatted.h"
void GetCompileDate(int *year, int *month, int *day) void GetCompileDate(int *year, int *month, int *day)
{ {
@ -52,19 +50,12 @@ BOOL GetCompileVersion(int *v1, int *v2, int *v3, int *v4)
void DeleteLog(void) void DeleteLog(void)
{ {
char *path; remove((gModulePath + "/debug.txt").c_str());
if (asprintf(&path, "%s/debug.txt", gModulePath) < 0)
return;
remove(path);
free(path);
} }
BOOL WriteLog(const char *string, int value1, int value2, int value3) BOOL WriteLog(const char *string, int value1, int value2, int value3)
{ {
FILE *fp = fopenFormatted("a+", "%s/debug.txt", gModulePath); FILE *fp = fopen((gModulePath + "/debug.txt").c_str(), "a+");
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;
@ -75,8 +66,7 @@ BOOL WriteLog(const char *string, int value1, int value2, int value3)
BOOL IsKeyFile(const char *name) BOOL IsKeyFile(const char *name)
{ {
FILE *file = fopenFormatted("rb", "%s/%s", gModulePath, name); FILE *file = fopen((gModulePath + '/' + name).c_str(), "rb");
if (file == NULL) if (file == NULL)
return FALSE; return FALSE;
@ -104,15 +94,12 @@ long GetFileSizeLong(const char *path)
BOOL ErrorLog(const char *string, int value) BOOL ErrorLog(const char *string, int value)
{ {
char *path; std::string path = gModulePath + "/error.log";
if (asprintf(&path, "%s/%s", gModulePath, "error.log") < 0)
return FALSE;
if (GetFileSizeLong(path) > 0x19000) // Purge the error log if it gets too big, I guess if (GetFileSizeLong(path.c_str()) > 0x19000) // Purge the error log if it gets too big, I guess
remove(path); remove(path.c_str());
FILE *fp = fopen(path, "a+"); FILE *fp = fopen(path.c_str(), "a+");
free(path);
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;

View file

@ -1,18 +0,0 @@
#ifndef _GNU_SOURCE
#include "Asprintf.h"
#include "Vasprintf.h"
#include "../Attributes.h"
#include <stdarg.h>
ATTRIBUTE_FORMAT(printf, 2, 3) ATTRIBUTE_WARN_UNUSED_RESULT int asprintf(char **result_string, const char *format_string, ...)
{
// Handle variadic arguments and redirect to vasprintf
va_list arguments_local;
va_start(arguments_local, format_string);
int retVal = vasprintf(result_string, format_string, arguments_local);
va_end(arguments_local); // Destroy arguments_local
return retVal;
}
#endif

View file

@ -1,15 +0,0 @@
#pragma once
// If <stdio.h> defines asprintf for us, use its definition
#ifdef _GNU_SOURCE
#include <stdio.h>
#else
#include "../Attributes.h"
#define asprintf Portable_asprintf
ATTRIBUTE_FORMAT(printf, 2, 3) ATTRIBUTE_WARN_UNUSED_RESULT int asprintf(char **resultString, const char *formatString, ...);
#endif

View file

@ -1,23 +0,0 @@
#include "FopenFormatted.h"
#include "../Attributes.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
ATTRIBUTE_FORMAT(printf, 2, 3) ATTRIBUTE_WARN_UNUSED_RESULT FILE *fopenFormatted(const char *mode, const char *format_string, ...)
{
// Handle variadic arguments and redirect to vasprintf
va_list arguments_local;
va_start(arguments_local, format_string);
char *path;
int vasprintf_retval = vasprintf(&path, format_string, arguments_local);
va_end(arguments_local); // Destroy arguments_local
if (vasprintf_retval < 0)
return NULL;
FILE *file = fopen(path, mode);
free(path);
return file;
}

View file

@ -1,5 +0,0 @@
#pragma once
#include "../Attributes.h"
#include <stdio.h>
ATTRIBUTE_FORMAT(printf, 2, 3) ATTRIBUTE_WARN_UNUSED_RESULT FILE *fopenFormatted(const char *mode, const char *formatString, ...);

View file

@ -1,20 +0,0 @@
#include <assert.h>
#if !(_XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200809L)
#include "Strdup.h"
#include "../Attributes.h"
#include <string.h>
#include <stdlib.h>
ATTRIBUTE_MALLOC ATTRIBUTE_NONNULL((1)) char *strdup(const char *duplicated_string)
{
size_t duplicatedStringLength = strlen(duplicated_string) + sizeof(char); // Length of the whole string, plus the terminator
char *returnedString = (char *)malloc(duplicatedStringLength); // Memory for the new string is obtained with malloc. malloc also sets errno to ENOMEM on failure, which is exactly what we want for conformance
if (returnedString) // If the result of malloc was NULL, allocation failed copying into it would be UB
memcpy(returnedString, duplicated_string, duplicatedStringLength); // Copy the entire duplicated string (including the null terminator)
return returnedString; // Returns a pointer to the duplicated string on success, NULL if insufficient memory was available
}
#endif

View file

@ -1,16 +0,0 @@
#pragma once
#include <assert.h> // Probably the smallest header that will include <features.h> on systems with it
// If <string.h> defines strdup for us, use its definition
#if (_XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200809L)
#include <string.h>
#else
#include "../Attributes.h"
#define strdup Portable_strdup
ATTRIBUTE_MALLOC ATTRIBUTE_NONNULL(1) char *strdup(const char *duplicatedString);
#endif

View file

@ -1,32 +0,0 @@
#ifndef _GNU_SOURCE
#include "Vasprintf.h"
#include "../Attributes.h"
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
ATTRIBUTE_FORMAT(printf, 2, 0) ATTRIBUTE_WARN_UNUSED_RESULT int vasprintf(char **result_string, const char *format_string, va_list arguments)
{
const int error_return_value = -1; // According to the man page, this is returned on error
va_list arguments_local;
va_copy(arguments_local, arguments); // Copy the arguments so we can actually use them
int size = vsnprintf(NULL, 0, format_string, arguments_local); // Get the amount of bytes we need for the output buffer
va_end(arguments_local); // Destroy arguments_local
if (size < 0) // If an output error is encountered, vsnprintf returns a negative value
return error_return_value;
*result_string = (char *)malloc(size + 1); // Allocate enough space for the string (need + 1 for the null terminator)
if (*result_string == NULL) // On error, malloc returns NULL
return error_return_value;
// We know we have enough space, so we can use vsprintf safely
return vsprintf(*result_string, format_string, arguments); // vsprintf returns the amount of characters that got printed. This is what we're supposed to return
}
#endif

View file

@ -1,16 +0,0 @@
#pragma once
// If <stdio.h> defines asprintf for us, use its definition
#ifdef _GNU_SOURCE
#include <stdio.h>
#else
#include "../Attributes.h"
#include <stdarg.h>
#define vasprintf Portable_vasprintf
ATTRIBUTE_FORMAT(printf, 2, 0) ATTRIBUTE_WARN_UNUSED_RESULT int vasprintf(char **resultString, const char *formatString, va_list arguments);
#endif

View file

@ -24,11 +24,9 @@
#include "Resource.h" #include "Resource.h"
#include "Sound.h" #include "Sound.h"
#include "Triangle.h" #include "Triangle.h"
#include "Helpers/Asprintf.h"
#include "Helpers/Strdup.h"
char *gModulePath; std::string gModulePath;
char *gDataPath; std::string gDataPath;
BOOL bFullscreen; BOOL bFullscreen;
BOOL gbUseJoystick = FALSE; BOOL gbUseJoystick = FALSE;
@ -84,24 +82,6 @@ void PutFramePerSecound(void)
} }
} }
static int main_out_backend_deinit(int return_value)
{
Backend_Deinit();
return return_value;
}
static int main_out_free_module_path(int return_value)
{
free(gModulePath);
return main_out_backend_deinit(return_value);
}
static int main_out_free_data_path(int return_value)
{
free(gDataPath);
return main_out_free_module_path(return_value);
}
// TODO - Inaccurate stack frame // TODO - Inaccurate stack frame
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -116,26 +96,20 @@ int main(int argc, char *argv[])
if (!Backend_GetBasePath(&gModulePath)) if (!Backend_GetBasePath(&gModulePath))
{ {
// Fall back on argv[0] if the backend cannot provide a path // Fall back on argv[0] if the backend cannot provide a path
gModulePath = strdup(argv[0]); gModulePath = argv[0];
if (!gModulePath)
{
Backend_PrintError("Could not get executable path (not enough memory)");
return main_out_backend_deinit(EXIT_FAILURE);
}
for (size_t i = strlen(gModulePath);; --i) for (size_t i = gModulePath.length();; --i)
{ {
if (i == 0 || gModulePath[i] == '\\' || gModulePath[i] == '/') if (i == 0 || gModulePath[i] == '\\' || gModulePath[i] == '/')
{ {
gModulePath[i] = '\0'; gModulePath.resize(i);
break; break;
} }
} }
} }
// Get path of the data folder // Get path of the data folder
if (asprintf(&gDataPath, "%s/data", gModulePath) < 0) gDataPath = gModulePath + "/data";
return main_out_free_module_path(EXIT_FAILURE);
CONFIG conf; CONFIG conf;
if (!LoadConfigData(&conf)) if (!LoadConfigData(&conf))
@ -248,12 +222,12 @@ int main(int argc, char *argv[])
if (conf.display_mode == 1) if (conf.display_mode == 1)
{ {
if (!StartDirectDraw(lpWindowName, windowWidth, windowHeight, 0)) if (!StartDirectDraw(lpWindowName, windowWidth, windowHeight, 0))
return main_out_free_data_path(EXIT_FAILURE); return EXIT_FAILURE;
} }
else else
{ {
if (!StartDirectDraw(lpWindowName, windowWidth, windowHeight, 1)) if (!StartDirectDraw(lpWindowName, windowWidth, windowHeight, 1))
return main_out_free_data_path(EXIT_FAILURE); return EXIT_FAILURE;
} }
#else #else
// Doesn't handle StartDirectDraw failing // Doesn't handle StartDirectDraw failing
@ -274,7 +248,7 @@ int main(int argc, char *argv[])
#ifdef FIX_BUGS #ifdef FIX_BUGS
if (!StartDirectDraw(lpWindowName, windowWidth, windowHeight, 2)) if (!StartDirectDraw(lpWindowName, windowWidth, windowHeight, 2))
return main_out_free_data_path(EXIT_FAILURE); return EXIT_FAILURE;
#else #else
// Doesn't handle StartDirectDraw failing // Doesn't handle StartDirectDraw failing
StartDirectDraw(lpWindowName, windowWidth, windowHeight, 2); StartDirectDraw(lpWindowName, windowWidth, windowHeight, 2);
@ -342,7 +316,7 @@ int main(int argc, char *argv[])
// Draw to screen // Draw to screen
if (!Flip_SystemTask()) if (!Flip_SystemTask())
return main_out_free_data_path(EXIT_SUCCESS); return EXIT_SUCCESS;
// Initialize sound // Initialize sound
InitDirectSound(); InitDirectSound();
@ -366,7 +340,7 @@ int main(int argc, char *argv[])
EndDirectSound(); EndDirectSound();
EndDirectDraw(); EndDirectDraw();
return main_out_free_data_path(EXIT_SUCCESS); return EXIT_SUCCESS;
} }
void InactiveWindow(void) void InactiveWindow(void)

View file

@ -1,9 +1,10 @@
#pragma once #pragma once
#include "WindowsWrapper.h" #include "WindowsWrapper.h"
#include <string>
extern char *gModulePath; extern std::string gModulePath;
extern char *gDataPath; extern std::string gDataPath;
extern BOOL bFullscreen; extern BOOL bFullscreen;
extern BOOL gbUseJoystick; extern BOOL gbUseJoystick;

View file

@ -12,7 +12,6 @@
#include "File.h" #include "File.h"
#include "Main.h" #include "Main.h"
#include "NpChar.h" #include "NpChar.h"
#include "Helpers/FopenFormatted.h"
#define PXM_BUFFER_SIZE 0x4B000 #define PXM_BUFFER_SIZE 0x4B000
@ -28,11 +27,10 @@ BOOL InitMapData2(void)
BOOL LoadMapData2(const char *path_map) BOOL LoadMapData2(const char *path_map)
{ {
FILE *fp;
char check[3]; char check[3];
// Open file // Open file
fp = fopenFormatted("rb", "%s/%s", gDataPath, path_map); FILE *fp = fopen((gDataPath + '/' + path_map).c_str(), "rb");
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;
@ -65,10 +63,8 @@ BOOL LoadMapData2(const char *path_map)
BOOL LoadAttributeData(const char *path_atrb) BOOL LoadAttributeData(const char *path_atrb)
{ {
FILE *fp;
// Open file // Open file
fp = fopenFormatted("rb", "%s/%s", gDataPath, path_atrb); FILE *fp = fopen((gDataPath + '/' + path_atrb).c_str(), "rb");
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;

View file

@ -16,8 +16,6 @@
#include "Sound.h" #include "Sound.h"
#include "TextScr.h" #include "TextScr.h"
#include "ValueView.h" #include "ValueView.h"
#include "Helpers/Asprintf.h"
#include "Helpers/FopenFormatted.h"
ARMS_LEVEL gArmsLevelTable[14] = ARMS_LEVEL gArmsLevelTable[14] =
{ {
@ -437,18 +435,15 @@ BOOL SaveTimeCounter(void)
int i; int i;
unsigned char p[4]; unsigned char p[4];
REC rec; REC rec;
FILE *fp;
char *path;
// Quit if player doesn't have the Nikumaru Counter // Quit if player doesn't have the Nikumaru Counter
if (!(gMC.equip & EQUIP_NIKUMARU_COUNTER)) if (!(gMC.equip & EQUIP_NIKUMARU_COUNTER))
return TRUE; return TRUE;
// Get last time // Get last time
if (asprintf(&path, "%s/290.rec", gModulePath) < 0) std::string path = gModulePath + "/290.rec";
return FALSE;
fp = fopen(path, "rb"); FILE *fp = fopen(path.c_str(), "rb");
if (fp != NULL) if (fp != NULL)
{ {
// Read data // Read data
@ -488,7 +483,7 @@ BOOL SaveTimeCounter(void)
rec.counter[i] = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); rec.counter[i] = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
} }
fp = fopen(path, "wb"); fp = fopen(path.c_str(), "wb");
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;
@ -510,10 +505,9 @@ int LoadTimeCounter(void)
int i; int i;
unsigned char p[4]; unsigned char p[4];
REC rec; REC rec;
FILE *fp;
// Open file // Open file
fp = fopenFormatted("rb", "%s/290.rec", gModulePath); FILE *fp = fopen((gModulePath + "/290.rec").c_str(), "rb");
if (fp == NULL) if (fp == NULL)
return 0; return 0;

View file

@ -17,7 +17,6 @@
#include "NpcTbl.h" #include "NpcTbl.h"
#include "Sound.h" #include "Sound.h"
#include "ValueView.h" #include "ValueView.h"
#include "Helpers/FopenFormatted.h"
NPCHAR gNPC[NPC_MAX]; NPCHAR gNPC[NPC_MAX];
int gCurlyShoot_wait; int gCurlyShoot_wait;
@ -55,12 +54,11 @@ void InitNpChar(void)
BOOL LoadEvent(const char *path_event) BOOL LoadEvent(const char *path_event)
{ {
int i, n; int i, n;
FILE *fp;
int count; int count;
char code[4]; char code[4];
EVENT eve; EVENT eve;
fp = fopenFormatted("rb", "%s/%s", gDataPath, path_event); FILE *fp = fopen((gDataPath + '/' + path_event).c_str(), "rb");
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;

View file

@ -22,14 +22,13 @@
#include "Stage.h" #include "Stage.h"
#include "Star.h" #include "Star.h"
#include "ValueView.h" #include "ValueView.h"
#include "Helpers/FopenFormatted.h"
const char* const gDefaultName = "Profile.dat"; const char* const gDefaultName = "Profile.dat";
const char* const gProfileCode = "Do041220"; const char* const gProfileCode = "Do041220";
BOOL IsProfile(void) BOOL IsProfile(void)
{ {
FILE *file = fopenFormatted("rb", "%s/%s", gModulePath, gDefaultName); FILE *file = fopen((gModulePath + '/' + gDefaultName).c_str(), "rb");
if (file == NULL) if (file == NULL)
return FALSE; return FALSE;
@ -42,7 +41,7 @@ BOOL SaveProfile(const char *name)
const char *FLAG = "FLAG"; const char *FLAG = "FLAG";
// Open file // Open file
FILE *fp = fopenFormatted("wb", "%s/%s", gModulePath, ((name != NULL) ? name : gDefaultName)); FILE *fp = fopen((gModulePath + '/' + ((name != NULL) ? name : gDefaultName)).c_str(), "wb");
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;
@ -111,14 +110,14 @@ BOOL SaveProfile(const char *name)
BOOL LoadProfile(const char *name) BOOL LoadProfile(const char *name)
{ {
FILE *fp;
PROFILE profile; PROFILE profile;
// Open file // Open file
FILE *fp;
if (name != NULL) if (name != NULL)
fp = fopenFormatted("rb", "%s", name); fp = fopen(name, "rb");
else else
fp = fopenFormatted("rb", "%s/%s", gModulePath, gDefaultName); fp = fopen((gModulePath + '/' + gDefaultName).c_str(), "rb");
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;

View file

@ -161,9 +161,7 @@ int StageSelectLoop(int *p_event)
gSelectedStage = 0; gSelectedStage = 0;
BackupSurface(SURFACE_ID_SCREEN_GRAB, &grcFull); BackupSurface(SURFACE_ID_SCREEN_GRAB, &grcFull);
char *old_script_path = GetTextScriptPath(); std::string old_script_path = GetTextScriptPath();
if (!old_script_path)
return enum_ESCRETURN_exit;
LoadTextScript2("StageSelect.tsc"); LoadTextScript2("StageSelect.tsc");
gStageSelectTitleY = (WINDOW_HEIGHT / 2) - 66; gStageSelectTitleY = (WINDOW_HEIGHT / 2) - 66;
StartTextScript(gPermitStage[gSelectedStage].index + 1000); StartTextScript(gPermitStage[gSelectedStage].index + 1000);
@ -177,11 +175,9 @@ int StageSelectLoop(int *p_event)
switch (Call_Escape()) switch (Call_Escape())
{ {
case enum_ESCRETURN_exit: case enum_ESCRETURN_exit:
free(old_script_path);
return enum_ESCRETURN_exit; return enum_ESCRETURN_exit;
case enum_ESCRETURN_restart: case enum_ESCRETURN_restart:
free(old_script_path);
return enum_ESCRETURN_restart; return enum_ESCRETURN_restart;
} }
} }
@ -191,11 +187,9 @@ int StageSelectLoop(int *p_event)
switch (TextScriptProc()) switch (TextScriptProc())
{ {
case enum_ESCRETURN_exit: case enum_ESCRETURN_exit:
free(old_script_path);
return enum_ESCRETURN_exit; return enum_ESCRETURN_exit;
case enum_ESCRETURN_restart: case enum_ESCRETURN_restart:
free(old_script_path);
return enum_ESCRETURN_restart; return enum_ESCRETURN_restart;
} }
@ -216,8 +210,7 @@ int StageSelectLoop(int *p_event)
else if (gKeyTrg & gKeyCancel) else if (gKeyTrg & gKeyCancel)
{ {
StopTextScript(); StopTextScript();
LoadTextScript_Stage(old_script_path); LoadTextScript_Stage(old_script_path.c_str());
free(old_script_path);
*p_event = 0; *p_event = 0;
return enum_ESCRETURN_continue; return enum_ESCRETURN_continue;
} }
@ -225,14 +218,10 @@ int StageSelectLoop(int *p_event)
PutFramePerSecound(); PutFramePerSecound();
if (!Flip_SystemTask()) if (!Flip_SystemTask())
{
free(old_script_path);
return enum_ESCRETURN_exit; return enum_ESCRETURN_exit;
}
} }
LoadTextScript_Stage(old_script_path); LoadTextScript_Stage(old_script_path.c_str());
free(old_script_path);
*p_event = gPermitStage[gSelectedStage].event; *p_event = gPermitStage[gSelectedStage].event;
return enum_ESCRETURN_continue; return enum_ESCRETURN_continue;
} }

View file

@ -138,56 +138,41 @@ BOOL TransferStage(int no, int w, int x, int y)
bError = FALSE; bError = FALSE;
// Get path
char path_dir[sizeof("Stage")] = "Stage"; // Can only be either "Stage" or "Npc", and sizeof("Stage") > sizeof("Npc")
/*
* The size of path should be size of the format string (without the operands) + size of first operand + size of second operand - 2 (no null terminator needed for the first two operands, and sizeof will include the size for the null terminators here)
* The size of the format string is sizeof("/.pxa") because that's the biggest raw format (omitting the operands) used here
* Size of first operand is sizeof(path_dir) because that's always the first operand
* Size of second operand is sizeof(gTMT[no].parts) because all the operands used here (gTMT[no].parts, gTMT[no].map, gTMT[no].npc, gTMT[no].boss) are of the same size
* sprintf(path, "%s", gTMT[no].back) is irrelevant here because sizeof(gTMT[no].back) is the same as the size of all the operands discussed for the size of the second operand, so gTMT[no].back always fits into the size allocated for the second operand alone
*/
char path[sizeof("/.pxa") + sizeof(path_dir) + sizeof(gTMT[no].parts) - 2];
// Load tileset // Load tileset
sprintf(path, "%s/Prt%s", path_dir, gTMT[no].parts); std::string path = std::string{"Stage/Prt"} + gTMT[no].parts;
if (!ReloadBitmap_File(path, SURFACE_ID_LEVEL_TILESET)) if (!ReloadBitmap_File(path.c_str(), SURFACE_ID_LEVEL_TILESET))
bError = TRUE; bError = TRUE;
sprintf(path, "%s/%s.pxa", path_dir, gTMT[no].parts); path = std::string{"Stage/"} + gTMT[no].parts + ".pxa";
if (!LoadAttributeData(path)) if (!LoadAttributeData(path.c_str()))
bError = TRUE; bError = TRUE;
// Load tilemap // Load tilemap
sprintf(path, "%s/%s.pxm", path_dir, gTMT[no].map); path = std::string{"Stage/"} + gTMT[no].map + ".pxm";
if (!LoadMapData2(path)) if (!LoadMapData2(path.c_str()))
bError = TRUE; bError = TRUE;
// Load NPCs // Load NPCs
sprintf(path, "%s/%s.pxe", path_dir, gTMT[no].map); path = std::string{"Stage/"} + gTMT[no].map + ".pxe";
if (!LoadEvent(path)) if (!LoadEvent(path.c_str()))
bError = TRUE; bError = TRUE;
// Load script // Load script
sprintf(path, "%s/%s.tsc", path_dir, gTMT[no].map); path = std::string{"Stage/"} + gTMT[no].map + ".tsc";
if (!LoadTextScript_Stage(path)) if (!LoadTextScript_Stage(path.c_str()))
bError = TRUE; bError = TRUE;
// Load background // Load background
sprintf(path, "%s", gTMT[no].back); if (!InitBack(gTMT[no].back, gTMT[no].bkType))
if (!InitBack(path, gTMT[no].bkType))
bError = TRUE; bError = TRUE;
// Get path
strcpy(path_dir, "Npc");
// Load NPC sprite sheets // Load NPC sprite sheets
sprintf(path, "%s/Npc%s", path_dir, gTMT[no].npc); path = std::string{"Npc/Npc"} + gTMT[no].npc;
if (!ReloadBitmap_File(path, SURFACE_ID_LEVEL_SPRITESET_1)) if (!ReloadBitmap_File(path.c_str(), SURFACE_ID_LEVEL_SPRITESET_1))
bError = TRUE; bError = TRUE;
sprintf(path, "%s/Npc%s", path_dir, gTMT[no].boss); path = std::string{"Npc/Npc"} + gTMT[no].boss;
if (!ReloadBitmap_File(path, SURFACE_ID_LEVEL_SPRITESET_2)) if (!ReloadBitmap_File(path.c_str(), SURFACE_ID_LEVEL_SPRITESET_2))
bError = TRUE; bError = TRUE;
if (bError) if (bError)

View file

@ -33,8 +33,6 @@
#include "SelStage.h" #include "SelStage.h"
#include "Sound.h" #include "Sound.h"
#include "Stage.h" #include "Stage.h"
#include "Helpers/Asprintf.h"
#include "Helpers/Strdup.h"
// This limits the size of a .tsc script to 0x5000 bytes (the game will crash above this) // This limits the size of a .tsc script to 0x5000 bytes (the game will crash above this)
#define TSC_BUFFER_SIZE 0x5000 #define TSC_BUFFER_SIZE 0x5000
@ -126,22 +124,16 @@ void EncryptionBinaryData2(unsigned char *pData, long size)
BOOL LoadTextScript2(const char *name) BOOL LoadTextScript2(const char *name)
{ {
FILE *fp; FILE *fp;
char *path;
// Get path // Get path
if (asprintf(&path, "%s/%s", gDataPath, name) < 0) std::string path = gDataPath + '/' + name;
return FALSE;
gTS.size = GetFileSizeLong(path); gTS.size = GetFileSizeLong(path.c_str());
if (gTS.size == -1) if (gTS.size == -1)
{
free(path);
return FALSE; return FALSE;
}
// Open file // Open file
fp = fopen(path, "rb"); fp = fopen(path.c_str(), "rb");
free(path);
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;
@ -151,9 +143,7 @@ BOOL LoadTextScript2(const char *name)
fclose(fp); fclose(fp);
// Set path // Set path
if (gTS.path != NULL) gTS.path = name;
free(gTS.path);
gTS.path = strdup(name);
// Decrypt data // Decrypt data
EncryptionBinaryData2((unsigned char*)gTS.data, gTS.size); EncryptionBinaryData2((unsigned char*)gTS.data, gTS.size);
@ -169,19 +159,12 @@ BOOL LoadTextScript_Stage(const char *name)
long body_size; long body_size;
// Open Head.tsc // Open Head.tsc
char *path; std::string path = gDataPath + "/Head.tsc";
if (asprintf(&path, "%s/%s", gDataPath, "Head.tsc") < 0) head_size = GetFileSizeLong(path.c_str());
return FALSE;
head_size = GetFileSizeLong(path);
if (head_size == -1) if (head_size == -1)
{
free(path);
return FALSE; return FALSE;
}
fp = fopen(path, "rb"); fp = fopen(path.c_str(), "rb");
free(path);
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;
@ -192,18 +175,12 @@ BOOL LoadTextScript_Stage(const char *name)
fclose(fp); fclose(fp);
// Open stage's .tsc // Open stage's .tsc
if (asprintf(&path, "%s/%s", gDataPath, name) < 0) path = gDataPath + '/' + name;
return FALSE; body_size = GetFileSizeLong(path.c_str());
body_size = GetFileSizeLong(path);
if (body_size == -1) if (body_size == -1)
{
free(path);
return FALSE; return FALSE;
}
fp = fopen(path, "rb"); fp = fopen(path.c_str(), "rb");
free(path);
if (fp == NULL) if (fp == NULL)
return FALSE; return FALSE;
@ -215,17 +192,15 @@ BOOL LoadTextScript_Stage(const char *name)
// Set parameters // Set parameters
gTS.size = head_size + body_size; gTS.size = head_size + body_size;
if (gTS.path != NULL) gTS.path = name;
free(gTS.path);
gTS.path = strdup(name);
return TRUE; return TRUE;
} }
// Get current path // Get current path
char *GetTextScriptPath() std::string GetTextScriptPath()
{ {
return strdup(gTS.path); return gTS.path;
} }
// Get 4 digit number from TSC data // Get 4 digit number from TSC data

View file

@ -1,11 +1,12 @@
#pragma once #pragma once
#include "WindowsWrapper.h" #include "WindowsWrapper.h"
#include <string>
typedef struct TEXT_SCRIPT typedef struct TEXT_SCRIPT
{ {
// Path (reload when exit teleporter menu/inventory) // Path (reload when exit teleporter menu/inventory)
char *path; std::string path;
// Script buffer // Script buffer
long size; long size;
@ -62,7 +63,7 @@ void EndTextScript(void);
void EncryptionBinaryData2(unsigned char *pData, long size); void EncryptionBinaryData2(unsigned char *pData, long size);
BOOL LoadTextScript2(const char *name); BOOL LoadTextScript2(const char *name);
BOOL LoadTextScript_Stage(const char *name); BOOL LoadTextScript_Stage(const char *name);
char *GetTextScriptPath(); std::string GetTextScriptPath();
BOOL StartTextScript(int no); BOOL StartTextScript(int no);
void StopTextScript(void); void StopTextScript(void);
void PutTextScript(void); void PutTextScript(void);