Skip to content

Commit

Permalink
Add Light Phaser support. Fix #43
Browse files Browse the repository at this point in the history
  • Loading branch information
drhelius committed Dec 27, 2024
1 parent 2cc8716 commit c373f96
Show file tree
Hide file tree
Showing 13 changed files with 215 additions and 52 deletions.
23 changes: 23 additions & 0 deletions platforms/desktop-shared/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,26 @@ static void sdl_events_emu(const SDL_Event* event)
}
break;

case (SDL_MOUSEBUTTONDOWN):
{
if (config_emulator.light_phaser && gui_main_window_hovered)
{
if (event->button.button == SDL_BUTTON_LEFT)
emu_key_pressed(Joypad_1, Key_1);
}
}
break;

case (SDL_MOUSEBUTTONUP):
{
if (config_emulator.light_phaser)
{
if (event->button.button == SDL_BUTTON_LEFT)
emu_key_released(Joypad_1, Key_1);
}
}
break;

case SDL_CONTROLLERBUTTONDOWN:
{
for (int i = 0; i < 2; i++)
Expand Down Expand Up @@ -500,6 +520,9 @@ static void handle_mouse_cursor(void)
if (!config_emulator.show_menu && !config_debug.debug)
hide_cursor = true;

if (config_emulator.light_phaser)
hide_cursor = false;

if (hide_cursor)
ImGui::SetMouseCursor(ImGuiMouseCursor_None);
else
Expand Down
2 changes: 2 additions & 0 deletions platforms/desktop-shared/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ void config_read(void)
config_emulator.window_width = read_int("Emulator", "WindowWidth", 640);
config_emulator.window_height = read_int("Emulator", "WindowHeight", 503);
config_emulator.status_messages = read_bool("Emulator", "StatusMessages", false);
config_emulator.light_phaser = read_bool("Emulator", "LightPhaser", false);

if (config_emulator.savefiles_path.empty())
{
Expand Down Expand Up @@ -312,6 +313,7 @@ void config_write(void)
write_int("Emulator", "WindowWidth", config_emulator.window_width);
write_int("Emulator", "WindowHeight", config_emulator.window_height);
write_bool("Emulator", "StatusMessages", config_emulator.status_messages);
write_bool("Emulator", "LightPhaser", config_emulator.light_phaser);

for (int i = 0; i < config_max_recent_roms; i++)
{
Expand Down
1 change: 1 addition & 0 deletions platforms/desktop-shared/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ struct config_Emulator
int window_width = 640;
int window_height = 503;
bool status_messages = false;
bool light_phaser = false;
};

struct config_Video
Expand Down
10 changes: 10 additions & 0 deletions platforms/desktop-shared/emu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ void emu_key_released(GS_Joypads pad, GS_Keys key)
gearsystem->KeyReleased(pad, key);
}

void emu_set_phaser(int x, int y)
{
gearsystem->SetPhaser(x, y);
}

void emu_enable_phaser(bool enable)
{
gearsystem->EnablePhaser(enable);
}

void emu_pause(void)
{
gearsystem->Pause(true);
Expand Down
2 changes: 2 additions & 0 deletions platforms/desktop-shared/emu.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ EXTERN void emu_update(void);
EXTERN void emu_load_rom(const char* file_path, Cartridge::ForceConfiguration config);
EXTERN void emu_key_pressed(GS_Joypads pad, GS_Keys key);
EXTERN void emu_key_released(GS_Joypads pad, GS_Keys key);
EXTERN void emu_set_phaser(int x, int y);
EXTERN void emu_enable_phaser(bool enable);
EXTERN void emu_pause(void);
EXTERN void emu_resume(void);
EXTERN bool emu_is_paused(void);
Expand Down
19 changes: 19 additions & 0 deletions platforms/desktop-shared/gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ void gui_init(void)
emu_set_overscan(config_debug.debug ? 0 : config_video.overscan);
emu_set_hide_left_bar(config_video.hide_left_bar);
emu_disable_ym2413(config_audio.ym2413 == 1);
emu_enable_phaser(config_emulator.light_phaser);
}

void gui_destroy(void)
Expand Down Expand Up @@ -927,6 +928,13 @@ static void main_menu(void)
ImGui::EndMenu();
}

ImGui::Separator();

if (ImGui::MenuItem("Enable Light Phaser", "", &config_emulator.light_phaser))
{
emu_enable_phaser(config_emulator.light_phaser);
}

ImGui::EndMenu();
}

Expand Down Expand Up @@ -1248,6 +1256,17 @@ static void main_window(void)
float tex_h = (float)runtime.screen_width / (float)(SYSTEM_TEXTURE_WIDTH);
float tex_v = (float)runtime.screen_height / (float)(SYSTEM_TEXTURE_HEIGHT);

if (config_emulator.light_phaser)
{
ImVec2 p = ImGui::GetCursorScreenPos();
ImGuiIO& io = ImGui::GetIO();
float mouse_x = (io.MousePos.x - p.x) / scale_multiplier;
float mouse_y = (io.MousePos.y - p.y) / scale_multiplier;
mouse_x *= (float)runtime.screen_width / (float)w_corrected;
mouse_y *= (float)runtime.screen_height / (float)h_corrected;
emu_set_phaser((int)mouse_x, (int)mouse_y);
}

ImGui::Image((ImTextureID)(intptr_t)renderer_emu_texture, ImVec2((float)main_window_width, (float)main_window_height), ImVec2(0, 0), ImVec2(tex_h, tex_v));

if (config_video.fps)
Expand Down
14 changes: 11 additions & 3 deletions src/GearsystemCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ void GearsystemCore::Init(GS_Color_Format pixelFormat)
m_pCartridge = new Cartridge();
m_pProcessor = new Processor(m_pMemory);
m_pVideo = new Video(m_pMemory, m_pProcessor, m_pCartridge);
m_pInput = new Input(m_pProcessor);
m_pInput = new Input(m_pProcessor, m_pVideo);
m_pAudio = new Audio(m_pCartridge);
m_pSmsIOPorts = new SmsIOPorts(m_pAudio, m_pVideo, m_pInput, m_pCartridge, m_pMemory, m_pProcessor);
m_pGameGearIOPorts = new GameGearIOPorts(m_pAudio, m_pVideo, m_pInput, m_pCartridge, m_pMemory);
Expand Down Expand Up @@ -154,8 +154,6 @@ bool GearsystemCore::RunToVBlank(u8* pFrameBuffer, s16* pSampleBuffer, int* pSam
#endif
vblank = m_pVideo->Tick(clockCycles);
m_pAudio->Tick(clockCycles);
m_pInput->Tick(clockCycles);

totalClocks += clockCycles;

#ifndef GEARSYSTEM_DISABLE_DISASSEMBLER
Expand Down Expand Up @@ -353,6 +351,16 @@ void GearsystemCore::KeyReleased(GS_Joypads joypad, GS_Keys key)
m_pInput->KeyReleased(joypad, key);
}

void GearsystemCore::SetPhaser(int x, int y)
{
m_pInput->SetPhaser(x, y);
}

void GearsystemCore::EnablePhaser(bool enable)
{
m_pInput->EnablePhaser(enable);
}

void GearsystemCore::Pause(bool paused)
{
if (paused)
Expand Down
2 changes: 2 additions & 0 deletions src/GearsystemCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class GearsystemCore
bool GetRuntimeInfo(GS_RuntimeInfo& runtime_info);
void KeyPressed(GS_Joypads joypad, GS_Keys key);
void KeyReleased(GS_Joypads joypad, GS_Keys key);
void SetPhaser(int x, int y);
void EnablePhaser(bool enable);
void Pause(bool paused);
bool IsPaused();
void ResetROM(Cartridge::ForceConfiguration* config = NULL);
Expand Down
106 changes: 67 additions & 39 deletions src/Input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,19 @@
#include "Input.h"
#include "Memory.h"
#include "Processor.h"
#include "Video.h"

Input::Input(Processor* pProcessor)
Input::Input(Processor* pProcessor, Video* pVideo)
{
m_pProccesor = pProcessor;
m_pVideo = pVideo;
m_bGameGear = false;
m_Joypad1 = 0;
m_Joypad2 = 0;
m_IOPortDC = 0;
m_IOPortDD = 0;
m_IOPort00 = 0;
m_iInputCycles = 0;
m_bGameGear = false;
m_GlassesRegistry = 0;
m_bPhaser = false;
m_Phaser.x = 0;
m_Phaser.y = 0;
}

void Input::Init()
Expand All @@ -43,22 +45,9 @@ void Input::Reset(bool bGameGear)
m_bGameGear = bGameGear;
m_Joypad1 = 0xFF;
m_Joypad2 = 0xFF;
m_IOPortDC = 0xFF;
m_IOPortDD = 0xFF;
m_IOPort00 = 0xFF;
m_GlassesRegistry = 0;
m_iInputCycles = 0;
}

void Input::Tick(unsigned int clockCycles)
{
m_iInputCycles += clockCycles;

if (m_iInputCycles >= 10000)
{
m_iInputCycles -= 10000;
Update();
}
m_Phaser.x = 0;
m_Phaser.y = 0;
}

void Input::KeyPressed(GS_Joypads joypad, GS_Keys key)
Expand All @@ -71,6 +60,11 @@ void Input::KeyPressed(GS_Joypads joypad, GS_Keys key)
}
else
m_Joypad2 = UnsetBit(m_Joypad2, key);

if (!m_bGameGear && m_bPhaser && (key == Key_1))
{
m_pVideo->SetPhaserCoordinates(m_Phaser.x, m_Phaser.y);
}
}

void Input::KeyReleased(GS_Joypads joypad, GS_Keys key)
Expand All @@ -81,19 +75,62 @@ void Input::KeyReleased(GS_Joypads joypad, GS_Keys key)
m_Joypad2 = SetBit(m_Joypad2, key);
}

void Input::EnablePhaser(bool enable)
{
Debug("Light Phaser %s", enable ? "enabled" : "disabled");
m_bPhaser = enable;
}

void Input::SetPhaser(int x, int y)
{
m_Phaser.x = x;
m_Phaser.y = y;
}

bool Input::IsPhaserEnabled()
{
return m_bPhaser;
}

u8 Input::GetPortDC()
{
return m_IOPortDC;
if (!m_bGameGear && m_bPhaser)
{
return IsSetBit(m_Joypad1, Key_1) ? 0xFF : 0xEF;
}
else
{
return (m_Joypad1 & 0x3F) + ((m_Joypad2 << 6) & 0xC0);
}
}

u8 Input::GetPortDD()
{
return m_IOPortDD;
if (!m_bGameGear && m_bPhaser)
{
u8 dd = ((m_Joypad2 >> 2) & 0x0F) | 0xF0;

if (m_pVideo->IsPhaserDetected())
dd = UnsetBit(dd, 6);

return dd;
}
else
{
return ((m_Joypad2 >> 2) & 0x0F) | 0xF0;
}
}

u8 Input::GetPort00()
{
return m_IOPort00;
if (m_bPhaser)
{
return 0x00;
}
else
{
return (IsSetBit(m_Joypad1, Key_Start) ? 0x80 : 0) & 0x80;
}
}

u8 Input::GetGlassesRegistry()
Expand All @@ -106,23 +143,15 @@ void Input::SetGlassesRegistry(u8 value)
m_GlassesRegistry = value;
}

void Input::Update()
{
m_IOPortDC = (m_Joypad1 & 0x3F) + ((m_Joypad2 << 6) & 0xC0);
m_IOPortDD = ((m_Joypad2 >> 2) & 0x0F) | 0xF0;
m_IOPort00 = (IsSetBit(m_Joypad1, Key_Start) ? 0x80 : 0) & 0x80;
}

void Input::SaveState(std::ostream& stream)
{
using namespace std;

stream.write(reinterpret_cast<const char*> (&m_Joypad1), sizeof(m_Joypad1));
stream.write(reinterpret_cast<const char*> (&m_Joypad2), sizeof(m_Joypad2));
stream.write(reinterpret_cast<const char*> (&m_IOPortDC), sizeof(m_IOPortDC));
stream.write(reinterpret_cast<const char*> (&m_IOPortDD), sizeof(m_IOPortDD));
stream.write(reinterpret_cast<const char*> (&m_IOPort00), sizeof(m_IOPort00));
stream.write(reinterpret_cast<const char*> (&m_iInputCycles), sizeof(m_iInputCycles));
stream.write(reinterpret_cast<const char*> (&m_GlassesRegistry), sizeof(m_GlassesRegistry));
stream.write(reinterpret_cast<const char*> (&m_bPhaser), sizeof(m_bPhaser));
stream.write(reinterpret_cast<const char*> (&m_Phaser), sizeof(m_Phaser));
}

void Input::LoadState(std::istream& stream)
Expand All @@ -131,8 +160,7 @@ void Input::LoadState(std::istream& stream)

stream.read(reinterpret_cast<char*> (&m_Joypad1), sizeof(m_Joypad1));
stream.read(reinterpret_cast<char*> (&m_Joypad2), sizeof(m_Joypad2));
stream.read(reinterpret_cast<char*> (&m_IOPortDC), sizeof(m_IOPortDC));
stream.read(reinterpret_cast<char*> (&m_IOPortDD), sizeof(m_IOPortDD));
stream.read(reinterpret_cast<char*> (&m_IOPort00), sizeof(m_IOPort00));
stream.read(reinterpret_cast<char*> (&m_iInputCycles), sizeof(m_iInputCycles));
stream.read(reinterpret_cast<char*> (&m_GlassesRegistry), sizeof(m_GlassesRegistry));
stream.read(reinterpret_cast<char*> (&m_bPhaser), sizeof(m_bPhaser));
stream.read(reinterpret_cast<char*> (&m_Phaser), sizeof(m_Phaser));
}
24 changes: 15 additions & 9 deletions src/Input.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,26 @@

class Memory;
class Processor;
class Video;

class Input
{
public:
Input(Processor* pProcessor);
struct stPhaser
{
int x;
int y;
};

public:
Input(Processor* pProcessor, Video* pVideo);
void Init();
void Reset(bool bGameGear);
void Tick(unsigned int clockCycles);
void KeyPressed(GS_Joypads joypad, GS_Keys key);
void KeyReleased(GS_Joypads joypad, GS_Keys key);
void EnablePhaser(bool enable);
void SetPhaser(int x, int y);
bool IsPhaserEnabled();
u8 GetPortDC();
u8 GetPortDD();
u8 GetPort00();
Expand All @@ -42,19 +52,15 @@ class Input
void SaveState(std::ostream& stream);
void LoadState(std::istream& stream);

private:
void Update();

private:
Processor* m_pProccesor;
Video* m_pVideo;
u8 m_Joypad1;
u8 m_Joypad2;
u8 m_IOPortDC;
u8 m_IOPortDD;
u8 m_IOPort00;
u8 m_GlassesRegistry;
int m_iInputCycles;
bool m_bGameGear;
bool m_bPhaser;
stPhaser m_Phaser;
};

#endif /* INPUT_H */
Loading

0 comments on commit c373f96

Please sign in to comment.