make screenimage be a wxFrame; break out REPT key handling into dedicated class; progress on wx paddle handling
This commit is contained in:
parent
f63dcd908a
commit
29165a5685
|
@ -91,6 +91,8 @@ firmwarecard.cpp
|
|||
gui.cpp
|
||||
keyboardbuffermode.cpp
|
||||
keyboard.cpp
|
||||
KeyEventHandler.cpp
|
||||
KeyRepeatHandler.cpp
|
||||
languagecard.cpp
|
||||
lss.cpp
|
||||
magneticfield.cpp
|
||||
|
@ -201,7 +203,10 @@ include_directories(${PROJECT_BINARY_DIR})
|
|||
# TODO: can we remove this without being too backwardly incompatible?
|
||||
target_compile_definitions(${APP_NAME} PRIVATE ETCDIR="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_SYSCONFDIR}")
|
||||
|
||||
|
||||
if(WIN32)
|
||||
else()
|
||||
target_compile_options(${APP_NAME} PRIVATE -ggdb3)
|
||||
endif()
|
||||
|
||||
set_target_properties(${APP_NAME} PROPERTIES RESOURCE "${resources}")
|
||||
|
||||
|
|
|
@ -83,6 +83,8 @@ public:
|
|||
const std::filesystem::path GetConfigDir() const;
|
||||
const std::filesystem::path GetDocumentsDir() const;
|
||||
|
||||
E2wxFrame *GetFrame() { return this->frame; }
|
||||
|
||||
void StartEmulator();
|
||||
void StopEmulator();
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
enum E2MenuID {
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
epple2
|
||||
Copyright (C) 2022 by Christopher A. Mosher <cmosher01@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY, without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: KeyEventHandler.cpp
|
||||
* Author: chris.mosher
|
||||
*
|
||||
* Created on December 19, 2022, 7:36 AM
|
||||
*/
|
||||
|
||||
#include "KeyEventHandler.h"
|
||||
|
||||
KeyEventHandler::KeyEventHandler() {
|
||||
}
|
||||
|
||||
KeyEventHandler::KeyEventHandler(const KeyEventHandler& orig) {
|
||||
}
|
||||
|
||||
KeyEventHandler::~KeyEventHandler() {
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
epple2
|
||||
Copyright (C) 2022 by Christopher A. Mosher <cmosher01@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY, without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: KeyEventHandler.h
|
||||
* Author: chris.mosher
|
||||
*
|
||||
* Created on December 19, 2022, 7:36 AM
|
||||
*/
|
||||
|
||||
#ifndef KEYEVENTHANDLER_H
|
||||
#define KEYEVENTHANDLER_H
|
||||
|
||||
class KeyEventHandler {
|
||||
public:
|
||||
KeyEventHandler();
|
||||
KeyEventHandler(const KeyEventHandler& orig);
|
||||
virtual ~KeyEventHandler();
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif /* KEYEVENTHANDLER_H */
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
epple2
|
||||
Copyright (C) 2022 by Christopher A. Mosher <cmosher01@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY, without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: KeyRepeatHandler.cpp
|
||||
* Author: chris.mosher
|
||||
*
|
||||
* Created on December 19, 2022, 7:35 AM
|
||||
*/
|
||||
|
||||
#include "KeyRepeatHandler.h"
|
||||
#include "e2const.h"
|
||||
|
||||
// U.A.2 p. 7-13: REPT key repeats at 10Hz.
|
||||
static const int CYCLES_PER_REPT(E2Const::AVG_CPU_HZ / 10);
|
||||
|
||||
KeyRepeatHandler::KeyRepeatHandler(KeypressQueue &q) :
|
||||
repeat(false),
|
||||
is_key_down(false),
|
||||
keypresses(q) {
|
||||
}
|
||||
|
||||
KeyRepeatHandler::~KeyRepeatHandler() {
|
||||
}
|
||||
|
||||
void KeyRepeatHandler::tick() {
|
||||
if (this->repeat) {
|
||||
// Count our way down to when the timer for the REPT key
|
||||
// fires off: 10Hz in terms of how many CPU cycles have gone
|
||||
// by
|
||||
--this->rept;
|
||||
// If it's time for the REPT key timer to fire (at long
|
||||
// last)...
|
||||
if (this->rept <= 0) {
|
||||
// ...reload the timer for the next firing 1/10 second from
|
||||
// now ( *reset* the timer )
|
||||
this->rept = CYCLES_PER_REPT;
|
||||
// If any other keys are actually being held down...
|
||||
if (this->is_key_down) {
|
||||
// ...REPEAT the most recent one that was pressed
|
||||
this->keypresses.push(this->key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyRepeatHandler::setKey(unsigned char lastKeyDown) {
|
||||
this->is_key_down = true;
|
||||
this->key = lastKeyDown;
|
||||
}
|
||||
|
||||
void KeyRepeatHandler::clearKey() {
|
||||
this->is_key_down = false;
|
||||
}
|
||||
|
||||
void KeyRepeatHandler::press() {
|
||||
this->repeat = true;
|
||||
this->rept = CYCLES_PER_REPT;
|
||||
}
|
||||
|
||||
void KeyRepeatHandler::release() {
|
||||
this->repeat = false;
|
||||
this->rept = 0;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
epple2
|
||||
Copyright (C) 2022 by Christopher A. Mosher <cmosher01@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY, without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* File: KeyRepeatHandler.h
|
||||
* Author: chris.mosher
|
||||
*
|
||||
* Created on December 19, 2022, 7:35 AM
|
||||
*/
|
||||
|
||||
#ifndef KEYREPEATHANDLER_H
|
||||
#define KEYREPEATHANDLER_H
|
||||
|
||||
#include "keyboard.h"
|
||||
|
||||
class KeyRepeatHandler {
|
||||
bool repeat;
|
||||
int rept;
|
||||
bool is_key_down;
|
||||
unsigned char key;
|
||||
|
||||
KeypressQueue &keypresses;
|
||||
|
||||
public:
|
||||
KeyRepeatHandler(KeypressQueue &keypresses);
|
||||
virtual ~KeyRepeatHandler();
|
||||
|
||||
virtual void tick();
|
||||
|
||||
void setKey(unsigned char lastKeyDown);
|
||||
void clearKey();
|
||||
|
||||
void press();
|
||||
void release();
|
||||
};
|
||||
|
||||
#endif /* KEYREPEATHANDLER_H */
|
|
@ -20,6 +20,7 @@
|
|||
#include "e2config.h"
|
||||
#include "e2command.h"
|
||||
#include "e2const.h"
|
||||
#include "KeyRepeatHandler.h"
|
||||
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/string.h>
|
||||
|
@ -52,7 +53,7 @@ Emulator::Emulator() :
|
|||
videoStatic(display),
|
||||
apple2(keypresses, paddleButtonStates, display, buffered, screenImage),
|
||||
timable(nullptr), // No ticked object (NULL pointer)
|
||||
repeat(false),
|
||||
keyrepeater(keypresses),
|
||||
keysDown(0),
|
||||
prev_ms(SDL_GetTicks()) {
|
||||
}
|
||||
|
@ -70,31 +71,6 @@ void Emulator::config(E2Config& cfg) {
|
|||
}
|
||||
|
||||
|
||||
// U.A.2 p. 7-13: REPT key repeats at 10Hz.
|
||||
static const int CYCLES_PER_REPT(E2Const::AVG_CPU_HZ / 10);
|
||||
|
||||
// If the Apple ][ keyboard repeat is on (the REPT key is
|
||||
// down)...
|
||||
void Emulator::handleRepeatKey() {
|
||||
if (this->repeat) {
|
||||
// Count our way down to when the timer for the REPT key
|
||||
// fires off: 10Hz in terms of how many CPU cycles have gone
|
||||
// by
|
||||
--this->rept;
|
||||
// If it's time for the REPT key timer to fire (at long
|
||||
// last)...
|
||||
if (this->rept <= 0) {
|
||||
// ...reload the timer for the next firing 1/10 second from
|
||||
// now ( *reset* the timer )
|
||||
this->rept = CYCLES_PER_REPT;
|
||||
// If any other keys are actually being held down...
|
||||
if (this->keysDown > 0) {
|
||||
// ...REPEAT the most recent one that was pressed
|
||||
this->keypresses.push(this->lastKeyDown);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Emulator::handleAnyPendingEvents() {
|
||||
SDL_Event event;
|
||||
|
@ -134,10 +110,12 @@ void Emulator::tick50ms() {
|
|||
if (this->timable) {
|
||||
for (int i = 0; i < CHECK_EVERY_CYCLE; ++i) {
|
||||
this->timable->tick(); // this runs the emulator!
|
||||
handleRepeatKey();
|
||||
this->keyrepeater.tick(); // TODO move into Apple2
|
||||
}
|
||||
}
|
||||
|
||||
handleAnyPendingEvents();
|
||||
|
||||
this->screenImage.displayHz((1000*CHECK_EVERY_CYCLE)/(SDL_GetTicks() - this->prev_ms));
|
||||
this->prev_ms = SDL_GetTicks();
|
||||
}
|
||||
|
@ -225,7 +203,7 @@ static bool translateKeysToAppleModernized(SDL_Keycode keycode, SDL_Keymod modif
|
|||
// Take real-world keystrokes from SDL and filter them to emulate the Apple ][ keyboard
|
||||
void Emulator::dispatchKeyDown(const SDL_KeyboardEvent& keyEvent) {
|
||||
if (keyEvent.repeat) {
|
||||
// To repeat on the real Apple ][, you need to use the REPT key (emulated below by F10)
|
||||
// To repeat on the real Apple ][, you need to use the REPT key (emulated by F10)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -239,18 +217,16 @@ void Emulator::dispatchKeyDown(const SDL_KeyboardEvent& keyEvent) {
|
|||
}
|
||||
|
||||
if (sym == SDLK_F10) {
|
||||
// handle REPT key
|
||||
this->repeat = true;
|
||||
this->rept = CYCLES_PER_REPT;
|
||||
} else if (SDLK_F1 <= sym && sym <= SDLK_F12) {
|
||||
wxGetApp().OnFnKeyPressed(sym);
|
||||
this->keyrepeater.press();
|
||||
// } else if (SDLK_F1 <= sym && sym <= SDLK_F12) {
|
||||
// wxGetApp().OnFnKeyPressed(sym);
|
||||
} else {
|
||||
unsigned char key;
|
||||
const bool sendKey = translateKeysToAppleModernized(sym, mod, &key);
|
||||
if (sendKey) {
|
||||
//printf(" sending to apple as ASCII ------------------------------> %02X (%02X) (%d)\n", key, key | 0x80, key | 0x80);
|
||||
this->keypresses.push(key);
|
||||
this->lastKeyDown = key;
|
||||
this->keyrepeater.setKey(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,11 +237,13 @@ void Emulator::dispatchKeyUp(const SDL_KeyboardEvent& keyEvent) {
|
|||
|
||||
if (isKeyDown(sym, mod)) {
|
||||
--this->keysDown;
|
||||
} else if (sym == SDLK_F10) {
|
||||
// ...else if this is the emulated REPT key on the Apple keyboard...
|
||||
// ...stop repeating. The key has been released
|
||||
this->repeat = false;
|
||||
this->rept = 0;
|
||||
if (this->keysDown <= 0) {
|
||||
this->keyrepeater.clearKey();
|
||||
}
|
||||
}
|
||||
|
||||
if (sym == SDLK_F10) {
|
||||
this->keyrepeater.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,10 +315,11 @@ bool Emulator::isSafeToQuit() {
|
|||
|
||||
|
||||
void Emulator::toggleComputerPower() {
|
||||
if (this->timable == &this->videoStatic)
|
||||
if (this->timable == &this->videoStatic) {
|
||||
powerOnComputer();
|
||||
else
|
||||
} else {
|
||||
powerOffComputer();
|
||||
}
|
||||
}
|
||||
|
||||
void Emulator::powerOnComputer() {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "screenimage.h"
|
||||
#include "analogtv.h"
|
||||
#include "keyboardbuffermode.h"
|
||||
#include "KeyRepeatHandler.h"
|
||||
#include "clipboardhandler.h"
|
||||
#include <SDL.h>
|
||||
#include <wx/string.h>
|
||||
|
@ -35,6 +36,7 @@ class E2Config;
|
|||
class Emulator {
|
||||
PaddleButtonStates paddleButtonStates;
|
||||
KeypressQueue keypresses;
|
||||
KeyRepeatHandler keyrepeater;
|
||||
|
||||
KeyboardBufferMode buffered;
|
||||
ScreenImage screenImage;
|
||||
|
@ -45,10 +47,7 @@ class Emulator {
|
|||
|
||||
Timable* timable;
|
||||
|
||||
bool repeat;
|
||||
int keysDown;
|
||||
int rept;
|
||||
unsigned char lastKeyDown;
|
||||
int keysDown; // TODO move to KeyEventHandler
|
||||
Uint32 prev_ms;
|
||||
|
||||
void powerOnComputer();
|
||||
|
|
|
@ -14,79 +14,88 @@
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
#include "e2const.h"
|
||||
#include "paddles.h"
|
||||
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
|
||||
|
||||
Paddles::Paddles():
|
||||
rTick(PADDLE_COUNT)
|
||||
{
|
||||
|
||||
Paddles::Paddles() : rTick(PADDLE_COUNT) {
|
||||
}
|
||||
|
||||
|
||||
Paddles::~Paddles()
|
||||
{
|
||||
Paddles::~Paddles() {
|
||||
}
|
||||
|
||||
|
||||
void Paddles::tick()
|
||||
{
|
||||
for (int paddle = 0; paddle < PADDLE_COUNT; ++paddle)
|
||||
{
|
||||
if (this->rTick[paddle] > 0)
|
||||
void Paddles::tick() {
|
||||
for (int paddle = 0; paddle < PADDLE_COUNT; ++paddle) {
|
||||
if (this->rTick[paddle] > 0) {
|
||||
--this->rTick[paddle];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Paddles::startTimers()
|
||||
{
|
||||
try
|
||||
{
|
||||
void Paddles::startTimers() {
|
||||
try {
|
||||
tryStartPaddleTimers();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << "Warning: cannot start paddle timers; mouse will not function as paddles." << std::endl;
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Warning: cannot start paddle timers; mouse will not function as paddles.";
|
||||
}
|
||||
}
|
||||
|
||||
void Paddles::tryStartPaddleTimers()
|
||||
{
|
||||
static wxPoint current_mouse_position() {
|
||||
int x, y;
|
||||
SDL_GetMouseState(&x,&y);
|
||||
SDL_GetMouseState(&x, &y);
|
||||
return wxPoint(x, y);
|
||||
}
|
||||
|
||||
void Paddles::tryStartPaddleTimers() {
|
||||
// wxWindow *pwin = ::wxGetActiveWindow();
|
||||
// const wxPoint w = pwin->GetPosition(); // crash
|
||||
// BOOST_LOG_TRIVIAL(info) << "x: " << w.x << ", y: " << w.y;
|
||||
// constwxPoint m = ::wxGetMousePosition();
|
||||
// const wxPoint p = w-m;
|
||||
const wxPoint p = current_mouse_position();
|
||||
|
||||
double pMin = 0;
|
||||
double pMax = 500;
|
||||
x = (int)((x-pMin)/(pMax-pMin)*PADDLE_CYCLES+.5);
|
||||
y = (int)((y-pMin)/(pMax-pMin)*PADDLE_CYCLES+.5);
|
||||
int x = (int) ((p.x - pMin) / (pMax - pMin) * PADDLE_CYCLES + .5);
|
||||
int y = (int) ((p.y - pMin) / (pMax - pMin) * PADDLE_CYCLES + .5);
|
||||
|
||||
if (isTimedOut(0))
|
||||
if (isTimedOut(0)) {
|
||||
this->rTick[0] = x;
|
||||
if (isTimedOut(1))
|
||||
}
|
||||
if (isTimedOut(1)) {
|
||||
this->rTick[1] = y;
|
||||
}
|
||||
|
||||
/*
|
||||
Here we emulate having 4700 ohm across pins 7 and 1
|
||||
of the game controller, and a 47Kohm resistor acros
|
||||
of the game controller, and a 47K ohm resistor across
|
||||
pins 11 and 1, to give cheap real-time clocks at
|
||||
paddles 2 and 3. Paddle 2 is the 100 microsecond reference,
|
||||
and paddle 3 is the 1 millisecond reference. This is
|
||||
described in U.A.2, p. 7-33.
|
||||
*/
|
||||
if (isTimedOut(2))
|
||||
this->rTick[2] = E2Const::AVG_CPU_HZ/10000; // was 90, but why?
|
||||
if (isTimedOut(3))
|
||||
this->rTick[3] = E2Const::AVG_CPU_HZ/1000;
|
||||
*/
|
||||
if (isTimedOut(2)) {
|
||||
this->rTick[2] = E2Const::AVG_CPU_HZ / 10000; // was 90, but why?
|
||||
}
|
||||
if (isTimedOut(3)) {
|
||||
this->rTick[3] = E2Const::AVG_CPU_HZ / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
bool Paddles::isTimedOut(const int paddle)
|
||||
{
|
||||
if (paddle < 0 || PADDLE_COUNT <= paddle)
|
||||
{
|
||||
bool Paddles::isTimedOut(const int paddle) {
|
||||
if (paddle < 0 || PADDLE_COUNT <= paddle) {
|
||||
return false;
|
||||
}
|
||||
return this->rTick[paddle] <= 0;
|
||||
|
|
|
@ -16,11 +16,19 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "screenimage.h"
|
||||
#include "E2wxApp.h"
|
||||
#include "E2wxFrame.h"
|
||||
#include "e2const.h"
|
||||
#include "applentsc.h"
|
||||
#include "card.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/gdicmn.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
|
@ -57,6 +65,8 @@ class ScreenException {
|
|||
};
|
||||
|
||||
ScreenImage::ScreenImage() :
|
||||
wxFrame(nullptr/*wxGetApp().GetFrame()*/, wxID_ANY, "Emulator", wxDefaultPosition, wxDefaultSize,
|
||||
wxSYSTEM_MENU | wxCLOSE_BOX | wxCAPTION | wxCLIP_CHILDREN),
|
||||
fullscreen(false),
|
||||
buffer(true),
|
||||
display(AnalogTV::TV_OLD_COLOR),
|
||||
|
@ -64,12 +74,16 @@ ScreenImage::ScreenImage() :
|
|||
cassInName(32, ' '),
|
||||
cassOutName(32, ' ') {
|
||||
createScreen();
|
||||
Show();
|
||||
}
|
||||
|
||||
ScreenImage::~ScreenImage() {
|
||||
destroyScreen();
|
||||
}
|
||||
|
||||
wxBEGIN_EVENT_TABLE(ScreenImage, wxFrame)
|
||||
wxEND_EVENT_TABLE()
|
||||
|
||||
void ScreenImage::exitFullScreen() {
|
||||
if (this->fullscreen) {
|
||||
toggleFullScreen();
|
||||
|
@ -83,7 +97,30 @@ void ScreenImage::toggleFullScreen() {
|
|||
}
|
||||
|
||||
void ScreenImage::createScreen() {
|
||||
this->window = SDL_CreateWindow("Epple ][", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCRW, SCRH*ASPECT_RATIO, SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN);
|
||||
wxSizer *pszr = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
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);
|
||||
pszr->SetSizeHints(this);
|
||||
|
||||
}
|
||||
|
||||
void ScreenImage::createSdlTexture(wxPanel *panelSdl) {
|
||||
WXWidget nativeSdl = panelSdl->GetHandle();
|
||||
// TODO: do we need special gtk handling here, to get xid using:
|
||||
// GtkWidget* widget = panel->GetHandle();
|
||||
// gtk_widget_realize(widget);
|
||||
// Window xid = GDK_WINDOW_XWINDOW(widget->window);
|
||||
this->window = SDL_CreateWindowFrom(static_cast<void*>(nativeSdl));
|
||||
if (this->window == NULL) {
|
||||
printf("Unable to create window: %s\n", SDL_GetError());
|
||||
throw ScreenException();
|
||||
|
@ -105,9 +142,6 @@ void ScreenImage::createScreen() {
|
|||
|
||||
this->pixels = (unsigned int*) calloc(SCRW * SCRH, sizeof (unsigned int));
|
||||
this->screen_pitch = SCRW;
|
||||
|
||||
drawLabels();
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
void ScreenImage::destroyScreen() {
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
#define SCREENIMAGE_H
|
||||
|
||||
#include "analogtv.h"
|
||||
|
||||
#include <wx/frame.h>
|
||||
#include <wx/panel.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
@ -28,8 +32,9 @@ struct SDL_Texture;
|
|||
struct SDL_Renderer;
|
||||
struct SDL_Window;
|
||||
|
||||
class ScreenImage {
|
||||
class ScreenImage : public wxFrame {
|
||||
private:
|
||||
wxPanel *panelTop;
|
||||
SDL_Window* window;
|
||||
SDL_Renderer* renderer;
|
||||
SDL_Texture* texture;
|
||||
|
@ -39,6 +44,7 @@ private:
|
|||
bool buffer;
|
||||
AnalogTV::DisplayType display;
|
||||
void createScreen();
|
||||
void createSdlTexture(wxPanel *panelSdl);
|
||||
void destroyScreen();
|
||||
std::vector<std::string> slotnames;
|
||||
std::string cassInName;
|
||||
|
@ -46,6 +52,8 @@ private:
|
|||
|
||||
static std::string truncateFilePath(const std::filesystem::path& filepath);
|
||||
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
|
||||
// TODO some of these methods should be private
|
||||
public:
|
||||
ScreenImage();
|
||||
|
|
Loading…
Reference in New Issue