remove SDL event loop and use wx for keypresses instead; fix screen resizing
This commit is contained in:
parent
6d5e2d589a
commit
f7fc5e47e9
|
@ -169,7 +169,6 @@ void E2wxFrame::OnPreferences(wxCommandEvent& event) {
|
||||||
dlg->ShowModal();
|
dlg->ShowModal();
|
||||||
dlg->Destroy();
|
dlg->Destroy();
|
||||||
}
|
}
|
||||||
// TODO re-configure emulator here
|
|
||||||
wxGetApp().StartEmulator();
|
wxGetApp().StartEmulator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,21 +43,27 @@
|
||||||
90 GOTO 5
|
90 GOTO 5
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool isKeyDown(const SDL_Keycode sym, const SDL_Keymod mod) {
|
|
||||||
|
|
||||||
|
static bool is_key_down(const wxKeyEvent& keyEvent) {
|
||||||
|
const int sym = keyEvent.GetKeyCode();
|
||||||
return (
|
return (
|
||||||
(sym < 0x7F || sym == SDLK_LEFT || sym == SDLK_RIGHT) &&
|
(sym < 0x7F || sym == WXK_LEFT || sym == WXK_RIGHT) &&
|
||||||
!(sym == SDLK_TAB || sym == SDLK_BACKQUOTE || sym == '[' || sym == '\\' || sym == SDLK_DELETE) &&
|
!(sym == WXK_TAB || sym == '`' || sym == '[' || sym == '\\' || sym == WXK_DELETE) &&
|
||||||
!(sym == ']' && mod & KMOD_SHIFT)
|
!(sym == ']' && keyEvent.ShiftDown())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool translateKeysToAppleModernized(SDL_Keycode keycode, SDL_Keymod modifiers, unsigned char* key) {
|
// Take real-world keystrokes from SDL and filter them to emulate the Apple ][ keyboard
|
||||||
if (keycode == SDLK_LEFT) {
|
static bool translate_key(const wxKeyEvent& keyEvent, unsigned char* key) {
|
||||||
|
const int keycode = keyEvent.GetKeyCode();
|
||||||
|
|
||||||
|
if (keycode == WXK_LEFT) {
|
||||||
*key = 8;
|
*key = 8;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keycode == SDLK_RIGHT) {
|
if (keycode == WXK_RIGHT) {
|
||||||
*key = 21;
|
*key = 21;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -75,56 +81,56 @@ static bool translateKeysToAppleModernized(SDL_Keycode keycode, SDL_Keymod modif
|
||||||
|
|
||||||
// from SDL 1.2 to 2.0, we can't use UNICODE so we need to
|
// from SDL 1.2 to 2.0, we can't use UNICODE so we need to
|
||||||
// apply shift and control modifiers ourselves
|
// apply shift and control modifiers ourselves
|
||||||
if (modifiers & KMOD_SHIFT) {
|
if (keyEvent.ShiftDown()) {
|
||||||
if (keycode == SDLK_BACKQUOTE) *key = '~';
|
if (keycode == '`') *key = '~';
|
||||||
else if (keycode == SDLK_1) *key = '!';
|
else if (keycode == '1') *key = '!';
|
||||||
else if (keycode == SDLK_2) *key = '@';
|
else if (keycode == '2') *key = '@';
|
||||||
else if (keycode == SDLK_3) *key = '#';
|
else if (keycode == '3') *key = '#';
|
||||||
else if (keycode == SDLK_4) *key = '$';
|
else if (keycode == '4') *key = '$';
|
||||||
else if (keycode == SDLK_5) *key = '%';
|
else if (keycode == '5') *key = '%';
|
||||||
else if (keycode == SDLK_6) *key = '^';
|
else if (keycode == '6') *key = '^';
|
||||||
else if (keycode == SDLK_7) *key = '&';
|
else if (keycode == '7') *key = '&';
|
||||||
else if (keycode == SDLK_8) *key = '*';
|
else if (keycode == '8') *key = '*';
|
||||||
else if (keycode == SDLK_9) *key = '(';
|
else if (keycode == '9') *key = '(';
|
||||||
else if (keycode == SDLK_0) *key = ')';
|
else if (keycode == '0') *key = ')';
|
||||||
else if (keycode == SDLK_MINUS) *key = '_';
|
else if (keycode == '-') *key = '_';
|
||||||
else if (keycode == SDLK_EQUALS) *key = '+';
|
else if (keycode == '=') *key = '+';
|
||||||
|
|
||||||
else if (keycode == SDLK_SEMICOLON) *key = ':';
|
else if (keycode == ';') *key = ':';
|
||||||
else if (keycode == SDLK_QUOTE) *key = '\"';
|
else if (keycode == '\'') *key = '\"';
|
||||||
|
|
||||||
else if (keycode == SDLK_COMMA) *key = '<';
|
else if (keycode == ',') *key = '<';
|
||||||
else if (keycode == SDLK_PERIOD) *key = '>';
|
else if (keycode == '.') *key = '>';
|
||||||
else if (keycode == SDLK_SLASH) *key = '?';
|
else if (keycode == '/') *key = '?';
|
||||||
|
|
||||||
else if (keycode == SDLK_m) *key = ']';
|
else if (keycode == 'M') *key = ']';
|
||||||
else if (keycode == SDLK_n) *key = '^';
|
else if (keycode == 'N') *key = '^';
|
||||||
else if (keycode == SDLK_p) *key = '@';
|
else if (keycode == 'P') *key = '@';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modifiers & KMOD_CTRL) {
|
if (keyEvent.RawControlDown()) {
|
||||||
if (('A' <= *key && *key <= 'Z') || (*key == ']') || (*key == '^') || (*key == '@')) {
|
if (('A' <= *key && *key <= 'Z') || (*key == ']') || (*key == '^') || (*key == '@')) {
|
||||||
*key -= 64;
|
*key -= 64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((modifiers & KMOD_SHIFT) && (modifiers & KMOD_CTRL) && keycode == ' ') {
|
if (keyEvent.ShiftDown() && keyEvent.RawControlDown() && keycode == ' ') {
|
||||||
// Ctrl-Shift-Space is the same as Space
|
// Ctrl-Shift-Space is the same as Space
|
||||||
*key = ' ';
|
*key = ' ';
|
||||||
} else if ((modifiers & KMOD_CTRL) && !(modifiers & KMOD_SHIFT) && (('0' <= keycode && keycode <= '9') || keycode == '/' || keycode == ' ')) {
|
} else if (keyEvent.RawControlDown() && !keyEvent.ShiftDown() && (('0' <= keycode && keycode <= '9') || keycode == '/' || keycode == ' ')) {
|
||||||
// Control-only upon 0-9, / and space leaves them unchanged, the same as unmodified
|
// Control-only upon 0-9, / and space leaves them unchanged, the same as unmodified
|
||||||
*key = keycode;
|
*key = keycode;
|
||||||
} else if (keycode == ']') {
|
} else if (keycode == ']') {
|
||||||
if (modifiers & KMOD_SHIFT) {
|
if (keyEvent.ShiftDown()) {
|
||||||
// ignore '}' (shift ']')
|
// ignore '}' (shift ']')
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (modifiers & KMOD_CTRL) {
|
if (keyEvent.RawControlDown()) {
|
||||||
// Ctrl-] == ASCII: $1D
|
// Ctrl-] == ASCII: $1D
|
||||||
*key = 29;
|
*key = 29;
|
||||||
}
|
}
|
||||||
} // else if this is one of the *keys that can't be typed on an Apple ][ keyboard
|
} // else if this is one of the *keys that can't be typed on an Apple ][ keyboard
|
||||||
else if (*key == 0 || keycode == SDLK_TAB || keycode == SDLK_BACKQUOTE || keycode == '[' || keycode == '\\' || keycode == SDLK_DELETE) {
|
else if (*key == 0 || keycode == WXK_TAB || keycode == '`' || keycode == '[' || keycode == '\\' || keycode == WXK_DELETE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,29 +146,26 @@ KeyEventHandler::~KeyEventHandler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Take real-world keystrokes from SDL and filter them to emulate the Apple ][ keyboard
|
|
||||||
void KeyEventHandler::dispatchKeyDown(const SDL_KeyboardEvent& keyEvent) {
|
void KeyEventHandler::dispatchKeyDown(const wxKeyEvent& keyEvent) {
|
||||||
if (keyEvent.repeat) {
|
if (keyEvent.IsAutoRepeat()) {
|
||||||
// To repeat on the real Apple ][, you need to use the REPT key (emulated by F10)
|
// To repeat on the real Apple ][, you need to use the REPT key (emulated by F10)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SDL_Keycode sym = keyEvent.keysym.sym;
|
const int sym = keyEvent.GetKeyCode();
|
||||||
const SDL_Keymod mod = (SDL_Keymod)keyEvent.keysym.mod;
|
|
||||||
|
|
||||||
//printf("keydown: mod: %04X sym: %08X scan:%04X name:%s\n", mod, sym, scan, SDL_GetKeyName(sym));
|
//printf("keydown: mod: %04X sym: %08X scan:%04X name:%s\n", mod, sym, scan, SDL_GetKeyName(sym));
|
||||||
|
|
||||||
if (isKeyDown(sym, mod)) {
|
if (is_key_down(keyEvent)) {
|
||||||
++this->keysDown;
|
++this->keysDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym == SDLK_F10) {
|
if (sym == WXK_F10) {
|
||||||
this->repeater.press();
|
this->repeater.press();
|
||||||
// } else if (SDLK_F1 <= sym && sym <= SDLK_F12) {
|
|
||||||
// wxGetApp().OnFnKeyPressed(sym);
|
|
||||||
} else {
|
} else {
|
||||||
unsigned char key;
|
unsigned char key;
|
||||||
const bool sendKey = translateKeysToAppleModernized(sym, mod, &key);
|
const bool sendKey = translate_key(keyEvent, &key);
|
||||||
if (sendKey) {
|
if (sendKey) {
|
||||||
//printf(" sending to apple as ASCII ------------------------------> %02X (%02X) (%d)\n", key, key | 0x80, key | 0x80);
|
//printf(" sending to apple as ASCII ------------------------------> %02X (%02X) (%d)\n", key, key | 0x80, key | 0x80);
|
||||||
this->keypresses.push(key);
|
this->keypresses.push(key);
|
||||||
|
@ -171,18 +174,17 @@ void KeyEventHandler::dispatchKeyDown(const SDL_KeyboardEvent& keyEvent) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyEventHandler::dispatchKeyUp(const SDL_KeyboardEvent& keyEvent) {
|
void KeyEventHandler::dispatchKeyUp(const wxKeyEvent& keyEvent) {
|
||||||
const SDL_Keycode sym = keyEvent.keysym.sym;
|
const int sym = keyEvent.GetKeyCode();
|
||||||
const SDL_Keymod mod = (SDL_Keymod)keyEvent.keysym.mod;
|
|
||||||
|
|
||||||
if (isKeyDown(sym, mod)) {
|
if (is_key_down(keyEvent)) {
|
||||||
--this->keysDown;
|
--this->keysDown;
|
||||||
if (this->keysDown <= 0) {
|
if (this->keysDown <= 0) {
|
||||||
this->repeater.clearKey();
|
this->repeater.clearKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym == SDLK_F10) {
|
if (sym == WXK_F10) {
|
||||||
this->repeater.release();
|
this->repeater.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
#include "KeyRepeatHandler.h"
|
#include "KeyRepeatHandler.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include <SDL.h>
|
#include <wx/event.h>
|
||||||
|
|
||||||
class KeyEventHandler {
|
class KeyEventHandler {
|
||||||
int keysDown;
|
int keysDown;
|
||||||
|
@ -40,8 +40,8 @@ public:
|
||||||
KeyEventHandler(KeypressQueue &keypresses, KeyRepeatHandler &repeater);
|
KeyEventHandler(KeypressQueue &keypresses, KeyRepeatHandler &repeater);
|
||||||
virtual ~KeyEventHandler();
|
virtual ~KeyEventHandler();
|
||||||
|
|
||||||
void dispatchKeyDown(const SDL_KeyboardEvent& keyEvent);
|
void dispatchKeyDown(const wxKeyEvent& keyEvent);
|
||||||
void dispatchKeyUp(const SDL_KeyboardEvent& keyEvent);
|
void dispatchKeyUp(const wxKeyEvent& keyEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* KEYEVENTHANDLER_H */
|
#endif /* KEYEVENTHANDLER_H */
|
||||||
|
|
|
@ -327,6 +327,7 @@ void PreferencesDialog::OnRename(wxCommandEvent& evt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO make two buttons: "Close & Restart" and just "Close"
|
||||||
void PreferencesDialog::OnCloseButton(wxCommandEvent& evt) {
|
void PreferencesDialog::OnCloseButton(wxCommandEvent& evt) {
|
||||||
CTRL(wxTreeCtrl, treItems);
|
CTRL(wxTreeCtrl, treItems);
|
||||||
const TreeItemData *data = (TreeItemData*)treItems->GetItemData(treItems->GetSelection());
|
const TreeItemData *data = (TreeItemData*)treItems->GetItemData(treItems->GetSelection());
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
|
|
||||||
Emulator::Emulator() :
|
Emulator::Emulator() :
|
||||||
|
screenImage(keyEventHandler),
|
||||||
display(screenImage),
|
display(screenImage),
|
||||||
videoStatic(display),
|
videoStatic(display),
|
||||||
apple2(keypresses, paddleButtonStates, display, buffered, screenImage),
|
apple2(keypresses, paddleButtonStates, display, buffered, screenImage),
|
||||||
|
@ -60,31 +61,6 @@ void Emulator::config(E2Config& cfg) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Emulator::handleAnyPendingEvents() {
|
|
||||||
SDL_Event event;
|
|
||||||
while (SDL_PollEvent(&event)) {
|
|
||||||
switch (event.type) {
|
|
||||||
case SDL_QUIT:
|
|
||||||
// If SDL is going away...
|
|
||||||
// could be due to user closing the SDL window, pressing cmd-Q on Mac,
|
|
||||||
// ctrl-C from the command line on Linux, process being killed, etc.
|
|
||||||
wxGetApp().CloseMainFrame();
|
|
||||||
break;
|
|
||||||
case SDL_KEYDOWN:
|
|
||||||
// we're collecting keypresses for the keyboard
|
|
||||||
// emulation (and thus the Apple ][ emulation itself)
|
|
||||||
this->keyEventHandler.dispatchKeyDown(event.key);
|
|
||||||
// People who have too many press-releases should be referred to as "keyboards"
|
|
||||||
break;
|
|
||||||
case SDL_KEYUP:
|
|
||||||
this->keyEventHandler.dispatchKeyUp(event.key);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// How many emulation ticks between asking SDL if there is any new input
|
// How many emulation ticks between asking SDL if there is any new input
|
||||||
// from the user or other GUI events.
|
// from the user or other GUI events.
|
||||||
// This is also how often we shall update the estimate of the emulator's
|
// This is also how often we shall update the estimate of the emulator's
|
||||||
|
@ -101,8 +77,6 @@ void Emulator::tick50ms() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAnyPendingEvents();
|
|
||||||
|
|
||||||
this->screenImage.displayHz((1000*CHECK_EVERY_CYCLE)/(SDL_GetTicks() - this->prev_ms));
|
this->screenImage.displayHz((1000*CHECK_EVERY_CYCLE)/(SDL_GetTicks() - this->prev_ms));
|
||||||
this->prev_ms = SDL_GetTicks();
|
this->prev_ms = SDL_GetTicks();
|
||||||
}
|
}
|
||||||
|
@ -228,8 +202,8 @@ void Emulator::toggleBuffered() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emulator::toggleFullScreen() {
|
void Emulator::toggleFullScreen() {
|
||||||
this->screenImage.toggleFullScreen();
|
// this->screenImage.toggleFullScreen();
|
||||||
this->screenImage.drawPower(this->timable == &this->apple2);
|
// this->screenImage.drawPower(this->timable == &this->apple2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emulator::screenshot() {
|
void Emulator::screenshot() {
|
||||||
|
|
|
@ -52,10 +52,6 @@ class Emulator {
|
||||||
void powerOnComputer();
|
void powerOnComputer();
|
||||||
void powerOffComputer();
|
void powerOffComputer();
|
||||||
|
|
||||||
void handleAnyPendingEvents();
|
|
||||||
|
|
||||||
void handleRepeatKey();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Emulator();
|
Emulator();
|
||||||
virtual ~Emulator();
|
virtual ~Emulator();
|
||||||
|
|
|
@ -64,62 +64,69 @@ static const int WIDTH = AppleNTSC::H - AppleNTSC::PIC_START - 2;
|
||||||
class ScreenException {
|
class ScreenException {
|
||||||
};
|
};
|
||||||
|
|
||||||
ScreenImage::ScreenImage() :
|
ScreenImage::ScreenImage(KeyEventHandler &k) :
|
||||||
wxFrame(nullptr/*wxGetApp().GetFrame()*/, wxID_ANY, "Emulator", wxDefaultPosition, wxDefaultSize,
|
wxFrame(nullptr, wxID_ANY, "Emulator"),
|
||||||
wxSYSTEM_MENU | wxCLOSE_BOX | wxCAPTION | wxCLIP_CHILDREN),
|
|
||||||
fullscreen(false),
|
fullscreen(false),
|
||||||
buffer(true),
|
buffer(true),
|
||||||
display(AnalogTV::TV_OLD_COLOR),
|
display(AnalogTV::TV_OLD_COLOR),
|
||||||
slotnames(8),
|
slotnames(8),
|
||||||
cassInName(32, ' '),
|
cassInName(32, ' '),
|
||||||
cassOutName(32, ' ') {
|
cassOutName(32, ' '),
|
||||||
|
keyEventHandler(k) {
|
||||||
createScreen();
|
createScreen();
|
||||||
Show();
|
Show();
|
||||||
|
Bind(wxEVT_IDLE, &ScreenImage::OnIdle, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenImage::~ScreenImage() {
|
ScreenImage::~ScreenImage() {
|
||||||
destroyScreen();
|
destroyScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxBEGIN_EVENT_TABLE(ScreenImage, wxFrame)
|
|
||||||
wxEND_EVENT_TABLE()
|
|
||||||
|
|
||||||
void ScreenImage::exitFullScreen() {
|
|
||||||
if (this->fullscreen) {
|
void ScreenImage::OnIdle(wxIdleEvent &evt) {
|
||||||
toggleFullScreen();
|
if (!this->FindFocus() || !this->sdl->HasFocus()) {
|
||||||
|
this->sdl->SetFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScreenImage::exitFullScreen() {
|
||||||
|
// if (this->fullscreen) {
|
||||||
|
// toggleFullScreen();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
void ScreenImage::toggleFullScreen() {
|
void ScreenImage::toggleFullScreen() {
|
||||||
this->fullscreen = !this->fullscreen;
|
// this->fullscreen = !this->fullscreen;
|
||||||
const int flags = this->fullscreen ? SDL_WINDOW_FULLSCREEN : 0;
|
// const int flags = this->fullscreen ? SDL_WINDOW_FULLSCREEN : 0;
|
||||||
SDL_SetWindowFullscreen(this->window, flags);
|
// SDL_SetWindowFullscreen(this->window, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenImage::createScreen() {
|
void ScreenImage::createScreen() {
|
||||||
|
this->sdl = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(SCRW,SCRH*ASPECT_RATIO));
|
||||||
|
createSdlTexture();
|
||||||
|
this->sdl->Bind(wxEVT_KEY_DOWN, &ScreenImage::OnKeyDown, this);
|
||||||
|
this->sdl->Bind(wxEVT_KEY_UP, &ScreenImage::OnKeyUp, this);
|
||||||
|
|
||||||
wxSizer *pszr = new wxBoxSizer(wxVERTICAL);
|
wxSizer *pszr = new wxBoxSizer(wxVERTICAL);
|
||||||
|
pszr->Add(this->sdl);
|
||||||
this->panelTop = new wxPanel(this);
|
|
||||||
// TODO why won't shaped work? (Disabled frame resize as a workaround, for now.)
|
|
||||||
pszr->Add(this->panelTop, wxSizerFlags(0).Expand().Shaped().Center());
|
|
||||||
|
|
||||||
wxPanel *panelSdl = new wxPanel(this->panelTop, wxID_ANY, wxDefaultPosition, wxSize(SCRW,SCRH*ASPECT_RATIO));
|
|
||||||
createSdlTexture(panelSdl);
|
|
||||||
|
|
||||||
drawLabels();
|
|
||||||
notifyObservers();
|
|
||||||
|
|
||||||
SetSizer(pszr);
|
SetSizer(pszr);
|
||||||
pszr->SetSizeHints(this);
|
pszr->SetSizeHints(this);
|
||||||
|
|
||||||
|
this->pixels = (unsigned int*) calloc(SCRW * SCRH, sizeof (unsigned int));
|
||||||
|
this->screen_pitch = SCRW;
|
||||||
|
|
||||||
|
drawLabels();
|
||||||
|
notifyObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenImage::createSdlTexture(wxPanel *panelSdl) {
|
void ScreenImage::createSdlTexture() {
|
||||||
WXWidget nativeSdl = panelSdl->GetHandle();
|
WXWidget nativeSdl = this->sdl->GetHandle();
|
||||||
// TODO: do we need special gtk handling here, to get xid using:
|
// TODO: do we need special gtk handling here, to get xid using:
|
||||||
// GtkWidget* widget = panel->GetHandle();
|
// GtkWidget* widget = panel->GetHandle();
|
||||||
// gtk_widget_realize(widget);
|
// gtk_widget_realize(widget);
|
||||||
// Window xid = GDK_WINDOW_XWINDOW(widget->window);
|
// Window xid = GDK_WINDOW_XWINDOW(widget->window);
|
||||||
|
|
||||||
this->window = SDL_CreateWindowFrom(static_cast<void*>(nativeSdl));
|
this->window = SDL_CreateWindowFrom(static_cast<void*>(nativeSdl));
|
||||||
if (this->window == NULL) {
|
if (this->window == NULL) {
|
||||||
printf("Unable to create window: %s\n", SDL_GetError());
|
printf("Unable to create window: %s\n", SDL_GetError());
|
||||||
|
@ -139,9 +146,6 @@ void ScreenImage::createSdlTexture(wxPanel *panelSdl) {
|
||||||
std::cerr << SDL_GetError() << std::endl;
|
std::cerr << SDL_GetError() << std::endl;
|
||||||
throw ScreenException();
|
throw ScreenException();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->pixels = (unsigned int*) calloc(SCRW * SCRH, sizeof (unsigned int));
|
|
||||||
this->screen_pitch = SCRW;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenImage::destroyScreen() {
|
void ScreenImage::destroyScreen() {
|
||||||
|
@ -320,25 +324,26 @@ void ScreenImage::drawPower(bool on) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenImage::notifyObservers() {
|
void ScreenImage::notifyObservers() {
|
||||||
const int e = SDL_UpdateTexture(this->texture, NULL, this->pixels, SCRW * sizeof (unsigned int));
|
const int e = SDL_UpdateTexture(this->texture, NULL, this->pixels, SCRW*sizeof(unsigned int));
|
||||||
if (e) {
|
if (e) {
|
||||||
std::cerr << SDL_GetError() << std::endl;
|
std::cerr << SDL_GetError() << std::endl;
|
||||||
}
|
}
|
||||||
SDL_RenderClear(this->renderer);
|
SDL_RenderClear(this->renderer);
|
||||||
SDL_RenderCopy(this->renderer,this->texture,NULL,NULL);
|
SDL_RenderCopy(this->renderer, this->texture, NULL, NULL);
|
||||||
SDL_RenderPresent(this->renderer);
|
SDL_RenderPresent(this->renderer);
|
||||||
|
SDL_RenderSetLogicalSize(this->renderer, SCRW, SCRH*ASPECT_RATIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenImage::setElem(unsigned int i, const unsigned int val) {
|
void ScreenImage::setElem(unsigned int i, const unsigned int val) {
|
||||||
unsigned int* pn = this->pixels;
|
unsigned int* pn = this->pixels;
|
||||||
i += (i / WIDTH)*(SCRW - WIDTH);
|
i += (i/WIDTH)*(SCRW-WIDTH);
|
||||||
pn += i;
|
pn += i;
|
||||||
*pn = val;
|
*pn = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenImage::blank() {
|
void ScreenImage::blank() {
|
||||||
for (int r = 0; r < HEIGHT; ++r) {
|
for (int r = 0; r < HEIGHT; ++r) {
|
||||||
memset((char*) (this->pixels) + r * SCRW * 4, 0, WIDTH * 4);
|
memset((char*)(this->pixels)+r*SCRW*4, 0, WIDTH*4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,3 +544,11 @@ void ScreenImage::saveBMP() {
|
||||||
SDL_SaveBMP(screenshot, time);
|
SDL_SaveBMP(screenshot, time);
|
||||||
SDL_FreeSurface(screenshot);
|
SDL_FreeSurface(screenshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScreenImage::OnKeyDown(wxKeyEvent &evt) {
|
||||||
|
this->keyEventHandler.dispatchKeyDown(evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenImage::OnKeyUp(wxKeyEvent &evt) {
|
||||||
|
this->keyEventHandler.dispatchKeyUp(evt);
|
||||||
|
}
|
||||||
|
|
|
@ -18,10 +18,13 @@
|
||||||
#ifndef SCREENIMAGE_H
|
#ifndef SCREENIMAGE_H
|
||||||
#define SCREENIMAGE_H
|
#define SCREENIMAGE_H
|
||||||
|
|
||||||
|
#include "keyboard.h"
|
||||||
#include "analogtv.h"
|
#include "analogtv.h"
|
||||||
|
#include "KeyEventHandler.h"
|
||||||
|
|
||||||
#include <wx/frame.h>
|
#include <wx/frame.h>
|
||||||
#include <wx/panel.h>
|
#include <wx/panel.h>
|
||||||
|
#include <wx/event.h>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -34,7 +37,7 @@ struct SDL_Window;
|
||||||
|
|
||||||
class ScreenImage : public wxFrame {
|
class ScreenImage : public wxFrame {
|
||||||
private:
|
private:
|
||||||
wxPanel *panelTop;
|
wxPanel *sdl;
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
SDL_Renderer* renderer;
|
SDL_Renderer* renderer;
|
||||||
SDL_Texture* texture;
|
SDL_Texture* texture;
|
||||||
|
@ -44,19 +47,23 @@ private:
|
||||||
bool buffer;
|
bool buffer;
|
||||||
AnalogTV::DisplayType display;
|
AnalogTV::DisplayType display;
|
||||||
void createScreen();
|
void createScreen();
|
||||||
void createSdlTexture(wxPanel *panelSdl);
|
void createSdlTexture();
|
||||||
void destroyScreen();
|
void destroyScreen();
|
||||||
std::vector<std::string> slotnames;
|
std::vector<std::string> slotnames;
|
||||||
std::string cassInName;
|
std::string cassInName;
|
||||||
std::string cassOutName;
|
std::string cassOutName;
|
||||||
|
|
||||||
|
KeyEventHandler &keyEventHandler;
|
||||||
|
|
||||||
static std::string truncateFilePath(const std::filesystem::path& filepath);
|
static std::string truncateFilePath(const std::filesystem::path& filepath);
|
||||||
|
|
||||||
wxDECLARE_EVENT_TABLE();
|
void OnIdle(wxIdleEvent &evt);
|
||||||
|
void OnKeyDown(wxKeyEvent &evt);
|
||||||
|
void OnKeyUp(wxKeyEvent &evt);
|
||||||
|
|
||||||
// TODO some of these methods should be private
|
// TODO some of these methods should be private
|
||||||
public:
|
public:
|
||||||
ScreenImage();
|
ScreenImage(KeyEventHandler &keyEventHandler);
|
||||||
~ScreenImage();
|
~ScreenImage();
|
||||||
|
|
||||||
void exitFullScreen();
|
void exitFullScreen();
|
||||||
|
|
Loading…
Reference in New Issue