ImGui: fix event handling.
1) always pass events to ImGui 2) only pass keyboards to AW when ImGui says so
This commit is contained in:
parent
fdfbb795d1
commit
c81b4ab1bf
9 changed files with 384 additions and 393 deletions
|
@ -4,7 +4,6 @@ add_executable(sa2)
|
|||
|
||||
set(SOURCE_FILES
|
||||
main.cpp
|
||||
emulator.cpp
|
||||
gamepad.cpp
|
||||
sdirectsound.cpp
|
||||
utils.cpp
|
||||
|
@ -13,7 +12,6 @@ set(SOURCE_FILES
|
|||
)
|
||||
|
||||
set(HEADER_FILES
|
||||
emulator.h
|
||||
gamepad.h
|
||||
sdirectsound.h
|
||||
utils.h
|
||||
|
|
|
@ -1,346 +0,0 @@
|
|||
#include "StdAfx.h"
|
||||
|
||||
#include "frontends/sdl/emulator.h"
|
||||
#include "frontends/sdl/sdirectsound.h"
|
||||
#include "frontends/sdl/utils.h"
|
||||
#include "frontends/sdl/sdlframe.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "linux/paddle.h"
|
||||
#include "linux/keyboard.h"
|
||||
|
||||
#include "Common.h"
|
||||
#include "Interface.h"
|
||||
#include "CardManager.h"
|
||||
#include "Core.h"
|
||||
#include "Disk.h"
|
||||
#include "CPU.h"
|
||||
#include "Video.h"
|
||||
#include "NTSC.h"
|
||||
#include "Mockingboard.h"
|
||||
#include "Speaker.h"
|
||||
#include "Utilities.h"
|
||||
#include "SaveState.h"
|
||||
#include "SoundCore.h"
|
||||
|
||||
// #define KEY_LOGGING_VERBOSE
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void processAppleKey(const SDL_KeyboardEvent & key, const bool forceCapsLock)
|
||||
{
|
||||
// using keycode (or scan code) one takes a physical view of the keyboard
|
||||
// ignoring non US layouts
|
||||
// SHIFT-3 on a A2 keyboard in # while on my UK keyboard is £?
|
||||
// so for now all ASCII keys are handled as text below
|
||||
// but this makes it impossible to detect CTRL-ASCII... more to follow
|
||||
BYTE ch = 0;
|
||||
|
||||
switch (key.keysym.sym)
|
||||
{
|
||||
case SDLK_RETURN:
|
||||
case SDLK_KP_ENTER:
|
||||
{
|
||||
ch = 0x0d;
|
||||
break;
|
||||
}
|
||||
case SDLK_BACKSPACE: // same as AppleWin
|
||||
case SDLK_LEFT:
|
||||
{
|
||||
ch = 0x08;
|
||||
break;
|
||||
}
|
||||
case SDLK_RIGHT:
|
||||
{
|
||||
ch = 0x15;
|
||||
break;
|
||||
}
|
||||
case SDLK_UP:
|
||||
{
|
||||
ch = 0x0b;
|
||||
break;
|
||||
}
|
||||
case SDLK_DOWN:
|
||||
{
|
||||
ch = 0x0a;
|
||||
break;
|
||||
}
|
||||
case SDLK_DELETE:
|
||||
{
|
||||
ch = 0x7f;
|
||||
break;
|
||||
}
|
||||
case SDLK_ESCAPE:
|
||||
{
|
||||
ch = 0x1b;
|
||||
break;
|
||||
}
|
||||
case SDLK_TAB:
|
||||
{
|
||||
ch = 0x09;
|
||||
break;
|
||||
}
|
||||
case SDLK_a ... SDLK_z:
|
||||
{
|
||||
// same logic as AW
|
||||
// CAPS is forced when the emulator starts
|
||||
// until is used the first time
|
||||
const bool capsLock = forceCapsLock || (SDL_GetModState() & KMOD_CAPS);
|
||||
const bool upper = capsLock || (key.keysym.mod & KMOD_SHIFT);
|
||||
|
||||
ch = (key.keysym.sym - SDLK_a) + 0x01;
|
||||
if (key.keysym.mod & KMOD_CTRL)
|
||||
{
|
||||
// ok
|
||||
}
|
||||
else if (upper)
|
||||
{
|
||||
ch += 0x40; // upper case
|
||||
}
|
||||
else
|
||||
{
|
||||
ch += 0x60; // lower case
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch)
|
||||
{
|
||||
addKeyToBuffer(ch);
|
||||
std::cerr << "SDL KeyboardEvent: " << std::hex << (int)ch << std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Emulator::Emulator(
|
||||
const std::shared_ptr<SDLFrame> & frame,
|
||||
const bool fixedSpeed
|
||||
)
|
||||
: myFrame(frame)
|
||||
, myForceCapsLock(true)
|
||||
, myMultiplier(1)
|
||||
, myFullscreen(false)
|
||||
, mySpeed(fixedSpeed)
|
||||
{
|
||||
}
|
||||
|
||||
void Emulator::execute(const size_t next)
|
||||
{
|
||||
if (g_nAppMode == MODE_RUNNING)
|
||||
{
|
||||
const size_t cyclesToExecute = mySpeed.getCyclesTillNext(next * 1000);
|
||||
|
||||
const bool bVideoUpdate = true;
|
||||
const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame();
|
||||
|
||||
const DWORD executedCycles = CpuExecute(cyclesToExecute, bVideoUpdate);
|
||||
|
||||
g_dwCyclesThisFrame = (g_dwCyclesThisFrame + executedCycles) % dwClksPerFrame;
|
||||
GetCardMgr().GetDisk2CardMgr().UpdateDriveState(executedCycles);
|
||||
MB_PeriodicUpdate(executedCycles);
|
||||
SpkrUpdate(executedCycles);
|
||||
}
|
||||
}
|
||||
|
||||
void Emulator::processEvents(bool & quit)
|
||||
{
|
||||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e) != 0)
|
||||
{
|
||||
switch (e.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
{
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
processKeyDown(e.key, quit);
|
||||
break;
|
||||
}
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
processKeyUp(e.key);
|
||||
break;
|
||||
}
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
processText(e.text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Emulator::processKeyDown(const SDL_KeyboardEvent & key, bool & quit)
|
||||
{
|
||||
// scancode vs keycode
|
||||
// scancode is relative to the position on the keyboard
|
||||
// keycode is what the os maps it to
|
||||
// if the user has decided to change the layout, we just go with it and use the keycode
|
||||
if (!key.repeat)
|
||||
{
|
||||
const std::shared_ptr<SDL_Window> & window = myFrame->GetWindow();
|
||||
switch (key.keysym.sym)
|
||||
{
|
||||
case SDLK_F12:
|
||||
{
|
||||
Snapshot_LoadState();
|
||||
mySpeed.reset();
|
||||
break;
|
||||
}
|
||||
case SDLK_F11:
|
||||
{
|
||||
const std::string & pathname = Snapshot_GetPathname();
|
||||
const std::string message = "Do you want to save the state to " + pathname + "?";
|
||||
SoundCore_SetFade(FADE_OUT);
|
||||
if (show_yes_no_dialog(window, "Save state", message))
|
||||
{
|
||||
Snapshot_SaveState();
|
||||
}
|
||||
SoundCore_SetFade(FADE_IN);
|
||||
mySpeed.reset();
|
||||
break;
|
||||
}
|
||||
case SDLK_F9:
|
||||
{
|
||||
myFrame->CycleVideoType();
|
||||
break;
|
||||
}
|
||||
case SDLK_F6:
|
||||
{
|
||||
if ((key.keysym.mod & KMOD_CTRL) && (key.keysym.mod & KMOD_SHIFT))
|
||||
{
|
||||
myFrame->Cycle50ScanLines();
|
||||
}
|
||||
else if (key.keysym.mod & KMOD_CTRL)
|
||||
{
|
||||
Video & video = GetVideo();
|
||||
myMultiplier = myMultiplier == 1 ? 2 : 1;
|
||||
const int sw = video.GetFrameBufferBorderlessWidth();
|
||||
const int sh = video.GetFrameBufferBorderlessHeight();
|
||||
SDL_SetWindowSize(window.get(), sw * myMultiplier, sh * myMultiplier);
|
||||
}
|
||||
else if (!(key.keysym.mod & KMOD_SHIFT))
|
||||
{
|
||||
myFullscreen = !myFullscreen;
|
||||
SDL_SetWindowFullscreen(window.get(), myFullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_F5:
|
||||
{
|
||||
CardManager & cardManager = GetCardMgr();
|
||||
if (cardManager.QuerySlot(SLOT6) == CT_Disk2)
|
||||
{
|
||||
dynamic_cast<Disk2InterfaceCard*>(cardManager.GetObj(SLOT6))->DriveSwap();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_F2:
|
||||
{
|
||||
if (key.keysym.mod & KMOD_CTRL)
|
||||
{
|
||||
CtrlReset();
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetMachineState();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_F1:
|
||||
{
|
||||
SDirectSound::printInfo();
|
||||
break;
|
||||
}
|
||||
case SDLK_LALT:
|
||||
{
|
||||
Paddle::setButtonPressed(Paddle::ourOpenApple);
|
||||
break;
|
||||
}
|
||||
case SDLK_RALT:
|
||||
{
|
||||
Paddle::setButtonPressed(Paddle::ourSolidApple);
|
||||
break;
|
||||
}
|
||||
case SDLK_PAUSE:
|
||||
{
|
||||
switch (g_nAppMode)
|
||||
{
|
||||
case MODE_RUNNING:
|
||||
g_nAppMode = MODE_PAUSED;
|
||||
SoundCore_SetFade(FADE_OUT);
|
||||
break;
|
||||
case MODE_PAUSED:
|
||||
g_nAppMode = MODE_RUNNING;
|
||||
SoundCore_SetFade(FADE_IN);
|
||||
mySpeed.reset();
|
||||
break;
|
||||
}
|
||||
GetFrame().FrameRefreshStatus(DRAW_TITLE);
|
||||
break;
|
||||
}
|
||||
case SDLK_CAPSLOCK:
|
||||
{
|
||||
myForceCapsLock = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processAppleKey(key, myForceCapsLock);
|
||||
|
||||
#ifdef KEY_LOGGING_VERBOSE
|
||||
std::cerr << "KEY DOWN: " << key.keysym.scancode << "," << key.keysym.sym << "," << key.keysym.mod << "," << bool(key.repeat) << std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void Emulator::processKeyUp(const SDL_KeyboardEvent & key)
|
||||
{
|
||||
switch (key.keysym.sym)
|
||||
{
|
||||
case SDLK_LALT:
|
||||
{
|
||||
Paddle::setButtonReleased(Paddle::ourOpenApple);
|
||||
break;
|
||||
}
|
||||
case SDLK_RALT:
|
||||
{
|
||||
Paddle::setButtonReleased(Paddle::ourSolidApple);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KEY_LOGGING_VERBOSE
|
||||
std::cerr << "KEY UP: " << key.keysym.scancode << "," << key.keysym.sym << "," << key.keysym.mod << "," << bool(key.repeat) << std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void Emulator::processText(const SDL_TextInputEvent & text)
|
||||
{
|
||||
if (strlen(text.text) == 1)
|
||||
{
|
||||
const char key = text.text[0];
|
||||
switch (key) {
|
||||
case 0x20 ... 0x40:
|
||||
case 0x5b ... 0x60:
|
||||
case 0x7b ... 0x7e:
|
||||
{
|
||||
// not the letters
|
||||
// this is very simple, but one cannot handle CRTL-key combination.
|
||||
addKeyToBuffer(key);
|
||||
std::cerr << "SDL TextInputEvent: " << std::hex << (int)key << std::dec << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <SDL.h>
|
||||
#include <memory>
|
||||
|
||||
#include "frontends/common2/speed.h"
|
||||
|
||||
class SDLFrame;
|
||||
|
||||
class Emulator
|
||||
{
|
||||
public:
|
||||
Emulator(
|
||||
const std::shared_ptr<SDLFrame> & frame,
|
||||
const bool fixedSpeed
|
||||
);
|
||||
|
||||
void execute(const size_t milliseconds);
|
||||
|
||||
void processEvents(bool & quit);
|
||||
|
||||
private:
|
||||
void processKeyDown(const SDL_KeyboardEvent & key, bool & quit);
|
||||
void processKeyUp(const SDL_KeyboardEvent & key);
|
||||
void processText(const SDL_TextInputEvent & text);
|
||||
|
||||
const std::shared_ptr<SDLFrame> myFrame;
|
||||
|
||||
bool myForceCapsLock;
|
||||
int myMultiplier;
|
||||
bool myFullscreen;
|
||||
|
||||
Speed mySpeed;
|
||||
};
|
|
@ -36,6 +36,7 @@ namespace
|
|||
}
|
||||
|
||||
SDLImGuiFrame::SDLImGuiFrame(const EmulatorOptions & options)
|
||||
: SDLFrame(options)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
|
@ -292,3 +293,24 @@ void SDLImGuiFrame::RenderPresent()
|
|||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
SDL_GL_SwapWindow(myWindow.get());
|
||||
}
|
||||
|
||||
void SDLImGuiFrame::ProcessSingleEvent(const SDL_Event & event, bool & quit)
|
||||
{
|
||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.WantCaptureKeyboard)
|
||||
{
|
||||
return; // do not pass on
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDLFrame::ProcessSingleEvent(event, quit);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@ public:
|
|||
void UpdateTexture() override;
|
||||
void RenderPresent() override;
|
||||
|
||||
protected:
|
||||
|
||||
void ProcessSingleEvent(const SDL_Event & event, bool & quit) override;
|
||||
|
||||
private:
|
||||
|
||||
void ClearBackground();
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "frontends/common2/utils.h"
|
||||
#include "frontends/common2/programoptions.h"
|
||||
#include "frontends/common2/timer.h"
|
||||
#include "frontends/sdl/emulator.h"
|
||||
#include "frontends/sdl/gamepad.h"
|
||||
#include "frontends/sdl/sdirectsound.h"
|
||||
#include "frontends/sdl/utils.h"
|
||||
|
@ -24,12 +23,15 @@
|
|||
#include "frontends/sdl/imgui/sdlimguiframe.h"
|
||||
#endif
|
||||
|
||||
#include "CardManager.h"
|
||||
#include "Core.h"
|
||||
#include "Log.h"
|
||||
#include "CPU.h"
|
||||
#include "NTSC.h"
|
||||
#include "SaveState.h"
|
||||
#include "Interface.h"
|
||||
#include "Mockingboard.h"
|
||||
#include "Speaker.h"
|
||||
|
||||
// comment out to test / debug init / shutdown only
|
||||
#define EMULATOR_RUN
|
||||
|
@ -51,9 +53,27 @@ namespace
|
|||
return current.refresh_rate;
|
||||
}
|
||||
|
||||
void execute(Speed speed, const size_t next)
|
||||
{
|
||||
if (g_nAppMode == MODE_RUNNING)
|
||||
{
|
||||
const size_t cyclesToExecute = speed.getCyclesTillNext(next * 1000);
|
||||
|
||||
const bool bVideoUpdate = true;
|
||||
const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame();
|
||||
|
||||
const DWORD executedCycles = CpuExecute(cyclesToExecute, bVideoUpdate);
|
||||
|
||||
g_dwCyclesThisFrame = (g_dwCyclesThisFrame + executedCycles) % dwClksPerFrame;
|
||||
GetCardMgr().GetDisk2CardMgr().UpdateDriveState(executedCycles);
|
||||
MB_PeriodicUpdate(executedCycles);
|
||||
SpkrUpdate(executedCycles);
|
||||
}
|
||||
}
|
||||
|
||||
struct Data
|
||||
{
|
||||
Emulator * emulator;
|
||||
Speed * speed;
|
||||
SDL_mutex * mutex;
|
||||
Timer * timer;
|
||||
};
|
||||
|
@ -64,7 +84,7 @@ namespace
|
|||
SDL_LockMutex(data->mutex);
|
||||
|
||||
data->timer->tic();
|
||||
data->emulator->execute(interval);
|
||||
execute(*data->speed, interval);
|
||||
data->timer->toc();
|
||||
|
||||
SDL_UnlockMutex(data->mutex);
|
||||
|
@ -132,8 +152,6 @@ void run_sdl(int argc, const char * argv [])
|
|||
const int fps = getRefreshRate();
|
||||
std::cerr << "Video refresh rate: " << fps << " Hz, " << 1000.0 / fps << " ms" << std::endl;
|
||||
|
||||
Emulator emulator(frame, options.fixedSpeed);
|
||||
|
||||
#ifdef EMULATOR_RUN
|
||||
if (options.benchmark)
|
||||
{
|
||||
|
@ -169,6 +187,8 @@ void run_sdl(int argc, const char * argv [])
|
|||
const std::string globalTag = ". .";
|
||||
std::string updateTextureTimerTag, refreshScreenTimerTag, cpuTimerTag, eventTimerTag;
|
||||
|
||||
Speed speed(options.fixedSpeed);
|
||||
|
||||
if (options.multiThreaded)
|
||||
{
|
||||
refreshScreenTimerTag = "0 .";
|
||||
|
@ -187,8 +207,8 @@ void run_sdl(int argc, const char * argv [])
|
|||
|
||||
Data data;
|
||||
data.mutex = mutex.get();
|
||||
data.emulator = &emulator;
|
||||
data.timer = &cpuTimer;
|
||||
data.speed = &speed;
|
||||
|
||||
const SDL_TimerID timer = SDL_AddTimer(options.timerInterval, emulator_callback, &data);
|
||||
|
||||
|
@ -200,7 +220,7 @@ void run_sdl(int argc, const char * argv [])
|
|||
|
||||
eventTimer.tic();
|
||||
SDirectSound::writeAudio();
|
||||
emulator.processEvents(quit);
|
||||
frame->ProcessEvents(quit);
|
||||
eventTimer.toc();
|
||||
|
||||
if (options.looseMutex)
|
||||
|
@ -257,11 +277,11 @@ void run_sdl(int argc, const char * argv [])
|
|||
|
||||
eventTimer.tic();
|
||||
SDirectSound::writeAudio();
|
||||
emulator.processEvents(quit);
|
||||
frame->ProcessEvents(quit);
|
||||
eventTimer.toc();
|
||||
|
||||
cpuTimer.tic();
|
||||
emulator.execute(oneFrame);
|
||||
execute(speed, oneFrame);
|
||||
cpuTimer.toc();
|
||||
|
||||
updateTextureTimer.tic();
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <iostream>
|
||||
|
||||
SDLRendererFrame::SDLRendererFrame(const EmulatorOptions & options)
|
||||
: SDLFrame(options)
|
||||
{
|
||||
const Geometry & geometry = options.geometry;
|
||||
|
||||
|
|
|
@ -1,15 +1,122 @@
|
|||
#include "StdAfx.h"
|
||||
#include "frontends/sdl/sdlframe.h"
|
||||
#include "frontends/sdl/utils.h"
|
||||
#include "frontends/sdl/sdirectsound.h"
|
||||
#include "frontends/common2/programoptions.h"
|
||||
|
||||
#include "CardManager.h"
|
||||
#include "Core.h"
|
||||
#include "Utilities.h"
|
||||
#include "SaveState.h"
|
||||
#include "Speaker.h"
|
||||
#include "SoundCore.h"
|
||||
#include "Interface.h"
|
||||
|
||||
#include "linux/paddle.h"
|
||||
#include "linux/keyboard.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <SDL_image.h>
|
||||
|
||||
SDLFrame::SDLFrame()
|
||||
// #define KEY_LOGGING_VERBOSE
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void processAppleKey(const SDL_KeyboardEvent & key, const bool forceCapsLock)
|
||||
{
|
||||
// using keycode (or scan code) one takes a physical view of the keyboard
|
||||
// ignoring non US layouts
|
||||
// SHIFT-3 on a A2 keyboard in # while on my UK keyboard is £?
|
||||
// so for now all ASCII keys are handled as text below
|
||||
// but this makes it impossible to detect CTRL-ASCII... more to follow
|
||||
BYTE ch = 0;
|
||||
|
||||
switch (key.keysym.sym)
|
||||
{
|
||||
case SDLK_RETURN:
|
||||
case SDLK_KP_ENTER:
|
||||
{
|
||||
ch = 0x0d;
|
||||
break;
|
||||
}
|
||||
case SDLK_BACKSPACE: // same as AppleWin
|
||||
case SDLK_LEFT:
|
||||
{
|
||||
ch = 0x08;
|
||||
break;
|
||||
}
|
||||
case SDLK_RIGHT:
|
||||
{
|
||||
ch = 0x15;
|
||||
break;
|
||||
}
|
||||
case SDLK_UP:
|
||||
{
|
||||
ch = 0x0b;
|
||||
break;
|
||||
}
|
||||
case SDLK_DOWN:
|
||||
{
|
||||
ch = 0x0a;
|
||||
break;
|
||||
}
|
||||
case SDLK_DELETE:
|
||||
{
|
||||
ch = 0x7f;
|
||||
break;
|
||||
}
|
||||
case SDLK_ESCAPE:
|
||||
{
|
||||
ch = 0x1b;
|
||||
break;
|
||||
}
|
||||
case SDLK_TAB:
|
||||
{
|
||||
ch = 0x09;
|
||||
break;
|
||||
}
|
||||
case SDLK_a ... SDLK_z:
|
||||
{
|
||||
// same logic as AW
|
||||
// CAPS is forced when the emulator starts
|
||||
// until is used the first time
|
||||
const bool capsLock = forceCapsLock || (SDL_GetModState() & KMOD_CAPS);
|
||||
const bool upper = capsLock || (key.keysym.mod & KMOD_SHIFT);
|
||||
|
||||
ch = (key.keysym.sym - SDLK_a) + 0x01;
|
||||
if (key.keysym.mod & KMOD_CTRL)
|
||||
{
|
||||
// ok
|
||||
}
|
||||
else if (upper)
|
||||
{
|
||||
ch += 0x40; // upper case
|
||||
}
|
||||
else
|
||||
{
|
||||
ch += 0x60; // lower case
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch)
|
||||
{
|
||||
addKeyToBuffer(ch);
|
||||
std::cerr << "SDL KeyboardEvent: " << std::hex << (int)ch << std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SDLFrame::SDLFrame(const EmulatorOptions & options)
|
||||
: myForceCapsLock(true)
|
||||
, myMultiplier(1)
|
||||
, myFullscreen(false)
|
||||
, mySpeed(options.fixedSpeed)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -89,3 +196,205 @@ int SDLFrame::FrameMessageBox(LPCSTR lpText, LPCSTR lpCaption, UINT uType)
|
|||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, lpCaption, s.c_str(), nullptr);
|
||||
return IDOK;
|
||||
}
|
||||
|
||||
void SDLFrame::ProcessEvents(bool &quit)
|
||||
{
|
||||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e) != 0)
|
||||
{
|
||||
ProcessSingleEvent(e, quit);
|
||||
}
|
||||
}
|
||||
|
||||
void SDLFrame::ProcessSingleEvent(const SDL_Event & e, bool &quit)
|
||||
{
|
||||
switch (e.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
{
|
||||
quit = true;
|
||||
break;
|
||||
}
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
ProcessKeyDown(e.key);
|
||||
break;
|
||||
}
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
ProcessKeyUp(e.key);
|
||||
break;
|
||||
}
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
ProcessText(e.text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SDLFrame::ProcessKeyDown(const SDL_KeyboardEvent & key)
|
||||
{
|
||||
// scancode vs keycode
|
||||
// scancode is relative to the position on the keyboard
|
||||
// keycode is what the os maps it to
|
||||
// if the user has decided to change the layout, we just go with it and use the keycode
|
||||
if (!key.repeat)
|
||||
{
|
||||
switch (key.keysym.sym)
|
||||
{
|
||||
case SDLK_F12:
|
||||
{
|
||||
Snapshot_LoadState();
|
||||
mySpeed.reset();
|
||||
break;
|
||||
}
|
||||
case SDLK_F11:
|
||||
{
|
||||
const std::string & pathname = Snapshot_GetPathname();
|
||||
const std::string message = "Do you want to save the state to " + pathname + "?";
|
||||
SoundCore_SetFade(FADE_OUT);
|
||||
if (show_yes_no_dialog(myWindow, "Save state", message))
|
||||
{
|
||||
Snapshot_SaveState();
|
||||
}
|
||||
SoundCore_SetFade(FADE_IN);
|
||||
mySpeed.reset();
|
||||
break;
|
||||
}
|
||||
case SDLK_F9:
|
||||
{
|
||||
CycleVideoType();
|
||||
break;
|
||||
}
|
||||
case SDLK_F6:
|
||||
{
|
||||
if ((key.keysym.mod & KMOD_CTRL) && (key.keysym.mod & KMOD_SHIFT))
|
||||
{
|
||||
Cycle50ScanLines();
|
||||
}
|
||||
else if (key.keysym.mod & KMOD_CTRL)
|
||||
{
|
||||
Video & video = GetVideo();
|
||||
myMultiplier = myMultiplier == 1 ? 2 : 1;
|
||||
const int sw = video.GetFrameBufferBorderlessWidth();
|
||||
const int sh = video.GetFrameBufferBorderlessHeight();
|
||||
SDL_SetWindowSize(myWindow.get(), sw * myMultiplier, sh * myMultiplier);
|
||||
}
|
||||
else if (!(key.keysym.mod & KMOD_SHIFT))
|
||||
{
|
||||
myFullscreen = !myFullscreen;
|
||||
SDL_SetWindowFullscreen(myWindow.get(), myFullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_F5:
|
||||
{
|
||||
CardManager & cardManager = GetCardMgr();
|
||||
if (cardManager.QuerySlot(SLOT6) == CT_Disk2)
|
||||
{
|
||||
dynamic_cast<Disk2InterfaceCard*>(cardManager.GetObj(SLOT6))->DriveSwap();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_F2:
|
||||
{
|
||||
if (key.keysym.mod & KMOD_CTRL)
|
||||
{
|
||||
CtrlReset();
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetMachineState();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDLK_F1:
|
||||
{
|
||||
SDirectSound::printInfo();
|
||||
break;
|
||||
}
|
||||
case SDLK_LALT:
|
||||
{
|
||||
Paddle::setButtonPressed(Paddle::ourOpenApple);
|
||||
break;
|
||||
}
|
||||
case SDLK_RALT:
|
||||
{
|
||||
Paddle::setButtonPressed(Paddle::ourSolidApple);
|
||||
break;
|
||||
}
|
||||
case SDLK_PAUSE:
|
||||
{
|
||||
switch (g_nAppMode)
|
||||
{
|
||||
case MODE_RUNNING:
|
||||
g_nAppMode = MODE_PAUSED;
|
||||
SoundCore_SetFade(FADE_OUT);
|
||||
break;
|
||||
case MODE_PAUSED:
|
||||
g_nAppMode = MODE_RUNNING;
|
||||
SoundCore_SetFade(FADE_IN);
|
||||
mySpeed.reset();
|
||||
break;
|
||||
}
|
||||
GetFrame().FrameRefreshStatus(DRAW_TITLE);
|
||||
break;
|
||||
}
|
||||
case SDLK_CAPSLOCK:
|
||||
{
|
||||
myForceCapsLock = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processAppleKey(key, myForceCapsLock);
|
||||
|
||||
#ifdef KEY_LOGGING_VERBOSE
|
||||
std::cerr << "KEY DOWN: " << key.keysym.scancode << "," << key.keysym.sym << "," << key.keysym.mod << "," << bool(key.repeat) << std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void SDLFrame::ProcessKeyUp(const SDL_KeyboardEvent & key)
|
||||
{
|
||||
switch (key.keysym.sym)
|
||||
{
|
||||
case SDLK_LALT:
|
||||
{
|
||||
Paddle::setButtonReleased(Paddle::ourOpenApple);
|
||||
break;
|
||||
}
|
||||
case SDLK_RALT:
|
||||
{
|
||||
Paddle::setButtonReleased(Paddle::ourSolidApple);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KEY_LOGGING_VERBOSE
|
||||
std::cerr << "KEY UP: " << key.keysym.scancode << "," << key.keysym.sym << "," << key.keysym.mod << "," << bool(key.repeat) << std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void SDLFrame::ProcessText(const SDL_TextInputEvent & text)
|
||||
{
|
||||
if (strlen(text.text) == 1)
|
||||
{
|
||||
const char key = text.text[0];
|
||||
switch (key) {
|
||||
case 0x20 ... 0x40:
|
||||
case 0x5b ... 0x60:
|
||||
case 0x7b ... 0x7e:
|
||||
{
|
||||
// not the letters
|
||||
// this is very simple, but one cannot handle CRTL-key combination.
|
||||
addKeyToBuffer(key);
|
||||
std::cerr << "SDL TextInputEvent: " << std::hex << (int)key << std::dec << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include "frontends/common2/commonframe.h"
|
||||
#include "frontends/common2/speed.h"
|
||||
#include <SDL.h>
|
||||
|
||||
struct EmulatorOptions;
|
||||
|
||||
class SDLFrame : public CommonFrame
|
||||
{
|
||||
public:
|
||||
SDLFrame();
|
||||
SDLFrame(const EmulatorOptions & options);
|
||||
|
||||
void VideoPresentScreen() override;
|
||||
void FrameRefreshStatus(int drawflags) override;
|
||||
int FrameMessageBox(LPCSTR lpText, LPCSTR lpCaption, UINT uType) override;
|
||||
void GetBitmap(LPCSTR lpBitmapName, LONG cb, LPVOID lpvBits) override;
|
||||
|
||||
void ProcessEvents(bool &quit);
|
||||
|
||||
virtual void UpdateTexture() = 0;
|
||||
virtual void RenderPresent() = 0;
|
||||
|
||||
|
@ -21,5 +26,17 @@ public:
|
|||
protected:
|
||||
void SetApplicationIcon();
|
||||
|
||||
virtual void ProcessSingleEvent(const SDL_Event & event, bool & quit);
|
||||
|
||||
void ProcessKeyDown(const SDL_KeyboardEvent & key);
|
||||
void ProcessKeyUp(const SDL_KeyboardEvent & key);
|
||||
void ProcessText(const SDL_TextInputEvent & text);
|
||||
|
||||
std::shared_ptr<SDL_Window> myWindow;
|
||||
|
||||
bool myForceCapsLock;
|
||||
int myMultiplier;
|
||||
bool myFullscreen;
|
||||
|
||||
Speed mySpeed;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue