From dd6f36048d66b458b131ba7ce0dd8c32a9973d35 Mon Sep 17 00:00:00 2001 From: "Christopher A. Mosher" Date: Sat, 3 Dec 2022 23:18:52 -0500 Subject: [PATCH] add wxWidgets app,frame; combine CMake files --- .github/workflows/build.yaml | 7 +- CMakeLists.txt | 168 +++++++++++++++++++++++++- src/CMakeLists.txt | 80 ------------- src/E2wxApp.cpp | 226 +++++++++++++++++++++++++++++++++++ src/E2wxApp.h | 63 ++++++++++ src/E2wxFrame.cpp | 96 +++++++++++++++ src/E2wxFrame.h | 49 ++++++++ src/apple2.cpp | 1 + src/emulator.cpp | 16 +-- src/emulator.h | 1 + src/main.cpp | 51 ++++++-- 11 files changed, 650 insertions(+), 108 deletions(-) delete mode 100644 src/CMakeLists.txt create mode 100644 src/E2wxApp.cpp create mode 100644 src/E2wxApp.h create mode 100644 src/E2wxFrame.cpp create mode 100644 src/E2wxFrame.h diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 5f9ca44..20539cc 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,8 +1,8 @@ --- on: push: - tags: - - "*" + branches: + - "2.0" env: name: "epple2" @@ -24,10 +24,11 @@ jobs: - name: "Build" run: | set -x + cd rom mkdir build cd build cmake .. - cmake --build . --target roms + cmake --build . - uses: "actions/upload-artifact@v3" with: diff --git a/CMakeLists.txt b/CMakeLists.txt index 1bb3aaf..c0b9e8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,167 @@ cmake_minimum_required(VERSION 3.22.1) -set(CMAKE_VERBOSE_MAKEFILE TRUE) -set(CMAKE_FIND_DEBUG_MODE TRUE) -project(epple2) +set(CMAKE_VERBOSE_MAKEFILE TRUE CACHE BOOL "Echo make commands.") +set(PACKAGE_SUITE TRUE CACHE BOOL "Build entire suite of packages; otherwise just ZIP file.") + +#set(CMAKE_BUILD_TYPE RelWithDebInfo) +set(CMAKE_BUILD_TYPE Debug) +set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) + +set(APP_NAME epple2) + +project(${APP_NAME} + VERSION 2.0.0 + DESCRIPTION "Apple II emulator" + HOMEPAGE_URL https://github.com/cmosher01/Epple-II + LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(PROJECT_FOURCC epl2) +set(PROJECT_VENDOR "nu.mine.mosher") +set(CPACK_PACKAGE_VENDOR "${PROJECT_VENDOR}") +set(CPACK_PACKAGE_CONTACT "cmosher01@gmail.com") +set(CPACK_PACKAGE_DESCRIPTION "${PROJECT_DESCRIPTION}") + + + +file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH) +if(EXISTS "${LOC_PATH}") + message(FATAL_ERROR "You cannot build in a source directory; make a build subdirectory.") +endif() + + + +if(WIN32) + set(CMAKE_INSTALL_PREFIX "C:/Program Files/${PROJECT_NAME}") + unset(CPACK_PACKAGING_INSTALL_PREFIX) +elseif(APPLE) + unset(CMAKE_INSTALL_PREFIX) + unset(CPACK_PACKAGING_INSTALL_PREFIX) +else() + set(CMAKE_INSTALL_PREFIX "/opt/${CPACK_PACKAGE_VENDOR}/${PROJECT_NAME}") + set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") +endif() include(GNUInstallDirs) -add_subdirectory(src) -add_subdirectory(conf) -add_subdirectory(rom) +include_directories(BEFORE "include") + + + +set(sources +a2colorsobserved.cpp +addressbus.cpp +analogtv.cpp +apple2.cpp +applentsc.cpp +card.cpp +cassette.cpp +cassettein.cpp +cassetteout.cpp +Circuit.cpp +clipboardhandler.cpp +clockcard.cpp +Common.cpp +configep2.cpp +Cpu6502.cpp +Cpu6502Helper.cpp +cpu.cpp +disk2readwritehead.cpp +disk2steppermotorcan.cpp +disk2steppermotor.cpp +disk2steppermotorrotor.cpp +diskcontroller.cpp +drive.cpp +drivemotor.cpp +E2wxApp.cpp +E2wxFrame.cpp +emptyslot.cpp +Emu6502.cpp +emulator.cpp +filterchroma.cpp +filterluma.cpp +firmwarecard.cpp +gui.cpp +hypermode.cpp +keyboardbuffermode.cpp +keyboard.cpp +languagecard.cpp +lss.cpp +magneticfield.cpp +main.cpp +memorychip.cpp +memory.cpp +memoryrandomaccess.cpp +memoryrow.cpp +memorystrapping.cpp +movable.cpp +paddlebuttonstates.cpp +paddles.cpp +picturegenerator.cpp +powerupreset.cpp +screenimage.cpp +SegmentCache.cpp +slots.cpp +speakerclicker.cpp +standardin.cpp +standardinproducer.cpp +standardout.cpp +StateCalculator.cpp +textcharacters.cpp +timable.cpp +tinyfiledialogs.cpp +Trace.cpp +TransCache.cpp +TransNetwork.cpp +videoaddressing.cpp +video.cpp +videomode.cpp +videostaticgenerator.cpp +wozfile.cpp +) +list(TRANSFORM sources PREPEND "src/") + +set(resources +#epple2.xrc +#epple2.png +conf/epple2.conf +) + +add_executable(${APP_NAME} WIN32 MACOSX_BUNDLE ${sources} ${resources}) + +find_package(SDL2 REQUIRED) +target_include_directories(${APP_NAME} PRIVATE ${SDL2_INCLUDE_DIRS}) +target_link_libraries(${APP_NAME} PRIVATE ${SDL2_LIBRARIES}) + +find_package(Boost REQUIRED COMPONENTS log filesystem) +# These settings must match those of the installed boost libraries. +# Use objdump to check the "namespace", such as "v2_mt_nt6" +# https://www.boost.org/doc/libs/master/libs/log/doc/html/log/rationale/namespace_mangling.html +target_compile_definitions(${APP_NAME} PRIVATE + BOOST_ALL_DYN_LINK + BOOST_ATOMIC_DYN_LINK + BOOST_CHRONO_DYN_LINK + BOOST_FILESYSTEM_DYN_LINK + BOOST_LIB_DIAGNOSTIC + BOOST_LOG_DYN_LINK + BOOST_REGEX_DYN_LINK + BOOST_THREAD_DYN_LINK + BOOST_ALL_NO_LIB + BOOST_LIB_DIAGNOSTIC + BOOST_USE_WINAPI_VERSION=0x0600) +target_link_libraries(${APP_NAME} PRIVATE ${Boost_LIBRARIES}) + +find_package(wxWidgets REQUIRED COMPONENTS base core xrc qa) +include(${wxWidgets_USE_FILE}) +target_link_libraries(${APP_NAME} PRIVATE ${wxWidgets_LIBRARIES}) + + + +target_compile_definitions(${APP_NAME} PRIVATE ETCDIR="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_SYSCONFDIR}") + + + +set_target_properties(${APP_NAME} PROPERTIES RESOURCE "${resources}") + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 12be51c..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,80 +0,0 @@ -set(sources -a2colorsobserved.cpp -addressbus.cpp -analogtv.cpp -apple2.cpp -applentsc.cpp -card.cpp -cassette.cpp -cassettein.cpp -cassetteout.cpp -Circuit.cpp -clipboardhandler.cpp -clockcard.cpp -Common.cpp -configep2.cpp -Cpu6502.cpp -Cpu6502Helper.cpp -cpu.cpp -disk2readwritehead.cpp -disk2steppermotorcan.cpp -disk2steppermotor.cpp -disk2steppermotorrotor.cpp -diskcontroller.cpp -drive.cpp -drivemotor.cpp -emptyslot.cpp -Emu6502.cpp -emulator.cpp -filterchroma.cpp -filterluma.cpp -firmwarecard.cpp -gui.cpp -hypermode.cpp -keyboardbuffermode.cpp -keyboard.cpp -languagecard.cpp -lss.cpp -magneticfield.cpp -main.cpp -memorychip.cpp -memory.cpp -memoryrandomaccess.cpp -memoryrow.cpp -memorystrapping.cpp -movable.cpp -paddlebuttonstates.cpp -paddles.cpp -picturegenerator.cpp -powerupreset.cpp -screenimage.cpp -SegmentCache.cpp -slots.cpp -speakerclicker.cpp -standardin.cpp -standardinproducer.cpp -standardout.cpp -StateCalculator.cpp -textcharacters.cpp -timable.cpp -tinyfiledialogs.cpp -Trace.cpp -TransCache.cpp -TransNetwork.cpp -videoaddressing.cpp -video.cpp -videomode.cpp -videostaticgenerator.cpp -wozfile.cpp -) - -add_executable(epple2 ${sources}) - -find_package(SDL2 CONFIG) -message(STATUS "SDL2_INCLUDE_DIRS: ${SDL2_INCLUDE_DIRS}") -target_include_directories(epple2 PRIVATE ${SDL2_INCLUDE_DIRS}) -message(STATUS "SDL2_LIBRARIES: ${SDL2_LIBRARIES}") -target_link_libraries(epple2 ${SDL2_LIBRARIES}) - -target_compile_features(epple2 PRIVATE cxx_std_17) -target_compile_definitions(epple2 PRIVATE ETCDIR="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_SYSCONFDIR}") diff --git a/src/E2wxApp.cpp b/src/E2wxApp.cpp new file mode 100644 index 0000000..cdac5c1 --- /dev/null +++ b/src/E2wxApp.cpp @@ -0,0 +1,226 @@ +/* + epple2 + Copyright (C) 2022 by Christopher A. Mosher + + 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 . + + Created on December 3, 2022, 3:02 PM + */ + +#include "E2wxApp.h" +#include "E2wxFrame.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +wxIMPLEMENT_APP_NO_MAIN(E2wxApp); + + + +#ifndef PROJECT_VERSION +#define PROJECT_VERSION 0.0.1 +#endif + +E2wxApp::E2wxApp() : id("nu.mine.mosher.epple2"), version(wxSTRINGIZE_T(PROJECT_VERSION)) { +} + +E2wxApp::~E2wxApp() { +} + + + + + + + + + + +static std::filesystem::path dirCache() { + return std::filesystem::path(wxStandardPaths::Get().GetUserDir(wxStandardPaths::Dir_Cache).t_str()); +} + +static std::filesystem::path dirConfig() { + return std::filesystem::path(wxStandardPaths::Get().GetUserConfigDir().t_str()); +} + +static std::filesystem::path dirDocuments() { + return std::filesystem::path(wxStandardPaths::Get().GetAppDocumentsDir().t_str()); +} + +static std::filesystem::path dirResources() { + return std::filesystem::path(wxStandardPaths::Get().GetResourcesDir().t_str()); +} + + + + + + + +bool E2wxApp::OnInit() { + if (!wxApp::OnInit()) { + return false; + } + + wxHandleFatalExceptions(); + + wxStandardPaths& stdpaths = wxStandardPaths::Get(); + //stdpaths.SetInstallPrefix("."); + stdpaths.SetFileLayout(wxStandardPaths::FileLayout_XDG); + + + + InitBoostLog(); + + + + + this->confdir = dirConfig() / std::filesystem::path(GetID()+".d"); + std::filesystem::create_directories(this->confdir); + BOOST_LOG_TRIVIAL(info) << "Configuration directory path: " << this->confdir; + + this->conffile = dirConfig() / std::filesystem::path(GetID()); + BOOST_LOG_TRIVIAL(info) << "Configuration file path: " << this->conffile; + wxConfigBase::Set(new wxFileConfig("", "", GetID())); + + this->docsdir = dirDocuments() / std::filesystem::path(GetID()); + BOOST_LOG_TRIVIAL(info) << "User document directory path: " << this->docsdir; + + const std::filesystem::path exe = std::filesystem::path(stdpaths.GetExecutablePath().t_str()); + std::cout << "Executable file path: " << exe << std::endl; + std::filesystem::path res = exe.parent_path(); + if (res.filename() == "bin" || res.filename() == "MacOS") { + res = res.parent_path(); + } + if (std::filesystem::is_directory(res / "share")) { + res /= "share"; + } + if (std::filesystem::is_directory(res / "Resources")) { + res /= "Resources"; + } + this->resdir = res; + std::cout << "Resource directory path: " << this->resdir << std::endl; + + wxXmlResource::Get()->InitAllHandlers(); + if (!wxXmlResource::Get()->LoadAllFiles(this->resdir.c_str())) { + return false; + } + + + + E2wxFrame *frame = new E2wxFrame(); + frame->DoInit(); + frame->Show(); + + + + return true; +} + +void E2wxApp::OnFatalException() { + wxDebugReport report; + report.AddAll(); + + wxDebugReportPreviewStd preview; + if (preview.Show(report)) { + report.Process(); + } +} + +int E2wxApp::OnExit() { + return 0; +} + + + +const std::filesystem::path E2wxApp::GetLogFile() const { + return this->logfile; +} + +const std::filesystem::path E2wxApp::GetResDir() const { + return this->resdir; +} + +const std::string E2wxApp::GetID() const { + return this->id; +} + +const wxString E2wxApp::GetVersion() const { + return this->version; +} + +const std::filesystem::path E2wxApp::GetConfigFile() const { + return this->conffile; +} + +const std::filesystem::path E2wxApp::GetConfigDir() const { + return this->confdir; +} + +const std::filesystem::path E2wxApp::GetDocumentsDir() const { + return this->docsdir; +} + + + +const std::filesystem::path E2wxApp::BuildLogFilePath() const { + std::filesystem::path logfile = + dirCache() / + std::filesystem::path(GetID()) / + std::filesystem::path("log"); + + std::filesystem::create_directories(logfile); + logfile = std::filesystem::canonical(logfile); + + const std::string ts = to_iso_string(boost::posix_time::second_clock::universal_time()); + logfile /= ts + ".log"; + + return logfile; +} + +void E2wxApp::InitBoostLog() { + this->logfile = BuildLogFilePath(); + + std::cout << "log file: " << this->logfile << std::endl; + + + + boost::log::add_file_log( + boost::log::keywords::file_name = this->logfile, + boost::log::keywords::auto_flush = true, + boost::log::keywords::format = ( + boost::log::expressions::stream << + to_iso_extended_string(boost::posix_time::microsec_clock::universal_time()) << "Z " << + boost::log::trivial::severity << " " << + boost::log::expressions::message + )); + + boost::log::add_common_attributes(); +} diff --git a/src/E2wxApp.h b/src/E2wxApp.h new file mode 100644 index 0000000..a37edba --- /dev/null +++ b/src/E2wxApp.h @@ -0,0 +1,63 @@ +/* + epple2 + Copyright (C) 2022 by Christopher A. Mosher + + 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 . + + Created on December 3, 2022, 3:02 PM + */ + +#ifndef E2WXAPP_H +#define E2WXAPP_H + +#include +#ifndef WX_PRECOMP + #include +#endif +#include +#include +#include + +class E2wxApp : public wxApp { + const std::string id; + const wxString version; + std::filesystem::path logfile; + std::filesystem::path resdir; + std::filesystem::path conffile; + std::filesystem::path confdir; + std::filesystem::path docsdir; + + const std::filesystem::path BuildLogFilePath() const; + void InitBoostLog(); + +public: + E2wxApp(); + virtual ~E2wxApp(); + + const std::string GetID() const; + const wxString GetVersion() const; + const std::filesystem::path GetLogFile() const; + const std::filesystem::path GetResDir() const; + const std::filesystem::path GetConfigFile() const; + const std::filesystem::path GetConfigDir() const; + const std::filesystem::path GetDocumentsDir() const; + + virtual bool OnInit() override; + virtual int OnExit() override; + virtual void OnFatalException() override; +}; + +wxDECLARE_APP(E2wxApp); + +#endif /* E2WXAPP_H */ diff --git a/src/E2wxFrame.cpp b/src/E2wxFrame.cpp new file mode 100644 index 0000000..34d523d --- /dev/null +++ b/src/E2wxFrame.cpp @@ -0,0 +1,96 @@ +/* + epple2 + Copyright (C) 2022 by Christopher A. Mosher + + 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 . + + Created on December 3, 2022, 3:02 PM + */ + +#include "E2wxFrame.h" +#include "E2wxApp.h" +//#include "PreferencesDialog.h" +#include + + + +wxBEGIN_EVENT_TABLE(E2wxFrame, wxFrame) + EVT_MENU(wxID_EXIT, E2wxFrame::OnExit) + EVT_MENU(wxID_PREFERENCES, E2wxFrame::OnPreferences) + EVT_MENU(wxID_ABOUT, E2wxFrame::OnAbout) +wxEND_EVENT_TABLE() + + + +E2wxFrame::E2wxFrame() : wxFrame(nullptr, wxID_ANY, "epple2") { +} + +E2wxFrame::~E2wxFrame() { +} + +void E2wxFrame::DoInit() { + InitMenuBar(); + InitStatusBar(); + + if (!wxPersistentRegisterAndRestore(this, "main")) { + Center(); + } +} + +void E2wxFrame::InitMenuBar() { + wxMenuBar *menuBar = new wxMenuBar(); + SetMenuBar(menuBar); + + wxMenu *menuFile = new wxMenu(); + menuBar->Append(menuFile, "&File"); + menuFile->Append(wxID_EXIT); + + wxMenu *menuEdit = new wxMenu(); + menuBar->Append(menuEdit, "&Edit"); + menuEdit->Append(wxID_PREFERENCES); + + wxMenu *menuHelp = new wxMenu(); + menuBar->Append(menuHelp, "&Help"); + menuHelp->Append(wxID_ABOUT); +} + +void E2wxFrame::InitStatusBar() { + CreateStatusBar(); + SetStatusText(wxT("Welcome to ")+wxGetApp().GetID()); +} + + + +void E2wxFrame::OnExit(wxCommandEvent& event) { + Close(true); +} + +void E2wxFrame::OnAbout(wxCommandEvent& event) { + wxString msg = ""; + + msg += wxGetApp().GetID()+wxT("\n"); + + msg += wxT("version: ")+wxGetApp().GetVersion()+wxT("\n"); + + msg += wxT("Current log file:\n"); + msg += wxGetApp().GetLogFile().c_str(); + + wxMessageBox(msg, wxT("About ")+wxGetApp().GetID(), wxOK | wxICON_INFORMATION); +} + +void E2wxFrame::OnPreferences(wxCommandEvent& event) { +// PreferencesDialog *dlg = new PreferencesDialog(this); +// dlg->OnInit(); +// dlg->ShowModal(); +} diff --git a/src/E2wxFrame.h b/src/E2wxFrame.h new file mode 100644 index 0000000..094499c --- /dev/null +++ b/src/E2wxFrame.h @@ -0,0 +1,49 @@ +/* + epple2 + Copyright (C) 2022 by Christopher A. Mosher + + 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 . + + Created on December 3, 2022, 3:02 PM + */ + +#ifndef E2WXFRAME_H +#define E2WXFRAME_H + +#include +#ifndef WX_PRECOMP + #include +#endif + +#include + +class E2wxFrame : public wxFrame { +public: + E2wxFrame(); + virtual ~E2wxFrame(); + + void DoInit(); + +private: + void OnExit(wxCommandEvent& event); + void OnPreferences(wxCommandEvent& event); + void OnAbout(wxCommandEvent& event); + + void InitMenuBar(); + void InitStatusBar(); + + wxDECLARE_EVENT_TABLE(); +}; + +#endif /* E2WXFRAME_H */ diff --git a/src/apple2.cpp b/src/apple2.cpp index ccf58ef..3b12f1d 100644 --- a/src/apple2.cpp +++ b/src/apple2.cpp @@ -89,6 +89,7 @@ void Apple2::tick() { void Apple2::powerOn() { + useEpple2Cpu(); // default, if not already set this->ram.powerOn(); this->cpu->powerOn(); this->videoMode.powerOn(); diff --git a/src/emulator.cpp b/src/emulator.cpp index 3779488..2d51d6c 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -142,9 +142,7 @@ int Emulator::run() { switch (event.type) { // If SDL is going away... case SDL_QUIT: - if (isSafeToQuit()) { - this->quit = true; - } + quitIfSafe(); break; case SDL_KEYDOWN: // If we're collecting a command line for changing any @@ -373,10 +371,7 @@ void Emulator::dispatchKeypress(const SDL_KeyboardEvent& keyEvent) { return; }// ...else exit the entire emulation else if (sym == SDLK_F9) { - this->screenImage.exitFullScreen(); - if (isSafeToQuit()) { - this->quit = true; - } + quitIfSafe(); return; }// ...else save a screen shot else if (sym == SDLK_F8) { @@ -475,3 +470,10 @@ bool Emulator::isSafeToQuit() { return true; } + +void Emulator::quitIfSafe() { + this->screenImage.exitFullScreen(); + if (isSafeToQuit()) { + this->quit = true; + } +} diff --git a/src/emulator.h b/src/emulator.h index c15a355..06663e8 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -74,6 +74,7 @@ public: void powerOffComputer(); void toggleComputerPower(); void cycleDisplayType(); + void quitIfSafe(); virtual int run(); }; diff --git a/src/main.cpp b/src/main.cpp index 0d8b551..05caf50 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ /* epple2 - Copyright (C) 2008 by Christopher A. Mosher + Copyright (C) 2008, 2022 by Christopher A. Mosher 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 @@ -21,16 +21,29 @@ #include "gui.h" #include "e2const.h" +#include + #include #include #include - #include #include +#include +static std::string parse_args(int argc, char* argv[]) { + if (argc > 2) { + throw std::runtime_error("usage: epple2 [config-file]" ); + } -static int run(const std::string& config_file) { + if (argc <= 1) { + return std::string(); + } + + return std::string(argv[1]); +} + +static int run(const std::string config_file) { GUI gui; std::unique_ptr emu(new Emulator()); @@ -43,15 +56,19 @@ static int run(const std::string& config_file) { return emu->run(); } +static void queueEmuQuit() { + SDL_Event f9; + f9.type = SDL_KEYDOWN; + f9.key.keysym.sym = SDLK_F9; + SDL_PushEvent(&f9); +} + #ifdef __cplusplus extern "C" #endif int main(int argc, char* argv[]) { setbuf(stdout, NULL); - - if (argc > 2) { - throw std::runtime_error("usage: epple2 [config-file]" ); - } + setbuf(stderr, NULL); int x = E2Const::test(); if (x != -1) { @@ -59,10 +76,20 @@ int main(int argc, char* argv[]) { throw std::runtime_error("bad constant in e2const.h" ); } - std::string config_file; - if (argc > 1) { - config_file = argv[1]; - } + const std::string config_file = parse_args(argc, argv); - return run(config_file); + + + std::thread sdl_thread(run, config_file); + + int none(0); + wxEntry(none, (char**)nullptr); + // Runs wxWidgets main event loop and waits for user to File/Exit. + + + + queueEmuQuit(); + sdl_thread.join(); + + return 0; }