add wxWidgets app,frame; combine CMake files

This commit is contained in:
Christopher A. Mosher 2022-12-03 23:18:52 -05:00
parent 0b63800a3a
commit dd6f36048d
11 changed files with 650 additions and 108 deletions

View File

@ -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:

View File

@ -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}")

View File

@ -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}")

226
src/E2wxApp.cpp Normal file
View File

@ -0,0 +1,226 @@
/*
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/>.
Created on December 3, 2022, 3:02 PM
*/
#include "E2wxApp.h"
#include "E2wxFrame.h"
#include <wx/app.h>
#include <wx/xrc/xmlres.h>
#include <wx/fileconf.h>
#include <wx/stdpaths.h>
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/sources/severity_feature.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/expressions/formatters/stream.hpp>
#include <boost/log/expressions.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <wx/debugrpt.h>
#include <iostream>
#include <algorithm>
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();
}

63
src/E2wxApp.h Normal file
View File

@ -0,0 +1,63 @@
/*
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/>.
Created on December 3, 2022, 3:02 PM
*/
#ifndef E2WXAPP_H
#define E2WXAPP_H
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/string.h>
#include <filesystem>
#include <string>
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 */

96
src/E2wxFrame.cpp Normal file
View File

@ -0,0 +1,96 @@
/*
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/>.
Created on December 3, 2022, 3:02 PM
*/
#include "E2wxFrame.h"
#include "E2wxApp.h"
//#include "PreferencesDialog.h"
#include <wx/persist/toplevel.h>
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();
}

49
src/E2wxFrame.h Normal file
View File

@ -0,0 +1,49 @@
/*
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/>.
Created on December 3, 2022, 3:02 PM
*/
#ifndef E2WXFRAME_H
#define E2WXFRAME_H
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <string>
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 */

View File

@ -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();

View File

@ -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;
}
}

View File

@ -74,6 +74,7 @@ public:
void powerOffComputer();
void toggleComputerPower();
void cycleDisplayType();
void quitIfSafe();
virtual int run();
};

View File

@ -1,6 +1,6 @@
/*
epple2
Copyright (C) 2008 by Christopher A. Mosher <cmosher01@gmail.com>
Copyright (C) 2008, 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
@ -21,16 +21,29 @@
#include "gui.h"
#include "e2const.h"
#include <wx/app.h>
#include <string>
#include <memory>
#include <stdexcept>
#include <iostream>
#include <iomanip>
#include <thread>
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<Emulator> 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;
}