Skip to content

Commit

Permalink
Add support for SAC Spinners, Wheel Controller and Roller Controller. F…
Browse files Browse the repository at this point in the history
…ixes #38
  • Loading branch information
drhelius committed Dec 26, 2023
1 parent f64edcf commit a7c272e
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 51 deletions.
57 changes: 57 additions & 0 deletions platforms/desktop-shared/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,63 @@ static void sdl_events_emu(const SDL_Event* event)
{
switch(event->type)
{
case (SDL_MOUSEMOTION):
{
if (config_emulator.spinner > 0)
{
int sen = config_emulator.spinner_sensitivity - 1;
if (sen < 0)
sen = 0;
float senf = (float)(sen / 2.0f) + 1.0f;
float relx = (float)(event->motion.xrel) * senf;

// roller controller
switch (config_emulator.spinner)
{
// SAC
case (1):
{
emu_spinner1(relx);
break;
}
// Wheel
case (2):
{
emu_spinner1(relx);
break;
}
// Roller
case (3):
{
float rely = (float)(event->motion.yrel) * senf;
emu_spinner1(relx);
emu_spinner2(rely);
break;
}
default:
break;
}
}

break;
}
case (SDL_MOUSEWHEEL):
{
// SAC
if (config_emulator.spinner == 1)
{
int sen = (config_emulator.spinner_sensitivity - 1) * 20;
if (sen < 0)
sen = 0;

float senf = (float)(sen / 2.0f) + 1.0f;
float rely = (float)(event->wheel.y) * senf;

emu_spinner2(rely);
}

break;
}
case (SDL_DROPFILE):
{
char* dropped_filedir = event->drop.file;
Expand Down
6 changes: 5 additions & 1 deletion platforms/desktop-shared/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ void config_read(void)
config_emulator.last_open_path = read_string("Emulator", "LastOpenPath");
config_emulator.window_width = read_int("Emulator", "WindowWidth", 770);
config_emulator.window_height = read_int("Emulator", "WindowHeight", 600);
config_emulator.spinner = read_int("Emulator", "Spinner", 0);
config_emulator.spinner_sensitivity = read_int("Emulator", "SpinnerSensitivity", 4);

if (config_emulator.savefiles_path.empty())
{
Expand Down Expand Up @@ -338,7 +340,9 @@ void config_write(void)
write_string("Emulator", "LastOpenPath", config_emulator.last_open_path);
write_int("Emulator", "WindowWidth", config_emulator.window_width);
write_int("Emulator", "WindowHeight", config_emulator.window_height);

write_int("Emulator", "Spinner", config_emulator.spinner);
write_int("Emulator", "SpinnerSensitivity", config_emulator.spinner_sensitivity);

for (int i = 0; i < config_max_recent_roms; i++)
{
std::string item = "RecentROM" + std::to_string(i);
Expand Down
2 changes: 2 additions & 0 deletions platforms/desktop-shared/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ struct config_Emulator
std::string last_open_path;
int window_width = 770;
int window_height = 600;
int spinner = 0;
int spinner_sensitivity = 0;
};

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 @@ -142,6 +142,16 @@ void emu_key_released(GC_Controllers controller, GC_Keys key)
gearcoleco->KeyReleased(controller, key);
}

void emu_spinner1(int movement)
{
gearcoleco->Spinner1(movement);
}

void emu_spinner2(int movement)
{
gearcoleco->Spinner2(movement);
}

void emu_pause(void)
{
gearcoleco->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(GC_Controllers controller, GC_Keys key);
EXTERN void emu_key_released(GC_Controllers controller, GC_Keys key);
EXTERN void emu_spinner1(int movement);
EXTERN void emu_spinner2(int movement);
EXTERN void emu_pause(void);
EXTERN void emu_resume(void);
EXTERN bool emu_is_paused(void);
Expand Down
16 changes: 13 additions & 3 deletions platforms/desktop-shared/gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ static void main_menu(void)
{
gui_in_use = true;

if (ImGui::BeginMenu("Keyboard Configuration"))
if (ImGui::BeginMenu("Keyboard"))
{
if (ImGui::BeginMenu("Player 1"))
{
Expand Down Expand Up @@ -576,8 +576,6 @@ static void main_menu(void)
ImGui::EndMenu();
}

ImGui::Separator();

if (ImGui::BeginMenu("Gamepads"))
{
if (ImGui::BeginMenu("Player 1"))
Expand Down Expand Up @@ -661,6 +659,18 @@ static void main_menu(void)
ImGui::EndMenu();
}

if (ImGui::BeginMenu("Spinners"))
{
ImGui::Combo("##spinner", &config_emulator.spinner, "Disabled\0Super Action Controller\0Steering Wheel\0Roller Controller\0\0", 4);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
{
ImGui::SetTooltip("SAC Spinner for P1 is controlled with mouse movement.\nSAC Spinner for P2 is controlled with mouse wheel.\nSteering Wheel is controlled with mouse movement.\nRoller Controller is controlled with mouse movement.");
}
ImGui::SliderInt("##spinner_sensitivity", &config_emulator.spinner_sensitivity, 1, 10, "Sensitivity = %d");

ImGui::EndMenu();
}

ImGui::EndMenu();
}

Expand Down
13 changes: 11 additions & 2 deletions src/GearcolecoCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void GearcolecoCore::Init(GC_Color_Format pixelFormat)
m_pProcessor = new Processor(m_pMemory);
m_pAudio = new Audio();
m_pVideo = new Video(m_pMemory, m_pProcessor);
m_pInput = new Input();
m_pInput = new Input(m_pProcessor);
m_pColecoVisionIOPorts = new ColecoVisionIOPorts(m_pAudio, m_pVideo, m_pInput, m_pCartridge, m_pMemory, m_pProcessor);

m_pMemory->Init();
Expand Down Expand Up @@ -93,7 +93,6 @@ bool GearcolecoCore::RunToVBlank(u8* pFrameBuffer, s16* pSampleBuffer, int* pSam
#endif
vblank = m_pVideo->Tick(clockCycles);
m_pAudio->Tick(clockCycles);
m_pInput->Tick(clockCycles);

totalClocks += clockCycles;

Expand Down Expand Up @@ -251,6 +250,16 @@ void GearcolecoCore::KeyReleased(GC_Controllers controller, GC_Keys key)
m_pInput->KeyReleased(controller, key);
}

void GearcolecoCore::Spinner1(int movement)
{
m_pInput->Spinner1(movement);
}

void GearcolecoCore::Spinner2(int movement)
{
m_pInput->Spinner2(movement);
}

void GearcolecoCore::Pause(bool paused)
{
if (paused)
Expand Down
2 changes: 2 additions & 0 deletions src/GearcolecoCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class GearcolecoCore
bool GetRuntimeInfo(GC_RuntimeInfo& runtime_info);
void KeyPressed(GC_Controllers controller, GC_Keys key);
void KeyReleased(GC_Controllers controller, GC_Keys key);
void Spinner1(int movement);
void Spinner2(int movement);
void Pause(bool paused);
bool IsPaused();
void ResetROM(Cartridge::ForceConfiguration* config = NULL);
Expand Down
70 changes: 34 additions & 36 deletions src/Input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
*/

#include "Input.h"
#include "Memory.h"
#include "Processor.h"

Input::Input()
Input::Input(Processor* pProcessor)
{
Reset();
m_pProcessor = pProcessor;
}

void Input::Init()
Expand All @@ -32,24 +32,10 @@ void Input::Init()

void Input::Reset()
{
m_iInputCycles = 0;
m_Segment = SegmentKeypadRightButtons;
m_Gamepad[0] = m_Gamepad[1] = 0xFF;
m_Keypad[0] = m_Keypad[1] = 0x0F;
m_InputState[0][0] = m_InputState[0][1] = 0xFF;
m_InputState[1][0] = m_InputState[1][1] = 0xFF;
}

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

// Joypad Poll Speed
if (m_iInputCycles >= 10000)
{
m_iInputCycles -= 10000;
Update();
}
m_Keypad[0] = m_Keypad[1] = 0xFF;
m_iSpinnerRel[0] = m_iSpinnerRel[1] = 0;
}

void Input::SetInputSegment(InputSegments segment)
Expand All @@ -59,16 +45,33 @@ void Input::SetInputSegment(InputSegments segment)

u8 Input::ReadInput(u8 port)
{
u8 controller = (port & 0x02) >> 1;
u8 c = (port & 0x02) >> 1;
u8 ret = 0xFF;

int rel = m_iSpinnerRel[c] / 4;
m_iSpinnerRel[c] -= rel;

if (m_Segment == SegmentKeypadRightButtons)
{
return m_InputState[controller][0];
ret = (m_Keypad[c] & 0x0F) | (IsSetBit(m_Gamepad[c], 5) ? 0x70 : 0x30);
}
else
{
return m_InputState[controller][1];
ret = (m_Gamepad[c] & 0x0F) | (IsSetBit(m_Gamepad[c], 4) ? 0x70 : 0x30);

if (rel > 0)
{
ret &= c ? 0xEF : 0xCF;
m_pProcessor->RequestINT(true);
}
else if (rel < 0)
{
ret &= c ? 0xCF : 0xEF;
m_pProcessor->RequestINT(true);
}
}

return ret;
}

void Input::KeyPressed(GC_Controllers controller, GC_Keys key)
Expand All @@ -95,33 +98,28 @@ void Input::KeyReleased(GC_Controllers controller, GC_Keys key)
}
}

void Input::Update()
void Input::Spinner1(int movement)
{
for (int c = 0; c < 2; c++)
{
m_InputState[c][0] = (m_Keypad[c] & 0x0F) | (IsSetBit(m_Gamepad[c], 5) ? 0x70 : 0x30);
m_InputState[c][1] = (m_Gamepad[c] & 0x0F) | (IsSetBit(m_Gamepad[c], 4) ? 0x70 : 0x30);
}
m_iSpinnerRel[0] = movement;
}

void Input::Spinner2(int movement)
{
m_iSpinnerRel[1] = movement;
}

void Input::SaveState(std::ostream& stream)
{
u8 dummy = 0xFF;
stream.write(reinterpret_cast<const char*> (m_Gamepad), sizeof(m_Gamepad));
stream.write(reinterpret_cast<const char*> (m_Keypad), sizeof(m_Keypad));
stream.write(reinterpret_cast<const char*> (m_InputState), sizeof(m_InputState));
stream.write(reinterpret_cast<const char*> (&dummy), sizeof(dummy));
stream.write(reinterpret_cast<const char*> (&m_Segment), sizeof(m_Segment));
stream.write(reinterpret_cast<const char*> (&m_iInputCycles), sizeof(m_iInputCycles));
stream.write(reinterpret_cast<const char*> (&m_iSpinnerRel), sizeof(m_iSpinnerRel));
}

void Input::LoadState(std::istream& stream)
{
u8 dummy = 0xFF;
stream.read(reinterpret_cast<char*> (m_Gamepad), sizeof(m_Gamepad));
stream.read(reinterpret_cast<char*> (m_Keypad), sizeof(m_Keypad));
stream.read(reinterpret_cast<char*> (m_InputState), sizeof(m_InputState));
stream.read(reinterpret_cast<char*> (&dummy), sizeof(dummy));
stream.read(reinterpret_cast<char*> (&m_Segment), sizeof(m_Segment));
stream.read(reinterpret_cast<char*> (&m_iInputCycles), sizeof(m_iInputCycles));
stream.read(reinterpret_cast<char*> (&m_iSpinnerRel), sizeof(m_iSpinnerRel));
}
14 changes: 6 additions & 8 deletions src/Input.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#include "definitions.h"

class Memory;
class Processor;

class Input
{
Expand All @@ -34,26 +34,24 @@ class Input
};

public:
Input();
Input(Processor* pProcessor);
void Init();
void Reset();
void Tick(unsigned int clockCycles);
void KeyPressed(GC_Controllers controller, GC_Keys key);
void KeyReleased(GC_Controllers controller, GC_Keys key);
void Spinner1(int movement);
void Spinner2(int movement);
void SaveState(std::ostream& stream);
void LoadState(std::istream& stream);
void SetInputSegment(InputSegments segment);
u8 ReadInput(u8 port);

private:
void Update();

private:
Processor* m_pProcessor;
u8 m_Gamepad[2];
u8 m_Keypad[2];
int m_iInputCycles;
InputSegments m_Segment;
u8 m_InputState[2][2];
int m_iSpinnerRel[2];
};

#endif /* INPUT_H */
1 change: 1 addition & 0 deletions src/Processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ unsigned int Processor::RunFor(unsigned int tstates)
else if (m_bIFF1 && m_bINTRequested && !m_bAfterEI)
{
LeaveHalt();
m_bINTRequested = false;
m_bIFF1 = false;
m_bIFF2 = false;
StackPush(&PC);
Expand Down
2 changes: 1 addition & 1 deletion src/definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ typedef void (*RamChangedCallback) (void);

#define GC_AUDIO_BUFFER_SIZE 8192

#define GC_SAVESTATE_MAGIC 0x83190128
#define GC_SAVESTATE_MAGIC 0x09200902

struct GC_Color
{
Expand Down

0 comments on commit a7c272e

Please sign in to comment.