185 lines
4.3 KiB
C++
185 lines
4.3 KiB
C++
#include "../emulibc/emulibc.h"
|
|
#include "../emulibc/waterboxcore.h"
|
|
#include <stdint.h>
|
|
#include "dobiestation/src/core/emulator.hpp"
|
|
#include "dobiestation/src/core/iop/cdvd/cdvd_container.hpp"
|
|
|
|
|
|
static size_t cd_length;
|
|
static void (*cdcallback)(size_t sector, uint8_t* dest);
|
|
static size_t cd_pos;
|
|
|
|
class DVD: public CDVD_Container
|
|
{
|
|
virtual bool open(std::string name) override
|
|
{
|
|
return true;
|
|
}
|
|
virtual void close() override {}
|
|
virtual size_t read(uint8_t* buff, size_t bytes)
|
|
{
|
|
uint8_t* buff_end = buff + bytes;
|
|
if (cd_pos % 2048 != 0)
|
|
{
|
|
auto offset = cd_pos % 2048;
|
|
auto nread = std::min(2048 - offset, bytes);
|
|
uint8_t tmp[2048];
|
|
cdcallback(cd_pos / 2048, tmp);
|
|
memcpy(buff, tmp + offset, nread);
|
|
buff += nread;
|
|
cd_pos += nread;
|
|
}
|
|
while (buff_end >= buff + 2048)
|
|
{
|
|
cdcallback(cd_pos / 2048, buff);
|
|
buff += 2048;
|
|
cd_pos += 2048;
|
|
}
|
|
if (buff_end > buff)
|
|
{
|
|
auto nread = buff_end - buff;
|
|
uint8_t tmp[2048];
|
|
cdcallback(cd_pos / 2048, tmp);
|
|
memcpy(buff, tmp, nread);
|
|
cd_pos += nread;
|
|
}
|
|
return bytes;
|
|
}
|
|
virtual void seek(size_t pos, std::ios::seekdir whence) override
|
|
{
|
|
cd_pos = pos * 2048;
|
|
}
|
|
virtual bool is_open() override
|
|
{
|
|
return true;
|
|
}
|
|
virtual size_t get_size() override
|
|
{
|
|
return cd_length;
|
|
}
|
|
};
|
|
|
|
|
|
struct MyFrameInfo: public FrameInfo
|
|
{
|
|
uint32_t Buttons;
|
|
uint32_t Axes;
|
|
};
|
|
|
|
Emulator* emu;
|
|
|
|
struct SyncSettings
|
|
{
|
|
bool EEJit;
|
|
bool VU0Jit;
|
|
bool VU1Jit;
|
|
};
|
|
|
|
ECL_EXPORT bool Initialize(
|
|
const uint8_t* bios,
|
|
size_t cd_length_,
|
|
void (*cdcallback_)(size_t sector, uint8_t* dest),
|
|
const SyncSettings& syncSettings
|
|
)
|
|
{
|
|
cd_length = cd_length_;
|
|
cdcallback = cdcallback_;
|
|
emu = new Emulator();
|
|
emu->reset();
|
|
emu->set_skip_BIOS_hack(LOAD_DISC);
|
|
emu->load_BIOS(bios);
|
|
emu->load_memcard(0, "MEMCARD0");
|
|
if (!emu->load_CDVD_Container("", std::unique_ptr<CDVD_Container>(new DVD())))
|
|
return false;
|
|
emu->set_ee_mode(syncSettings.EEJit ? JIT : INTERPRETER);
|
|
printf("EE Mode: %s\n", syncSettings.EEJit ? "JIT" : "INTERPRETER");
|
|
emu->set_vu0_mode(syncSettings.VU0Jit ? JIT : INTERPRETER);
|
|
printf("VU0 Mode: %s\n", syncSettings.VU0Jit ? "JIT" : "INTERPRETER");
|
|
emu->set_vu1_mode(syncSettings.VU1Jit ? JIT : INTERPRETER);
|
|
printf("VU1 Mode: %s\n", syncSettings.VU1Jit ? "JIT" : "INTERPRETER");
|
|
emu->set_wav_output(true);
|
|
return true;
|
|
}
|
|
|
|
static int16_t* audio_pos;
|
|
void hacky_enqueue_audio(stereo_sample s)
|
|
{
|
|
*audio_pos++ = s.left;
|
|
*audio_pos++ = s.right;
|
|
}
|
|
|
|
bool hacky_lag_flag;
|
|
void (*hacky_input_callback)();
|
|
|
|
ECL_EXPORT void FrameAdvance(MyFrameInfo& f)
|
|
{
|
|
for (auto i = 0; i < 16; i++)
|
|
{
|
|
if (f.Buttons & 1 << i)
|
|
{
|
|
emu->press_button((PAD_BUTTON)i);
|
|
}
|
|
else
|
|
{
|
|
emu->release_button((PAD_BUTTON)i);
|
|
}
|
|
}
|
|
for (auto i = 0; i < 4; i++)
|
|
{
|
|
emu->update_joystick((JOYSTICK)(i >> 1), (JOYSTICK_AXIS)(i & 1), f.Axes >> (i * 8));
|
|
}
|
|
audio_pos = f.SoundBuffer;
|
|
hacky_lag_flag = true;
|
|
emu->run();
|
|
f.Lagged = hacky_lag_flag;
|
|
emu->get_inner_resolution(f.Width, f.Height);
|
|
{
|
|
const uint32_t* src = emu->get_framebuffer();
|
|
const uint32_t* srcend = src + f.Width * f.Height;
|
|
uint32_t* dst = f.VideoBuffer;
|
|
while (src < srcend)
|
|
{
|
|
*dst = *src;
|
|
std::swap(((uint8_t*)dst)[2], ((uint8_t*)dst)[0]);
|
|
src++;
|
|
dst++;
|
|
}
|
|
}
|
|
|
|
f.Samples = (audio_pos - f.SoundBuffer) / 2;
|
|
audio_pos = nullptr;
|
|
}
|
|
|
|
ECL_EXPORT void GetMemoryAreas(MemoryArea *m)
|
|
{
|
|
m[0].Data = emu->RDRAM;
|
|
m[0].Name = "RDRAM";
|
|
m[0].Size = 1024 * 1024 * 32;
|
|
m[0].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE4 | MEMORYAREA_FLAGS_PRIMARY;
|
|
|
|
m[1].Data = emu->IOP_RAM;
|
|
m[1].Name = "IOP_RAM";
|
|
m[1].Size = 1024 * 1024 * 2;
|
|
m[1].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE4;
|
|
|
|
m[2].Data = emu->BIOS;
|
|
m[2].Name = "BIOS";
|
|
m[2].Size = 1024 * 1024 * 4;
|
|
m[2].Flags = MEMORYAREA_FLAGS_WORDSIZE4;
|
|
|
|
m[3].Data = emu->SPU_RAM;
|
|
m[3].Name = "SPU_RAM";
|
|
m[3].Size = 1024 * 1024 * 2;
|
|
m[3].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE4;
|
|
|
|
m[4].Data = emu->memcard.mem;
|
|
m[4].Name = "MEMCARD0";
|
|
m[4].Size = 0x840000;
|
|
m[4].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1 | MEMORYAREA_FLAGS_SAVERAMMABLE;
|
|
}
|
|
|
|
ECL_EXPORT void SetInputCallback(void (*callback)())
|
|
{
|
|
hacky_input_callback = callback;
|
|
}
|