329 lines
7.5 KiB
C++
329 lines
7.5 KiB
C++
#include "ss.h"
|
|
#include <memory>
|
|
#include "cdrom/cdromif.h"
|
|
#include "cdb.h"
|
|
#include "smpc.h"
|
|
#include "cart.h"
|
|
#include <ctime>
|
|
|
|
#define EXPORT extern "C" ECL_EXPORT
|
|
using namespace MDFN_IEN_SS;
|
|
|
|
int32 (*FirmwareSizeCallback)(const char *filename);
|
|
void (*FirmwareDataCallback)(const char *filename, uint8 *dest);
|
|
|
|
EXPORT void SetFirmwareCallbacks(int32 (*sizecallback)(const char *filename), void (*datacallback)(const char *filename, uint8 *dest))
|
|
{
|
|
FirmwareSizeCallback = sizecallback;
|
|
FirmwareDataCallback = datacallback;
|
|
}
|
|
|
|
struct FrontendTOC
|
|
{
|
|
int32 FirstTrack;
|
|
int32 LastTrack;
|
|
int32 DiskType;
|
|
struct
|
|
{
|
|
int32 Adr;
|
|
int32 Control;
|
|
int32 Lba;
|
|
int32 Valid;
|
|
} Tracks[101];
|
|
};
|
|
|
|
static void (*ReadTOCCallback)(int disk, FrontendTOC *dest);
|
|
static void (*ReadSector2448Callback)(int disk, int lba, uint8 *dest);
|
|
|
|
EXPORT void SetCDCallbacks(void (*toccallback)(int disk, FrontendTOC *dest), void (*sectorcallback)(int disk, int lba, uint8 *dest))
|
|
{
|
|
ReadTOCCallback = toccallback;
|
|
ReadSector2448Callback = sectorcallback;
|
|
}
|
|
|
|
class MyCDIF : public CDIF
|
|
{
|
|
private:
|
|
int disk;
|
|
|
|
public:
|
|
MyCDIF(int disk) : disk(disk)
|
|
{
|
|
FrontendTOC t;
|
|
ReadTOCCallback(disk, &t);
|
|
disc_toc.first_track = t.FirstTrack;
|
|
disc_toc.last_track = t.LastTrack;
|
|
disc_toc.disc_type = t.DiskType;
|
|
for (int i = 0; i < 101; i++)
|
|
{
|
|
disc_toc.tracks[i].adr = t.Tracks[i].Adr;
|
|
disc_toc.tracks[i].control = t.Tracks[i].Control;
|
|
disc_toc.tracks[i].lba = t.Tracks[i].Lba;
|
|
disc_toc.tracks[i].valid = t.Tracks[i].Valid;
|
|
}
|
|
}
|
|
|
|
virtual void HintReadSector(int32 lba) {}
|
|
virtual bool ReadRawSector(uint8 *buf, int32 lba)
|
|
{
|
|
ReadSector2448Callback(disk, lba, buf);
|
|
return true;
|
|
}
|
|
virtual bool ReadRawSectorPWOnly(uint8 *pwbuf, int32 lba, bool hint_fullread)
|
|
{
|
|
uint8 buff[2448];
|
|
ReadSector2448Callback(disk, lba, buff);
|
|
memcpy(pwbuf, buff + 2352, 96);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
static std::vector<CDIF *> CDInterfaces;
|
|
static uint32 *FrameBuffer;
|
|
static uint8 IsResetPushed; // 1 or 0
|
|
|
|
namespace MDFN_IEN_SS
|
|
{
|
|
extern bool LoadCD(std::vector<CDIF *> *CDInterfaces);
|
|
}
|
|
EXPORT bool Init(int numDisks, int cartType, int regionDefault, int regionAutodetect)
|
|
{
|
|
setting_ss_cart = cartType;
|
|
setting_ss_region_autodetect = regionAutodetect;
|
|
setting_ss_region_default = regionDefault;
|
|
|
|
FrameBuffer = (uint32 *)alloc_invisible(1024 * 1024 * sizeof(*FrameBuffer));
|
|
for (int i = 0; i < numDisks; i++)
|
|
CDInterfaces.push_back(new MyCDIF(i));
|
|
auto ret = LoadCD(&CDInterfaces);
|
|
if (ret)
|
|
SMPC_SetInput(12, nullptr, &IsResetPushed);
|
|
return ret;
|
|
}
|
|
|
|
EXPORT void HardReset()
|
|
{
|
|
// soft reset is handled as a normal button
|
|
SS_Reset(true);
|
|
}
|
|
|
|
EXPORT void SetDisk(int disk, bool open)
|
|
{
|
|
CDB_SetDisc(open, disk < 0 ? nullptr : CDInterfaces[disk]);
|
|
}
|
|
|
|
int setting_ss_slstartp = 0;
|
|
int setting_ss_slendp = 255;
|
|
int setting_ss_slstart = 0;
|
|
int setting_ss_slend = 239;
|
|
int setting_ss_region_default = SMPC_AREA_JP;
|
|
int setting_ss_cart = CART_NONE;
|
|
bool setting_ss_correct_aspect = true;
|
|
bool setting_ss_h_blend = false;
|
|
bool setting_ss_h_overscan = true;
|
|
bool setting_ss_region_autodetect = true;
|
|
bool setting_ss_input_sport1_multitap = false;
|
|
bool setting_ss_input_sport0_multitap = false;
|
|
|
|
namespace MDFN_IEN_SS
|
|
{
|
|
extern void Emulate(EmulateSpecStruct *espec_arg);
|
|
}
|
|
|
|
static uint8 ControllerInput[12 * 32];
|
|
bool InputLagged;
|
|
|
|
EXPORT void SetControllerData(const uint8_t* controllerData)
|
|
{
|
|
memcpy(ControllerInput, controllerData, sizeof(ControllerInput));
|
|
}
|
|
|
|
struct MyFrameInfo: public FrameInfo
|
|
{
|
|
int32_t ResetPushed;
|
|
};
|
|
|
|
EXPORT void FrameAdvance(MyFrameInfo& f)
|
|
{
|
|
EmulateSpecStruct e;
|
|
int32 LineWidths[1024];
|
|
memset(LineWidths, 0, sizeof(LineWidths));
|
|
e.pixels = FrameBuffer;
|
|
e.pitch32 = 1024;
|
|
e.LineWidths = LineWidths;
|
|
e.SoundBuf = f.SoundBuffer;
|
|
e.SoundBufMaxSize = 8192;
|
|
IsResetPushed = f.ResetPushed;
|
|
InputLagged = true;
|
|
Emulate(&e);
|
|
f.Samples = e.SoundBufSize;
|
|
f.Cycles = e.MasterCycles;
|
|
f.Lagged = InputLagged;
|
|
|
|
int w = 256;
|
|
for (int i = 0; i < e.h; i++)
|
|
w = std::max(w, LineWidths[i]);
|
|
|
|
const uint32 *src = FrameBuffer;
|
|
uint32 *dst = f.VideoBuffer;
|
|
const int srcp = 1024;
|
|
const int dstp = w;
|
|
src += e.y * srcp + e.x;
|
|
|
|
for (int j = 0; j < e.h; j++, src += srcp, dst += dstp)
|
|
{
|
|
memcpy(dst, src, LineWidths[j + e.y] * sizeof(*dst));
|
|
}
|
|
f.Width = w;
|
|
f.Height = e.h;
|
|
}
|
|
|
|
static const char *DeviceNames[] =
|
|
{
|
|
"none",
|
|
"gamepad",
|
|
"3dpad",
|
|
"mouse",
|
|
"wheel",
|
|
"mission",
|
|
"dmission",
|
|
"keyboard"};
|
|
|
|
EXPORT void SetupInput(const int *portdevices, const int *multitaps)
|
|
{
|
|
for (int i = 0; i < 2; i++)
|
|
SMPC_SetMultitap(i, multitaps[i]);
|
|
for (int i = 0; i < 12; i++)
|
|
SMPC_SetInput(i, DeviceNames[portdevices[i]], ControllerInput + i * 32);
|
|
}
|
|
|
|
void (*InputCallback)();
|
|
EXPORT void SetInputCallback(void (*callback)())
|
|
{
|
|
InputCallback = callback;
|
|
}
|
|
|
|
static std::vector<MemoryArea> MemoryAreas;
|
|
|
|
void AddMemoryDomain(const char *name, const void *ptr, int size, int flags)
|
|
{
|
|
MemoryArea m;
|
|
m.Data = (void*)ptr;
|
|
m.Name = name;
|
|
m.Size = size;
|
|
m.Flags = flags;
|
|
MemoryAreas.push_back(m);
|
|
}
|
|
|
|
EXPORT void GetMemoryAreas(MemoryArea* m)
|
|
{
|
|
memcpy(m, MemoryAreas.data(), MemoryAreas.size() * sizeof(MemoryArea));
|
|
}
|
|
|
|
EXPORT void SetRtc(int64 ticks, int language)
|
|
{
|
|
time_t time = ticks;
|
|
const struct tm *tm = gmtime(&time);
|
|
SMPC_SetRTC(tm, language);
|
|
}
|
|
|
|
namespace MDFN_IEN_SS
|
|
{
|
|
extern bool CorrectAspect;
|
|
extern bool ShowHOverscan;
|
|
extern bool DoHBlend;
|
|
extern int LineVisFirst;
|
|
extern int LineVisLast;
|
|
}
|
|
EXPORT void SetVideoParameters(bool correctAspect, bool hBlend, bool hOverscan, int sls, int sle)
|
|
{
|
|
CorrectAspect = correctAspect;
|
|
ShowHOverscan = hOverscan;
|
|
DoHBlend = hBlend;
|
|
LineVisFirst = sls;
|
|
LineVisLast = sle;
|
|
}
|
|
|
|
// if (BackupRAM_Dirty)SaveBackupRAM();
|
|
// if (CART_GetClearNVDirty())SaveCartNV();
|
|
|
|
/*static MDFN_COLD void CloseGame(void)
|
|
{
|
|
try { SaveBackupRAM(); } catch(std::exception& e) { MDFN_PrintError("%s", e.what()); }
|
|
try { SaveCartNV(); } catch(std::exception& e) { MDFN_PrintError("%s", e.what()); }
|
|
try { SaveRTC(); } catch(std::exception& e) { MDFN_PrintError("%s", e.what()); }
|
|
|
|
Cleanup();
|
|
}*/
|
|
|
|
/*
|
|
|
|
static MDFN_COLD void BackupCartNV(void)
|
|
{
|
|
const char* ext = nullptr;
|
|
void* nv_ptr = nullptr;
|
|
uint64 nv_size = 0;
|
|
|
|
CART_GetNVInfo(&ext, &nv_ptr, &nv_size);
|
|
|
|
if(ext)
|
|
MDFN_BackupSavFile(10, ext);
|
|
}*/
|
|
|
|
/*static MDFN_COLD void LoadCartNV(void)
|
|
{
|
|
const char* ext = nullptr;
|
|
void* nv_ptr = nullptr;
|
|
uint64 nv_size = 0;
|
|
|
|
CART_GetNVInfo(&ext, &nv_ptr, &nv_size);
|
|
|
|
if(ext)
|
|
{
|
|
//FileStream nvs(MDFN_MakeFName(MDFNMKF_SAV, 0, ext), FileStream::MODE_READ);
|
|
GZFileStream nvs(MDFN_MakeFName(MDFNMKF_SAV, 0, ext), GZFileStream::MODE::READ);
|
|
|
|
nvs.read(nv_ptr, nv_size);
|
|
}
|
|
}
|
|
|
|
static MDFN_COLD void SaveCartNV(void)
|
|
{
|
|
const char* ext = nullptr;
|
|
void* nv_ptr = nullptr;
|
|
uint64 nv_size = 0;
|
|
|
|
CART_GetNVInfo(&ext, &nv_ptr, &nv_size);
|
|
|
|
if(ext)
|
|
{
|
|
//FileStream nvs(MDFN_MakeFName(MDFNMKF_SAV, 0, ext), FileStream::MODE_WRITE_INPLACE);
|
|
GZFileStream nvs(MDFN_MakeFName(MDFNMKF_SAV, 0, ext), GZFileStream::MODE::WRITE);
|
|
|
|
nvs.write(nv_ptr, nv_size);
|
|
|
|
nvs.close();
|
|
}
|
|
}*/
|
|
|
|
/*static MDFN_COLD void SaveRTC(void)
|
|
{
|
|
FileStream sds(MDFN_MakeFName(MDFNMKF_SAV, 0, "smpc"), FileStream::MODE_WRITE_INPLACE);
|
|
|
|
SMPC_SaveNV(&sds);
|
|
|
|
sds.close();
|
|
}
|
|
|
|
static MDFN_COLD void LoadRTC(void)
|
|
{
|
|
FileStream sds(MDFN_MakeFName(MDFNMKF_SAV, 0, "smpc"), FileStream::MODE_READ);
|
|
|
|
SMPC_LoadNV(&sds);
|
|
}*/
|
|
|
|
int main()
|
|
{
|
|
return 0;
|
|
}
|