2015-08-09 20:39:32 +00:00
|
|
|
#include "naomi_cart.h"
|
|
|
|
#include "cfg/cfg.h"
|
2018-08-13 18:32:07 +00:00
|
|
|
#include "naomi.h"
|
2015-08-09 20:39:32 +00:00
|
|
|
|
|
|
|
u8* RomPtr;
|
|
|
|
u32 RomSize;
|
|
|
|
|
2015-08-09 21:40:05 +00:00
|
|
|
#if HOST_OS == OS_WINDOWS
|
|
|
|
typedef HANDLE fd_t;
|
|
|
|
#define INVALID_FD INVALID_HANDLE_VALUE
|
|
|
|
#else
|
|
|
|
typedef int fd_t;
|
|
|
|
#define INVALID_FD -1
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
2015-08-11 17:07:23 +00:00
|
|
|
#include <sys/mman.h>
|
2015-08-09 21:40:05 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
fd_t* RomCacheMap;
|
2015-08-09 20:39:32 +00:00
|
|
|
u32 RomCacheMapCount;
|
|
|
|
|
|
|
|
char SelectedFile[512];
|
2018-10-17 11:18:24 +00:00
|
|
|
char naomi_game_id[33];
|
2015-08-09 20:39:32 +00:00
|
|
|
|
2018-08-13 18:32:07 +00:00
|
|
|
extern s8 joyx[4],joyy[4];
|
|
|
|
extern u8 rt[4], lt[4];
|
|
|
|
|
|
|
|
static std::string trim(const std::string s)
|
|
|
|
{
|
|
|
|
std::string r(s);
|
|
|
|
while (!r.empty() && r[0] == ' ')
|
|
|
|
r.erase(0, 1);
|
|
|
|
while (!r.empty() && r[r.size() - 1] == ' ')
|
|
|
|
r.erase(r.size() - 1);
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u16 getJoystickXAxis()
|
|
|
|
{
|
|
|
|
return (joyx[0] + 128) << 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u16 getJoystickYAxis()
|
|
|
|
{
|
|
|
|
return (joyy[0] + 128) << 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u16 getLeftTriggerAxis()
|
|
|
|
{
|
|
|
|
return lt[0] << 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u16 getRightTriggerAxis()
|
|
|
|
{
|
|
|
|
return rt[0] << 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
static NaomiInputMapping naomi_default_mapping = {
|
|
|
|
{ getJoystickXAxis, getJoystickYAxis, getRightTriggerAxis, getLeftTriggerAxis },
|
2018-10-11 08:09:28 +00:00
|
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 },
|
|
|
|
{ 0x40, 0x01, 0x02, 0x80, 0x20, 0x10, 0x08, 0x04, 0, 0x80, 0x40, 0, 0 },
|
2018-08-13 18:32:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void parse_comment(const char *line)
|
|
|
|
{
|
|
|
|
std::string s(line + 1);
|
|
|
|
s = trim(s);
|
|
|
|
if (strncmp(s.c_str(), "input-mapping:", 14))
|
|
|
|
return;
|
|
|
|
|
|
|
|
s.erase(0, 14);
|
|
|
|
|
|
|
|
s = trim(s);
|
|
|
|
while (!s.empty())
|
|
|
|
{
|
|
|
|
size_t p = s.find_first_of(",");
|
|
|
|
if (p == -1)
|
|
|
|
p = s.size();
|
|
|
|
std::string mapping = s.substr(0, p);
|
|
|
|
size_t eq = mapping.find_first_of("=");
|
|
|
|
if (eq == -1 || eq == mapping.size() - 1)
|
|
|
|
printf("Warning: unparseable mapping %s\n", mapping.c_str());
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::string dc_key = trim(mapping.substr(0, eq));
|
|
|
|
std::string naomi_key = trim(mapping.substr(eq + 1));
|
|
|
|
if (!strncmp(naomi_key.c_str(), "axis_", 5))
|
|
|
|
{
|
|
|
|
int axis = naomi_key[5] - '0';
|
|
|
|
if (axis >= 4)
|
|
|
|
printf("Warning: invalid axis number %d\n", axis);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
getNaomiAxisFP fp = NULL;
|
|
|
|
if (dc_key == "axis_x")
|
|
|
|
fp = &getJoystickXAxis;
|
|
|
|
else if (dc_key == "axis_y")
|
|
|
|
fp = &getJoystickYAxis;
|
|
|
|
else if (dc_key == "axis_trigger_left")
|
|
|
|
fp = &getLeftTriggerAxis;
|
|
|
|
else if (dc_key == "axis_trigger_right")
|
|
|
|
fp = &getRightTriggerAxis;
|
|
|
|
else
|
|
|
|
printf("Warning: invalid controller axis %s\n", dc_key.c_str());
|
|
|
|
if (fp != NULL)
|
|
|
|
Naomi_Mapping.axis[axis] = fp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int byte = naomi_key[0] - '0';
|
|
|
|
size_t colon = naomi_key.find_first_of(":");
|
|
|
|
if (colon == -1 || colon == naomi_key.size() - 1)
|
|
|
|
printf("Warning: unparseable naomi key %s\n", naomi_key.c_str());
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int value = atoi(naomi_key.substr(colon + 1).c_str());
|
|
|
|
int dc_btnnum = -1;
|
|
|
|
if (dc_key == "x")
|
|
|
|
dc_btnnum = 10;
|
|
|
|
else if (dc_key == "y")
|
|
|
|
dc_btnnum = 9;
|
|
|
|
else if (dc_key == "a")
|
|
|
|
dc_btnnum = 2;
|
|
|
|
else if (dc_key == "b")
|
|
|
|
dc_btnnum = 1;
|
|
|
|
else if (dc_key == "c")
|
|
|
|
dc_btnnum = 0;
|
|
|
|
else if (dc_key == "d")
|
|
|
|
dc_btnnum = 11;
|
|
|
|
else if (dc_key == "z")
|
|
|
|
dc_btnnum = 8;
|
|
|
|
else if (dc_key == "up")
|
|
|
|
dc_btnnum = 4;
|
|
|
|
else if (dc_key == "down")
|
|
|
|
dc_btnnum = 5;
|
|
|
|
else if (dc_key == "left")
|
|
|
|
dc_btnnum = 6;
|
|
|
|
else if (dc_key == "right")
|
|
|
|
dc_btnnum = 7;
|
|
|
|
else if (dc_key == "start")
|
|
|
|
dc_btnnum = 3;
|
|
|
|
else
|
|
|
|
printf("Warning: unparseable dc key %s\n", dc_key.c_str());
|
|
|
|
if (dc_btnnum != -1)
|
|
|
|
{
|
|
|
|
Naomi_Mapping.button_mapping_byte[dc_btnnum] = byte;
|
|
|
|
Naomi_Mapping.button_mapping_mask[dc_btnnum] = value;
|
|
|
|
printf("Button %d: mapped to %d:%d\n", dc_btnnum, Naomi_Mapping.button_mapping_byte[dc_btnnum], Naomi_Mapping.button_mapping_mask[dc_btnnum]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (p == s.size())
|
|
|
|
break;
|
|
|
|
s = trim(s.substr(p + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-08-09 20:39:32 +00:00
|
|
|
bool naomi_cart_LoadRom(char* file)
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("\nnullDC-Naomi rom loader v1.2\n");
|
|
|
|
|
|
|
|
size_t folder_pos = strlen(file) - 1;
|
2015-08-11 17:07:23 +00:00
|
|
|
while (folder_pos>1 && (file[folder_pos] != '\\' && file[folder_pos] != '/'))
|
2015-08-09 20:39:32 +00:00
|
|
|
folder_pos--;
|
|
|
|
|
|
|
|
folder_pos++;
|
|
|
|
|
2016-02-22 17:37:41 +00:00
|
|
|
// FIXME: Data loss if buffer is too small
|
2015-08-09 20:39:32 +00:00
|
|
|
char t[512];
|
2016-02-22 17:37:41 +00:00
|
|
|
strncpy(t, file, sizeof(t));
|
|
|
|
t[sizeof(t) - 1] = '\0';
|
|
|
|
|
2018-08-13 18:32:07 +00:00
|
|
|
Naomi_Mapping = naomi_default_mapping;
|
|
|
|
|
2015-08-09 20:39:32 +00:00
|
|
|
vector<string> files;
|
|
|
|
vector<u32> fstart;
|
|
|
|
vector<u32> fsize;
|
|
|
|
u32 setsize = 0;
|
2018-10-24 08:34:50 +00:00
|
|
|
bool raw_bin_file = false;
|
2015-08-09 20:39:32 +00:00
|
|
|
|
2018-10-21 20:16:28 +00:00
|
|
|
char *pdot = strrchr(file, '.');
|
|
|
|
if (pdot != NULL && (!strcmp(pdot, ".lst") || !strcmp(pdot, ".LST")))
|
2015-08-09 20:39:32 +00:00
|
|
|
{
|
2018-10-21 20:16:28 +00:00
|
|
|
// LST file
|
|
|
|
|
|
|
|
FILE* fl = fopen(t, "r");
|
|
|
|
if (!fl)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
char* line = fgets(t, 512, fl);
|
|
|
|
if (!line)
|
|
|
|
{
|
|
|
|
fclose(fl);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* eon = strstr(line, "\n");
|
|
|
|
if (!eon)
|
|
|
|
printf("+Loading naomi rom that has no name\n");
|
2018-08-13 18:32:07 +00:00
|
|
|
else
|
2018-10-21 20:16:28 +00:00
|
|
|
*eon = 0;
|
|
|
|
|
|
|
|
printf("+Loading naomi rom : %s\n", line);
|
|
|
|
|
|
|
|
line = fgets(t, 512, fl);
|
|
|
|
if (!line)
|
2018-08-13 18:32:07 +00:00
|
|
|
{
|
2018-10-21 20:16:28 +00:00
|
|
|
fclose(fl);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
RomSize = 0;
|
|
|
|
|
|
|
|
while (line)
|
|
|
|
{
|
|
|
|
if (line[0] == '#')
|
|
|
|
parse_comment(line);
|
|
|
|
else
|
2018-10-17 11:18:24 +00:00
|
|
|
{
|
2018-10-21 20:16:28 +00:00
|
|
|
char filename[512];
|
|
|
|
u32 addr, sz;
|
|
|
|
if (sscanf(line, "\"%[^\"]\",%x,%x", filename, &addr, &sz) == 3)
|
|
|
|
{
|
|
|
|
files.push_back(filename);
|
|
|
|
fstart.push_back(addr);
|
|
|
|
fsize.push_back(sz);
|
|
|
|
setsize += sz;
|
|
|
|
RomSize = max(RomSize, (addr + sz));
|
|
|
|
}
|
|
|
|
else if (line[0] != 0 && line[0] != '\n' && line[0] != '\r')
|
|
|
|
printf("Warning: invalid line in .lst file: %s\n", line);
|
2018-10-17 11:18:24 +00:00
|
|
|
}
|
2018-10-21 20:16:28 +00:00
|
|
|
line = fgets(t, 512, fl);
|
2018-08-13 18:32:07 +00:00
|
|
|
}
|
2018-10-21 20:16:28 +00:00
|
|
|
fclose(fl);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// BIN loading
|
|
|
|
FILE* fp = fopen(t, "rb");
|
|
|
|
if (fp == NULL)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
fseek(fp, 0, SEEK_END);
|
|
|
|
u32 file_size = ftell(fp);
|
|
|
|
fclose(fp);
|
|
|
|
files.push_back(t);
|
|
|
|
fstart.push_back(0);
|
|
|
|
fsize.push_back(file_size);
|
|
|
|
setsize = file_size;
|
|
|
|
RomSize = file_size;
|
2018-10-24 08:34:50 +00:00
|
|
|
raw_bin_file = true;
|
2015-08-09 20:39:32 +00:00
|
|
|
}
|
|
|
|
|
2018-10-21 20:16:28 +00:00
|
|
|
printf("+%ld romfiles, %.2f MB set size, %.2f MB set address space\n", files.size(), setsize / 1024.f / 1024.f, RomSize / 1024.f / 1024.f);
|
2015-08-09 20:39:32 +00:00
|
|
|
|
|
|
|
if (RomCacheMap)
|
|
|
|
{
|
|
|
|
RomCacheMapCount = 0;
|
|
|
|
delete RomCacheMap;
|
|
|
|
}
|
|
|
|
|
|
|
|
RomCacheMapCount = (u32)files.size();
|
2018-10-17 11:18:24 +00:00
|
|
|
RomCacheMap = new fd_t[files.size()]();
|
2015-08-09 20:39:32 +00:00
|
|
|
|
|
|
|
//Allocate space for the ram, so we are sure we have a segment of continius ram
|
2015-08-09 21:40:05 +00:00
|
|
|
#if HOST_OS == OS_WINDOWS
|
2015-08-09 20:39:32 +00:00
|
|
|
RomPtr = (u8*)VirtualAlloc(0, RomSize, MEM_RESERVE, PAGE_NOACCESS);
|
2015-08-09 21:40:05 +00:00
|
|
|
#else
|
2015-08-11 17:07:23 +00:00
|
|
|
RomPtr = (u8*)mmap(0, RomSize, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
2015-08-09 21:40:05 +00:00
|
|
|
#endif
|
|
|
|
|
2015-08-09 20:39:32 +00:00
|
|
|
verify(RomPtr != 0);
|
2015-08-11 17:07:23 +00:00
|
|
|
verify(RomPtr != (void*)-1);
|
2015-08-09 20:39:32 +00:00
|
|
|
|
2018-10-17 11:18:24 +00:00
|
|
|
bool load_error = false;
|
|
|
|
|
2015-08-09 20:39:32 +00:00
|
|
|
//Create File Mapping Objects
|
|
|
|
for (size_t i = 0; i<files.size(); i++)
|
|
|
|
{
|
2018-10-24 08:34:50 +00:00
|
|
|
if (!raw_bin_file)
|
2018-10-21 20:16:28 +00:00
|
|
|
{
|
|
|
|
strncpy(t, file, sizeof(t));
|
|
|
|
t[sizeof(t) - 1] = '\0';
|
|
|
|
t[folder_pos] = 0;
|
|
|
|
strcat(t, files[i].c_str());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strncpy(t, files[i].c_str(), sizeof(t));
|
|
|
|
t[sizeof(t) - 1] = '\0';
|
|
|
|
}
|
|
|
|
|
2015-08-09 21:40:05 +00:00
|
|
|
fd_t RomCache;
|
2015-08-09 20:39:32 +00:00
|
|
|
|
|
|
|
if (strcmp(files[i].c_str(), "null") == 0)
|
|
|
|
{
|
2015-08-09 21:40:05 +00:00
|
|
|
RomCacheMap[i] = INVALID_FD;
|
2015-08-09 20:39:32 +00:00
|
|
|
continue;
|
|
|
|
}
|
2015-08-09 21:40:05 +00:00
|
|
|
#if HOST_OS == OS_WINDOWS
|
2015-08-09 20:39:32 +00:00
|
|
|
RomCache = CreateFile(t, FILE_READ_ACCESS, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
2015-08-09 21:40:05 +00:00
|
|
|
#else
|
|
|
|
RomCache = open(t, O_RDONLY);
|
|
|
|
#endif
|
|
|
|
if (RomCache == INVALID_FD)
|
2015-08-09 20:39:32 +00:00
|
|
|
{
|
2018-10-21 20:16:28 +00:00
|
|
|
printf("-Unable to read file %s: error %d\n", t, errno);
|
2015-08-09 21:40:05 +00:00
|
|
|
RomCacheMap[i] = INVALID_FD;
|
2018-10-17 11:18:24 +00:00
|
|
|
load_error = true;
|
|
|
|
break;
|
2015-08-09 20:39:32 +00:00
|
|
|
}
|
|
|
|
|
2015-08-09 21:40:05 +00:00
|
|
|
#if HOST_OS == OS_WINDOWS
|
2018-10-21 00:55:07 +00:00
|
|
|
// Windows doesn't allow mapping a read-only file to a memory area larger than the file size
|
|
|
|
BY_HANDLE_FILE_INFORMATION file_info;
|
|
|
|
GetFileInformationByHandle(RomCache, &file_info);
|
|
|
|
fsize[i] = file_info.nFileSizeLow;
|
2015-08-09 20:39:32 +00:00
|
|
|
RomCacheMap[i] = CreateFileMapping(RomCache, 0, PAGE_READONLY, 0, fsize[i], 0);
|
2018-10-21 00:55:07 +00:00
|
|
|
verify(RomCacheMap[i] != NULL);
|
2015-08-09 20:39:32 +00:00
|
|
|
verify(CloseHandle(RomCache));
|
2015-08-09 21:40:05 +00:00
|
|
|
#else
|
|
|
|
RomCacheMap[i] = RomCache;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
verify(RomCacheMap[i] != INVALID_FD);
|
2018-10-17 11:18:24 +00:00
|
|
|
//printf("-Preparing \"%s\" at 0x%08X, size 0x%08X\n", files[i].c_str(), fstart[i], fsize[i]);
|
2015-08-09 20:39:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//Release the segment we reserved so we can map the files there
|
2015-08-09 21:40:05 +00:00
|
|
|
#if HOST_OS == OS_WINDOWS
|
2015-08-09 20:39:32 +00:00
|
|
|
verify(VirtualFree(RomPtr, 0, MEM_RELEASE));
|
2015-08-09 21:40:05 +00:00
|
|
|
#else
|
|
|
|
munmap(RomPtr, RomSize);
|
|
|
|
#endif
|
2015-08-09 20:39:32 +00:00
|
|
|
|
2018-10-17 11:18:24 +00:00
|
|
|
if (load_error)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < files.size(); i++)
|
|
|
|
if (RomCacheMap[i] != INVALID_FD)
|
2018-10-20 18:08:51 +00:00
|
|
|
#if HOST_OS == OS_WINDOWS
|
|
|
|
CloseHandle(RomCacheMap[i]);
|
|
|
|
#else
|
2018-10-17 11:18:24 +00:00
|
|
|
close(RomCacheMap[i]);
|
2018-10-20 18:08:51 +00:00
|
|
|
#endif
|
2018-10-17 11:18:24 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//We have all file mapping objects, we start to map the ram
|
|
|
|
|
2015-08-09 20:39:32 +00:00
|
|
|
//Map the files into the segment of the ram that was reserved
|
|
|
|
for (size_t i = 0; i<RomCacheMapCount; i++)
|
|
|
|
{
|
|
|
|
u8* RomDest = RomPtr + fstart[i];
|
|
|
|
|
2015-08-09 21:40:05 +00:00
|
|
|
if (RomCacheMap[i] == INVALID_FD)
|
2015-08-09 20:39:32 +00:00
|
|
|
{
|
2018-10-17 11:18:24 +00:00
|
|
|
//printf("-Reserving ram at 0x%08X, size 0x%08X\n", fstart[i], fsize[i]);
|
2015-08-09 21:40:05 +00:00
|
|
|
|
|
|
|
#if HOST_OS == OS_WINDOWS
|
|
|
|
bool mapped = RomDest == VirtualAlloc(RomDest, fsize[i], MEM_RESERVE, PAGE_NOACCESS);
|
|
|
|
#else
|
|
|
|
bool mapped = RomDest == (u8*)mmap(RomDest, RomSize, PROT_NONE, MAP_PRIVATE, 0, 0);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
verify(mapped);
|
2015-08-09 20:39:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-10-17 11:18:24 +00:00
|
|
|
//printf("-Mapping \"%s\" at 0x%08X, size 0x%08X\n", files[i].c_str(), fstart[i], fsize[i]);
|
2015-08-09 21:40:05 +00:00
|
|
|
#if HOST_OS == OS_WINDOWS
|
2018-08-13 18:32:07 +00:00
|
|
|
bool mapped = RomDest == MapViewOfFileEx(RomCacheMap[i], FILE_MAP_READ, 0, 0, fsize[i], RomDest);
|
2015-08-09 21:40:05 +00:00
|
|
|
#else
|
2018-08-13 18:32:07 +00:00
|
|
|
bool mapped = RomDest == mmap(RomDest, fsize[i], PROT_READ, MAP_PRIVATE, RomCacheMap[i], 0 );
|
2015-08-09 21:40:05 +00:00
|
|
|
#endif
|
|
|
|
if (!mapped)
|
2015-08-09 20:39:32 +00:00
|
|
|
{
|
2018-10-17 11:18:24 +00:00
|
|
|
printf("-Mapping ROM FAILED: %s @ %08x size %x\n", files[i].c_str(), fstart[i], fsize[i]);
|
2015-08-09 20:39:32 +00:00
|
|
|
return false;
|
|
|
|
}
|
2018-10-17 11:18:24 +00:00
|
|
|
if (fstart[i] == 0 && fsize[i] >= 0x50)
|
|
|
|
{
|
2018-10-19 17:23:43 +00:00
|
|
|
memcpy(naomi_game_id, RomDest + 0x30, sizeof(naomi_game_id) - 1);
|
|
|
|
naomi_game_id[sizeof(naomi_game_id) - 1] = '\0';
|
2018-10-17 11:18:24 +00:00
|
|
|
if (!strcmp("AWNAOMI ", naomi_game_id) && fsize[i] >= 0xFF50)
|
|
|
|
{
|
2018-10-19 17:23:43 +00:00
|
|
|
memcpy(naomi_game_id, RomDest + 0xFF30, sizeof(naomi_game_id) - 1);
|
2018-10-17 11:18:24 +00:00
|
|
|
}
|
2018-10-19 17:23:43 +00:00
|
|
|
for (char *p = naomi_game_id + sizeof(naomi_game_id) - 2; *p == ' ' && p >= naomi_game_id; *p-- = '\0');
|
2018-10-17 11:18:24 +00:00
|
|
|
printf("NAOMI GAME ID [%s]\n", naomi_game_id);
|
|
|
|
}
|
2015-08-09 20:39:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//done :)
|
|
|
|
printf("\nMapped ROM Successfully !\n\n");
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool naomi_cart_SelectFile(void* handle)
|
|
|
|
{
|
2015-08-09 21:40:05 +00:00
|
|
|
cfgLoadStr("config", "image", SelectedFile, "null");
|
|
|
|
|
|
|
|
#if HOST_OS == OS_WINDOWS
|
|
|
|
if (strcmp(SelectedFile, "null") == 0) {
|
|
|
|
OPENFILENAME ofn = { 0 };
|
|
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
|
|
ofn.hInstance = (HINSTANCE)GetModuleHandle(0);
|
|
|
|
ofn.lpstrFile = SelectedFile;
|
|
|
|
ofn.nMaxFile = MAX_PATH;
|
2018-10-24 08:34:50 +00:00
|
|
|
ofn.lpstrFilter = "*.lst\0*.lst\0*.bin\0*.bin\0*.dat\0*.dat\0\0";
|
2015-08-09 21:40:05 +00:00
|
|
|
ofn.nFilterIndex = 0;
|
|
|
|
ofn.hwndOwner = (HWND)handle;
|
|
|
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
|
|
|
|
|
|
|
|
if (GetOpenFileName(&ofn) <= 0)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
2015-08-09 20:39:32 +00:00
|
|
|
if (!naomi_cart_LoadRom(SelectedFile))
|
|
|
|
{
|
2018-10-17 11:18:24 +00:00
|
|
|
printf("Cannot load %s: error %d\n", SelectedFile, errno);
|
|
|
|
return false;
|
2015-08-09 20:39:32 +00:00
|
|
|
}
|
|
|
|
|
2018-10-17 11:18:24 +00:00
|
|
|
cfgSaveStr("emu", "gamefile", SelectedFile);
|
2015-08-09 20:39:32 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool naomi_cart_Read(u32 offset, u32 size, void* dst) {
|
|
|
|
if (!RomPtr)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
memcpy(dst, naomi_cart_GetPtr(offset, size), size);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void* naomi_cart_GetPtr(u32 offset, u32 size) {
|
|
|
|
|
|
|
|
offset &= 0x0FFFffff;
|
|
|
|
|
|
|
|
verify(offset < RomSize);
|
2018-10-21 20:16:28 +00:00
|
|
|
verify((offset + size) <= RomSize);
|
2015-08-09 20:39:32 +00:00
|
|
|
|
|
|
|
return &RomPtr[offset];
|
2015-08-11 17:07:23 +00:00
|
|
|
}
|