mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-19 13:03:11 +01:00
add cross platform interface for enumerating files
This commit is contained in:
@@ -31,5 +31,8 @@ int platform_file_exists(const char *path);
|
||||
int platform_directory_exists(const char *path);
|
||||
int platform_ensure_directory_exists(const char *path);
|
||||
int platform_lock_single_instance();
|
||||
int platform_enumerate_files_begin(const char *pattern);
|
||||
int platform_enumerate_files_next(int handle, char **outFileName);
|
||||
void platform_enumerate_files_end(int handle);
|
||||
|
||||
#endif
|
||||
@@ -121,6 +121,72 @@ int platform_lock_single_instance()
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char active;
|
||||
char pattern[MAX_PATH];
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATAA data;
|
||||
} enumerate_file_info;
|
||||
static enumerate_file_info _enumerateFileInfoList[8] = { 0 };
|
||||
|
||||
int platform_enumerate_files_begin(const char *pattern)
|
||||
{
|
||||
int i;
|
||||
enumerate_file_info *enumFileInfo;
|
||||
|
||||
for (i = 0; i < countof(_enumerateFileInfoList); i++) {
|
||||
enumFileInfo = &_enumerateFileInfoList[i];
|
||||
if (!enumFileInfo->active) {
|
||||
strncpy(enumFileInfo->pattern, pattern, MAX_PATH);
|
||||
enumFileInfo->handle = NULL;
|
||||
enumFileInfo->active = 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int platform_enumerate_files_next(int handle, char **outFileName)
|
||||
{
|
||||
int result;
|
||||
enumerate_file_info *enumFileInfo;
|
||||
HANDLE findFileHandle;
|
||||
|
||||
enumFileInfo = &_enumerateFileInfoList[handle];
|
||||
|
||||
if (enumFileInfo->handle == NULL) {
|
||||
findFileHandle = FindFirstFile(enumFileInfo->pattern, &enumFileInfo->data);
|
||||
if (findFileHandle != INVALID_HANDLE_VALUE) {
|
||||
enumFileInfo->handle = findFileHandle;
|
||||
result = 1;
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
} else {
|
||||
result = FindNextFile(enumFileInfo->handle, &enumFileInfo->data);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
*outFileName = enumFileInfo->data.cFileName;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void platform_enumerate_files_end(int handle)
|
||||
{
|
||||
enumerate_file_info *enumFileInfo;
|
||||
|
||||
enumFileInfo = &_enumerateFileInfoList[handle];
|
||||
if (enumFileInfo->handle != NULL) {
|
||||
FindClose(enumFileInfo->handle);
|
||||
enumFileInfo->handle = NULL;
|
||||
}
|
||||
enumFileInfo->active = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* http://alter.org.ua/en/docs/win/args/
|
||||
*/
|
||||
|
||||
@@ -40,28 +40,26 @@
|
||||
* Loads only the basic information from a scenario.
|
||||
* rct2: 0x006761D6
|
||||
*/
|
||||
int scenario_load_basic(const char *path)
|
||||
int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *info)
|
||||
{
|
||||
FILE *file;
|
||||
rct_s6_header *s6Header = (rct_s6_header*)0x009E34E4;
|
||||
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
|
||||
|
||||
file = fopen(path, "rb");
|
||||
if (file != NULL) {
|
||||
// Read first chunk
|
||||
sawyercoding_read_chunk(file, (uint8*)s6Header);
|
||||
if (s6Header->type == S6_TYPE_SCENARIO) {
|
||||
sawyercoding_read_chunk(file, (uint8*)header);
|
||||
if (header->type == S6_TYPE_SCENARIO) {
|
||||
// Read second chunk
|
||||
sawyercoding_read_chunk(file, (uint8*)s6Info);
|
||||
sawyercoding_read_chunk(file, (uint8*)info);
|
||||
fclose(file);
|
||||
RCT2_GLOBAL(0x009AA00C, uint8) = 0;
|
||||
|
||||
// Checks for a scenario string object (possibly for localisation)
|
||||
if ((s6Info->entry.flags & 0xFF) != 255) {
|
||||
if (object_get_scenario_text(&s6Info->entry)) {
|
||||
if ((info->entry.flags & 0xFF) != 255) {
|
||||
if (object_get_scenario_text(&info->entry)) {
|
||||
int ebp = RCT2_GLOBAL(0x009ADAF8, uint32);
|
||||
format_string(s6Info->name, RCT2_GLOBAL(ebp, sint16), NULL);
|
||||
format_string(s6Info->details, RCT2_GLOBAL(ebp + 4, sint16), NULL);
|
||||
format_string(info->name, RCT2_GLOBAL(ebp, sint16), NULL);
|
||||
format_string(info->details, RCT2_GLOBAL(ebp + 4, sint16), NULL);
|
||||
RCT2_GLOBAL(0x009AA00C, uint8) = RCT2_GLOBAL(ebp + 6, uint8);
|
||||
object_free_scenario_text();
|
||||
}
|
||||
|
||||
@@ -402,7 +402,7 @@ extern rct_scenario_basic *gScenarioList;
|
||||
|
||||
int scenario_scores_save();
|
||||
void scenario_load_list();
|
||||
int scenario_load_basic(const char *path);
|
||||
int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *info);
|
||||
int scenario_load(const char *path);
|
||||
int scenario_load_and_play(const rct_scenario_basic *scenario);
|
||||
int scenario_load_and_play_from_path(const char *path);
|
||||
|
||||
@@ -18,9 +18,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <windows.h>
|
||||
#include "addresses.h"
|
||||
#include "rct2.h"
|
||||
#include "platform/platform.h"
|
||||
#include "scenario.h"
|
||||
|
||||
// Scenario list
|
||||
@@ -49,9 +48,8 @@ static rct_scenario_basic *get_scenario_by_filename(const char *filename)
|
||||
*/
|
||||
void scenario_load_list()
|
||||
{
|
||||
int i;
|
||||
HANDLE hFindFile;
|
||||
WIN32_FIND_DATAA findFileData;
|
||||
int i, enumFileHandle;
|
||||
char *enumFileName;
|
||||
|
||||
// Load scores
|
||||
scenario_scores_load();
|
||||
@@ -61,12 +59,12 @@ void scenario_load_list()
|
||||
gScenarioList[i].flags &= ~SCENARIO_FLAGS_VISIBLE;
|
||||
|
||||
// Enumerate through each scenario in the directory
|
||||
hFindFile = FindFirstFile(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), &findFileData);
|
||||
if (hFindFile != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
scenario_list_add(findFileData.cFileName);
|
||||
} while (FindNextFile(hFindFile, &findFileData));
|
||||
FindClose(hFindFile);
|
||||
enumFileHandle = platform_enumerate_files_begin(RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char));
|
||||
if (enumFileHandle >= 0) {
|
||||
while (platform_enumerate_files_next(enumFileHandle, &enumFileName)) {
|
||||
scenario_list_add(enumFileName);
|
||||
}
|
||||
platform_enumerate_files_end(enumFileHandle);
|
||||
}
|
||||
|
||||
// Sort alphabetically
|
||||
@@ -80,17 +78,18 @@ static void scenario_list_add(const char *path)
|
||||
{
|
||||
char scenarioPath[MAX_PATH];
|
||||
rct_scenario_basic *scenario;
|
||||
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
|
||||
rct_s6_header s6Header;
|
||||
rct_s6_info s6Info;
|
||||
|
||||
// Get absolute path
|
||||
subsitute_path(scenarioPath, RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), path);
|
||||
|
||||
// Load the basic scenario information
|
||||
if (!scenario_load_basic(scenarioPath))
|
||||
if (!scenario_load_basic(scenarioPath, &s6Header, &s6Info))
|
||||
return;
|
||||
|
||||
// Ignore scenarios where first header byte is not 255
|
||||
if (s6Info->var_000 != 255)
|
||||
if (s6Info.var_000 != 255)
|
||||
return;
|
||||
|
||||
// Check if scenario already exists in list, likely if in scores
|
||||
@@ -98,13 +97,13 @@ static void scenario_list_add(const char *path)
|
||||
if (scenario != NULL) {
|
||||
// Update the scenario information
|
||||
scenario->flags |= SCENARIO_FLAGS_VISIBLE;
|
||||
scenario->category = s6Info->category;
|
||||
scenario->objective_type = s6Info->objective_type;
|
||||
scenario->objective_arg_1 = s6Info->objective_arg_1;
|
||||
scenario->objective_arg_2 = s6Info->objective_arg_2;
|
||||
scenario->objective_arg_3 = s6Info->objective_arg_3;
|
||||
strcpy(scenario->name, s6Info->name);
|
||||
strcpy(scenario->details, s6Info->details);
|
||||
scenario->category = s6Info.category;
|
||||
scenario->objective_type = s6Info.objective_type;
|
||||
scenario->objective_arg_1 = s6Info.objective_arg_1;
|
||||
scenario->objective_arg_2 = s6Info.objective_arg_2;
|
||||
scenario->objective_arg_3 = s6Info.objective_arg_3;
|
||||
strcpy(scenario->name, s6Info.name);
|
||||
strcpy(scenario->details, s6Info.details);
|
||||
} else {
|
||||
// Check if the scenario list buffer has room for another scenario
|
||||
if (gScenarioListCount >= gScenarioListCapacity) {
|
||||
@@ -122,13 +121,13 @@ static void scenario_list_add(const char *path)
|
||||
scenario->flags = SCENARIO_FLAGS_VISIBLE;
|
||||
if (RCT2_GLOBAL(0x009AA00C, uint8) & 1)
|
||||
scenario->flags |= SCENARIO_FLAGS_SIXFLAGS;
|
||||
scenario->category = s6Info->category;
|
||||
scenario->objective_type = s6Info->objective_type;
|
||||
scenario->objective_arg_1 = s6Info->objective_arg_1;
|
||||
scenario->objective_arg_2 = s6Info->objective_arg_2;
|
||||
scenario->objective_arg_3 = s6Info->objective_arg_3;
|
||||
strcpy(scenario->name, s6Info->name);
|
||||
strcpy(scenario->details, s6Info->details);
|
||||
scenario->category = s6Info.category;
|
||||
scenario->objective_type = s6Info.objective_type;
|
||||
scenario->objective_arg_1 = s6Info.objective_arg_1;
|
||||
scenario->objective_arg_2 = s6Info.objective_arg_2;
|
||||
scenario->objective_arg_3 = s6Info.objective_arg_3;
|
||||
strcpy(scenario->name, s6Info.name);
|
||||
strcpy(scenario->details, s6Info.details);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user