#include "ss.h" #include #include "cdrom/cdromif.h" #include "cdb.h" #include "smpc.h" #include "cart.h" #include #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 CDInterfaces; static uint32 *FrameBuffer; static uint8 IsResetPushed; // 1 or 0 namespace MDFN_IEN_SS { extern bool LoadCD(std::vector *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 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; }