From f3bff96968d27da20bfaba85d596f096f56bb97d Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Tue, 17 Dec 2019 14:46:50 +0000 Subject: [PATCH 01/10] First draft of the SDL2 port. Signed-off-by: Andrea Odetti --- CMakeLists.txt | 1 + source/frontends/ncurses/CMakeLists.txt | 1 + source/frontends/ncurses/bitmaps.cpp | 14 ++ source/frontends/ncurses/main.cpp | 7 +- source/frontends/ncurses/resources.cpp | 12 -- source/frontends/sa2/CMakeLists.txt | 27 +++ source/frontends/sa2/bitmaps.cpp | 71 ++++++++ source/frontends/sa2/main.cpp | 225 ++++++++++++++++++++++++ 8 files changed, 344 insertions(+), 14 deletions(-) create mode 100644 source/frontends/ncurses/bitmaps.cpp create mode 100644 source/frontends/sa2/CMakeLists.txt create mode 100644 source/frontends/sa2/bitmaps.cpp create mode 100644 source/frontends/sa2/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 77c83723..30cdb44c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,4 +21,5 @@ include_directories(source) add_subdirectory(source) add_subdirectory(source/frontends/ncurses) add_subdirectory(source/frontends/qapple) +add_subdirectory(source/frontends/sa2) add_subdirectory(test/TestCPU6502) diff --git a/source/frontends/ncurses/CMakeLists.txt b/source/frontends/ncurses/CMakeLists.txt index ba20dbf4..36cd8056 100644 --- a/source/frontends/ncurses/CMakeLists.txt +++ b/source/frontends/ncurses/CMakeLists.txt @@ -9,6 +9,7 @@ add_executable(applen asciiart.cpp resources.cpp configuration.cpp + bitmaps.cpp ) pkg_search_module(NCURSESW REQUIRED ncursesw) diff --git a/source/frontends/ncurses/bitmaps.cpp b/source/frontends/ncurses/bitmaps.cpp new file mode 100644 index 00000000..5fa0f06d --- /dev/null +++ b/source/frontends/ncurses/bitmaps.cpp @@ -0,0 +1,14 @@ +#include "StdAfx.h" +#include "Log.h" + +HBITMAP LoadBitmap(HINSTANCE hInstance, const std::string & filename) +{ + LogFileOutput("LoadBitmap: not loading resource %s\n", filename.c_str()); + return nullptr; +} + +LONG GetBitmapBits(HBITMAP hbit, LONG cb, LPVOID lpvBits) +{ + memset(lpvBits, 0, cb); + return cb; +} diff --git a/source/frontends/ncurses/main.cpp b/source/frontends/ncurses/main.cpp index 6e17a880..38cc2806 100644 --- a/source/frontends/ncurses/main.cpp +++ b/source/frontends/ncurses/main.cpp @@ -345,8 +345,11 @@ namespace g_CardMgr.GetDisk2CardMgr().Destroy(); ImageDestroy(); - fclose(g_fh); - g_fh = NULL; + if (g_fh) + { + fclose(g_fh); + g_fh = NULL; + } return 0; } diff --git a/source/frontends/ncurses/resources.cpp b/source/frontends/ncurses/resources.cpp index fbc6796a..65d74189 100644 --- a/source/frontends/ncurses/resources.cpp +++ b/source/frontends/ncurses/resources.cpp @@ -36,15 +36,3 @@ HRSRC FindResource(void *, const std::string & filename, const char *) return result; } - -HBITMAP LoadBitmap(HINSTANCE hInstance, const std::string & filename) -{ - LogFileOutput("LoadBitmap: not loading resource %s\n", filename.c_str()); - return nullptr; -} - -LONG GetBitmapBits(HBITMAP hbit, LONG cb, LPVOID lpvBits) -{ - memset(lpvBits, 0, cb); - return cb; -} diff --git a/source/frontends/sa2/CMakeLists.txt b/source/frontends/sa2/CMakeLists.txt new file mode 100644 index 00000000..43ae5b0b --- /dev/null +++ b/source/frontends/sa2/CMakeLists.txt @@ -0,0 +1,27 @@ +include(FindPkgConfig) + +add_executable(sa2 + main.cpp + bitmaps.cpp + ../ncurses/configuration.cpp + ../ncurses/resources.cpp + ) + +find_package(Boost REQUIRED + COMPONENTS program_options + ) + +find_package(SDL2 REQUIRED) + +target_compile_features(sa2 PUBLIC cxx_std_17) + +target_include_directories(sa2 PRIVATE + ${Boost_INCLUDE_DIRS} + ${SDL2_INCLUDE_DIRS} + ) + +target_link_libraries(sa2 PRIVATE + Boost::program_options + ${SDL2_LIBRARIES} + appleii + ) diff --git a/source/frontends/sa2/bitmaps.cpp b/source/frontends/sa2/bitmaps.cpp new file mode 100644 index 00000000..f126bb6c --- /dev/null +++ b/source/frontends/sa2/bitmaps.cpp @@ -0,0 +1,71 @@ +#include +#include +#include + +#include +#include + +struct CBITMAP : public CHANDLE +{ + std::shared_ptr surface; +}; + +std::string getPath(const std::string & resource) +{ + if (resource == "CHARSET40") return "resource/CHARSET4.BMP"; + if (resource == "CHARSET82") return "resource/CHARSET82.bmp"; + if (resource == "CHARSET8M") return "resource/CHARSET8M.bmp"; + if (resource == "CHARSET8C") return "resource/CHARSET8C.bmp"; + + return resource; +} + +HBITMAP LoadBitmap(HINSTANCE hInstance, const std::string & resource) +{ + const std::string path = getPath(resource); + std::shared_ptr surface(SDL_LoadBMP(path.c_str()), SDL_FreeSurface); + if (surface) + { + CBITMAP * bitmap = new CBITMAP; + bitmap->surface = surface; + return bitmap; + } + else + { + std::cerr << "Cannot load: " << resource << " with path: " << path << std::endl; + return nullptr; + } +} + +LONG GetBitmapBits(HBITMAP hbit, LONG cb, LPVOID lpvBits) +{ + const CBITMAP & bitmap = dynamic_cast(*hbit); + + SDL_LockSurface(bitmap.surface.get()); + + const SDL_Surface * surface = bitmap.surface.get(); + + const char * source = static_cast(surface->pixels); + const size_t size = surface->h * surface->w / 8; + const size_t requested = cb; + + const size_t copied = std::min(requested, size); + + char * dest = static_cast(lpvBits); + + for (size_t i = 0; i < copied; ++i) + { + const size_t offset = i * 8; + char val = 0; + for (size_t j = 0; j < 8; ++j) + { + const char pixel = *(source + offset + j); + val = (val << 1) | pixel; + } + dest[i] = val; + } + + SDL_UnlockSurface(bitmap.surface.get()); + + return copied; +} diff --git a/source/frontends/sa2/main.cpp b/source/frontends/sa2/main.cpp new file mode 100644 index 00000000..7f042baf --- /dev/null +++ b/source/frontends/sa2/main.cpp @@ -0,0 +1,225 @@ +#include +#include +#include + +#include "linux/interface.h" +#include "linux/windows/misc.h" +#include "linux/data.h" +#include "frontends/ncurses/configuration.h" + +#include "StdAfx.h" +#include "Common.h" +#include "Applewin.h" +#include "Disk.h" +#include "Harddisk.h" +#include "Log.h" +#include "CPU.h" +#include "Frame.h" +#include "Memory.h" +#include "LanguageCard.h" +#include "MouseInterface.h" +#include "ParallelPrinter.h" +#include "Video.h" +#include "NTSC.h" +#include "SaveState.h" + + +namespace +{ + void initialiseEmulator() + { + g_fh = fopen("/tmp/applewin.txt", "w"); + setbuf(g_fh, nullptr); + + LogFileOutput("Initialisation\n"); + + ImageInitialize(); + g_bFullSpeed = false; + } + + void loadEmulator() + { + LoadConfiguration(); + CheckCpu(); + SetWindowTitle(); + FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES); + ResetDefaultMachineMemTypes(); + + MemInitialize(); + VideoInitialize(); + + sg_Disk2Card.Reset(); + HD_Reset(); + } + + void stopEmulator() + { + sg_Mouse.Uninitialize(); + sg_Mouse.Reset(); + MemDestroy(); + } + + void uninitialiseEmulator() + { + HD_Destroy(); + PrintDestroy(); + CpuDestroy(); + + sg_Disk2Card.Destroy(); + ImageDestroy(); + fclose(g_fh); + g_fh = nullptr; + } + + SDL_Rect refreshTexture(const std::shared_ptr & tex) + { + uint8_t * data; + int width; + int height; + int sx, sy; + int sw, sh; + + getScreenData(data, width, height, sx, sy, sw, sh); + + void * pixels; + int pitch; + SDL_LockTexture(tex.get(), nullptr, &pixels, &pitch); + + memcpy(pixels, data, width * height * 4); + + SDL_UnlockTexture(tex.get()); + + SDL_Rect srect; + srect.x = sx; + srect.y = sy; + srect.w = sw; + srect.h = sh; + + return srect; + } + + void renderScreen(const std::shared_ptr & ren, const std::shared_ptr & tex, const SDL_Rect & srect) + { + SDL_RenderCopyEx(ren.get(), tex.get(), &srect, nullptr, 0.0, nullptr, SDL_FLIP_VERTICAL); + SDL_RenderPresent(ren.get()); + } +} + +int MessageBox(HWND, const char * text, const char * caption, UINT type) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, caption, text, nullptr); + return IDOK; +} + +void FrameDrawDiskLEDS(HDC x) +{ +} + +void FrameDrawDiskStatus(HDC x) +{ +} + +void FrameRefreshStatus(int x, bool) +{ +} + +BYTE SpkrToggle (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles) +{ + return MemReadFloatingBus(uExecutedCycles); +} + +void run_sdl() +{ + InitializeRegistry("applen.conf"); + + initialiseEmulator(); + loadEmulator(); + + const int width = GetFrameBufferWidth(); + const int height = GetFrameBufferHeight(); + const int sx = GetFrameBufferBorderWidth(); + const int sy = GetFrameBufferBorderHeight(); + const int sw = GetFrameBufferBorderlessWidth(); + const int sh = GetFrameBufferBorderlessHeight(); + + std::shared_ptr win(SDL_CreateWindow(g_pAppTitle.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, sw, sh, SDL_WINDOW_SHOWN), SDL_DestroyWindow); + if (!win) + { + std::cerr << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl; + return; + } + + std::shared_ptr ren(SDL_CreateRenderer(win.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), SDL_DestroyRenderer); + if (!ren) + { + std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl; + return; + } + + const Uint32 format = SDL_PIXELFORMAT_BGRA32; + std::shared_ptr tex(SDL_CreateTexture(ren.get(), format, SDL_TEXTUREACCESS_STREAMING, width, height), SDL_DestroyTexture); + + bool quit = false; + do + { + SDL_Event e; + while (SDL_PollEvent(&e) != 0) + { + if (e.type == SDL_QUIT) + { + quit = true; + } + else if (e.type == SDL_KEYDOWN) + { + std::cerr << e.key.keysym.scancode << "," << e.key.keysym.sym << "," << e.key.keysym.mod << "," << bool(e.key.repeat) << ",AAA" << std::endl; + } + } + + const bool bVideoUpdate = true; + DWORD uCyclesToExecute = 1000; + const DWORD uActualCyclesExecuted = CpuExecute(uCyclesToExecute, bVideoUpdate); + g_dwCyclesThisFrame += uActualCyclesExecuted; + + sg_Disk2Card.UpdateDriveState(uActualCyclesExecuted); + + const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame(); + if (g_dwCyclesThisFrame >= dwClksPerFrame) + { + if (g_dwCyclesThisFrame >= dwClksPerFrame) + { + const SDL_Rect srect = refreshTexture(tex); + renderScreen(ren, tex, srect); + } + g_dwCyclesThisFrame -= dwClksPerFrame; + } + } while (!quit); + + stopEmulator(); + uninitialiseEmulator(); +} + +int main(int, char**) +{ + //First we need to start up SDL, and make sure it went ok + if (SDL_Init(SDL_INIT_VIDEO) != 0) + { + std::cerr << "SDL_Init Error: " << SDL_GetError() << std::endl; + return 1; + } + + int exit = 0; + + try + { + run_sdl(); + } + catch (const std::exception & e) + { + exit = 2; + std::cerr << e.what() << std::endl; + } + + SDL_Quit(); + + return exit; +} From e315bade5aa928f01f40214e2587f326c770880b Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Tue, 17 Dec 2019 14:51:41 +0000 Subject: [PATCH 02/10] Fix linker error. Signed-off-by: Andrea Odetti --- source/frontends/sa2/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/frontends/sa2/CMakeLists.txt b/source/frontends/sa2/CMakeLists.txt index 43ae5b0b..17069dd6 100644 --- a/source/frontends/sa2/CMakeLists.txt +++ b/source/frontends/sa2/CMakeLists.txt @@ -25,3 +25,9 @@ target_link_libraries(sa2 PRIVATE ${SDL2_LIBRARIES} appleii ) + +if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0) + target_link_libraries(sa2 PRIVATE + stdc++fs + ) +endif() From 9c21b12176c4e45c714750137f73e048dfb9f06b Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Tue, 17 Dec 2019 15:29:00 +0000 Subject: [PATCH 03/10] Add F9 and Ctrl-F6. Signed-off-by: Andrea Odetti --- source/frontends/sa2/main.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/source/frontends/sa2/main.cpp b/source/frontends/sa2/main.cpp index 7f042baf..5a64d545 100644 --- a/source/frontends/sa2/main.cpp +++ b/source/frontends/sa2/main.cpp @@ -142,6 +142,8 @@ void run_sdl() const int sw = GetFrameBufferBorderlessWidth(); const int sh = GetFrameBufferBorderlessHeight(); + int multiplier = 1; + std::shared_ptr win(SDL_CreateWindow(g_pAppTitle.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, sw, sh, SDL_WINDOW_SHOWN), SDL_DestroyWindow); if (!win) { @@ -171,6 +173,35 @@ void run_sdl() } else if (e.type == SDL_KEYDOWN) { + if (!e.key.repeat) + { + switch (e.key.keysym.scancode) + { + case SDL_SCANCODE_F9: + { + g_eVideoType++; + if (g_eVideoType >= NUM_VIDEO_MODES) + g_eVideoType = 0; + + SetWindowTitle(); + SDL_SetWindowTitle(win.get(), g_pAppTitle.c_str()); + + Config_Save_Video(); + VideoReinitialize(); + VideoRedrawScreen(); + break; + } + case SDL_SCANCODE_F6: + { + if (e.key.keysym.mod & KMOD_CTRL) + { + multiplier = multiplier == 1 ? 2 : 1; + SDL_SetWindowSize(win.get(), sw * multiplier, sh * multiplier); + break; + } + } + } + } std::cerr << e.key.keysym.scancode << "," << e.key.keysym.sym << "," << e.key.keysym.mod << "," << bool(e.key.repeat) << ",AAA" << std::endl; } } From 582b29a545fed1f4154d60588180622e67e1a483 Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Tue, 17 Dec 2019 16:21:54 +0000 Subject: [PATCH 04/10] Add 50% scalines keys. Signed-off-by: Andrea Odetti --- source/frontends/sa2/main.cpp | 49 ++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/source/frontends/sa2/main.cpp b/source/frontends/sa2/main.cpp index 5a64d545..ca4840d9 100644 --- a/source/frontends/sa2/main.cpp +++ b/source/frontends/sa2/main.cpp @@ -103,6 +103,36 @@ namespace SDL_RenderCopyEx(ren.get(), tex.get(), &srect, nullptr, 0.0, nullptr, SDL_FLIP_VERTICAL); SDL_RenderPresent(ren.get()); } + + void cycleVideoType(const std::shared_ptr & win) + { + g_eVideoType++; + if (g_eVideoType >= NUM_VIDEO_MODES) + g_eVideoType = 0; + + SetWindowTitle(); + SDL_SetWindowTitle(win.get(), g_pAppTitle.c_str()); + + Config_Save_Video(); + VideoReinitialize(); + VideoRedrawScreen(); + } + + void cycle50ScanLines(const std::shared_ptr & win) + { + VideoStyle_e videoStyle = GetVideoStyle(); + videoStyle = VideoStyle_e(videoStyle ^ VS_HALF_SCANLINES); + + SetVideoStyle(videoStyle); + + SetWindowTitle(); + SDL_SetWindowTitle(win.get(), g_pAppTitle.c_str()); + + Config_Save_Video(); + VideoReinitialize(); + VideoRedrawScreen(); + } + } int MessageBox(HWND, const char * text, const char * caption, UINT type) @@ -179,26 +209,21 @@ void run_sdl() { case SDL_SCANCODE_F9: { - g_eVideoType++; - if (g_eVideoType >= NUM_VIDEO_MODES) - g_eVideoType = 0; - - SetWindowTitle(); - SDL_SetWindowTitle(win.get(), g_pAppTitle.c_str()); - - Config_Save_Video(); - VideoReinitialize(); - VideoRedrawScreen(); + cycleVideoType(win); break; } case SDL_SCANCODE_F6: { - if (e.key.keysym.mod & KMOD_CTRL) + if ((e.key.keysym.mod & KMOD_CTRL) && (e.key.keysym.mod & KMOD_SHIFT)) + { + cycle50ScanLines(win); + } + else if (e.key.keysym.mod & KMOD_CTRL) { multiplier = multiplier == 1 ? 2 : 1; SDL_SetWindowSize(win.get(), sw * multiplier, sh * multiplier); - break; } + break; } } } From 806a3696240c09ad086c943fc02c4d1144f6ad38 Mon Sep 17 00:00:00 2001 From: "mariofutire@gmail.com" Date: Tue, 6 Oct 2020 20:05:48 +0100 Subject: [PATCH 05/10] WIP SDL2 --- CMakeLists.txt | 16 +++++++++++++--- source/CMakeLists.txt | 3 ++- source/frontends/sa2/main.cpp | 14 +++++++++----- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 30cdb44c..859cdfa3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,9 +12,19 @@ MESSAGE("CMAKE_CXX_FLAGS_RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) -include(CheckIPOSupported) -check_ipo_supported() -set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) +execute_process(COMMAND uname -n + OUTPUT_VARIABLE UNAME + OUTPUT_STRIP_TRAILING_WHITESPACE) + +if(${UNAME} STREQUAL raspberrypi) + # it is too slow and might cause out of memory issues + # more forensic is required + MESSAGE("Raspberry Pi detected: IPO disabled") +else() + include(CheckIPOSupported) + check_ipo_supported() + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE) +endif() include_directories(source) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 32076372..727dda5b 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,6 +1,8 @@ include(FindPkgConfig) add_library(appleii SHARED + linux/data.cpp + SaveState.cpp Pravets.cpp Tape.cpp @@ -36,7 +38,6 @@ add_library(appleii SHARED linux/windows/strings.cpp linux/windows/misc.cpp - linux/data.cpp linux/dummies.cpp linux/state.cpp linux/benchmark.cpp diff --git a/source/frontends/sa2/main.cpp b/source/frontends/sa2/main.cpp index ca4840d9..c16de7a6 100644 --- a/source/frontends/sa2/main.cpp +++ b/source/frontends/sa2/main.cpp @@ -9,6 +9,7 @@ #include "StdAfx.h" #include "Common.h" +#include "CardManager.h" #include "Applewin.h" #include "Disk.h" #include "Harddisk.h" @@ -48,14 +49,17 @@ namespace MemInitialize(); VideoInitialize(); - sg_Disk2Card.Reset(); + g_CardMgr.GetDisk2CardMgr().Reset(); HD_Reset(); } void stopEmulator() { - sg_Mouse.Uninitialize(); - sg_Mouse.Reset(); + CMouseInterface* pMouseCard = g_CardMgr.GetMouseCard(); + if (pMouseCard) + { + pMouseCard->Reset(); + } MemDestroy(); } @@ -65,7 +69,7 @@ namespace PrintDestroy(); CpuDestroy(); - sg_Disk2Card.Destroy(); + g_CardMgr.GetDisk2CardMgr().Destroy(); ImageDestroy(); fclose(g_fh); g_fh = nullptr; @@ -236,7 +240,7 @@ void run_sdl() const DWORD uActualCyclesExecuted = CpuExecute(uCyclesToExecute, bVideoUpdate); g_dwCyclesThisFrame += uActualCyclesExecuted; - sg_Disk2Card.UpdateDriveState(uActualCyclesExecuted); + g_CardMgr.GetDisk2CardMgr().UpdateDriveState(uActualCyclesExecuted); const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame(); if (g_dwCyclesThisFrame >= dwClksPerFrame) From 8b081725cebc760d6b774a9d7f30f8669b42bc4b Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Fri, 9 Oct 2020 09:46:15 +0100 Subject: [PATCH 06/10] More SDL WIP. --- source/CMakeLists.txt | 1 - source/frontends/ncurses/CMakeLists.txt | 1 + source/frontends/ncurses/bitmaps.cpp | 4 ++-- source/frontends/ncurses/resources.cpp | 14 +------------- source/frontends/sa2/CMakeLists.txt | 8 +++----- source/frontends/sa2/bitmaps.cpp | 24 ++++++++++++++++-------- source/frontends/sa2/main.cpp | 11 +++++++++++ 7 files changed, 34 insertions(+), 29 deletions(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 0ae6181c..ba914cf0 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -49,7 +49,6 @@ add_library(appleii SHARED linux/windows/dmusicc.cpp linux/windows/winnls.cpp - linux/data.cpp linux/benchmark.cpp linux/paddle.cpp diff --git a/source/frontends/ncurses/CMakeLists.txt b/source/frontends/ncurses/CMakeLists.txt index f962ac53..9f4330f4 100644 --- a/source/frontends/ncurses/CMakeLists.txt +++ b/source/frontends/ncurses/CMakeLists.txt @@ -24,6 +24,7 @@ target_include_directories(applen PRIVATE ${NCURSESW_INCLUDE_DIRS} ${LIBEVDEV_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR} ) target_compile_options(applen PRIVATE diff --git a/source/frontends/ncurses/bitmaps.cpp b/source/frontends/ncurses/bitmaps.cpp index 5fa0f06d..bf858012 100644 --- a/source/frontends/ncurses/bitmaps.cpp +++ b/source/frontends/ncurses/bitmaps.cpp @@ -1,9 +1,9 @@ #include "StdAfx.h" #include "Log.h" -HBITMAP LoadBitmap(HINSTANCE hInstance, const std::string & filename) +HBITMAP LoadBitmap(HINSTANCE hInstance, const char * filename) { - LogFileOutput("LoadBitmap: not loading resource %s\n", filename.c_str()); + LogFileOutput("LoadBitmap: not loading resource %s\n", filename); return nullptr; } diff --git a/source/frontends/ncurses/resources.cpp b/source/frontends/ncurses/resources.cpp index 92284718..343505b7 100644 --- a/source/frontends/ncurses/resources.cpp +++ b/source/frontends/ncurses/resources.cpp @@ -6,7 +6,7 @@ #include #include "Log.h" -#include "config.h" +#include "../ncurses/config.h" namespace { @@ -84,15 +84,3 @@ HRSRC FindResource(void *, const char * filename, const char *) return result; } - -HBITMAP LoadBitmap(HINSTANCE hInstance, const char * filename) -{ - LogFileOutput("LoadBitmap: not loading resource %s\n", filename); - return nullptr; -} - -LONG GetBitmapBits(HBITMAP hbit, LONG cb, LPVOID lpvBits) -{ - memset(lpvBits, 0, cb); - return cb; -} diff --git a/source/frontends/sa2/CMakeLists.txt b/source/frontends/sa2/CMakeLists.txt index 17069dd6..ce601f7d 100644 --- a/source/frontends/sa2/CMakeLists.txt +++ b/source/frontends/sa2/CMakeLists.txt @@ -18,6 +18,7 @@ target_compile_features(sa2 PUBLIC cxx_std_17) target_include_directories(sa2 PRIVATE ${Boost_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR} ) target_link_libraries(sa2 PRIVATE @@ -26,8 +27,5 @@ target_link_libraries(sa2 PRIVATE appleii ) -if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0) - target_link_libraries(sa2 PRIVATE - stdc++fs - ) -endif() +install(TARGETS sa2 + DESTINATION bin) diff --git a/source/frontends/sa2/bitmaps.cpp b/source/frontends/sa2/bitmaps.cpp index f126bb6c..85352e74 100644 --- a/source/frontends/sa2/bitmaps.cpp +++ b/source/frontends/sa2/bitmaps.cpp @@ -20,19 +20,27 @@ std::string getPath(const std::string & resource) return resource; } -HBITMAP LoadBitmap(HINSTANCE hInstance, const std::string & resource) +HBITMAP LoadBitmap(HINSTANCE hInstance, const char * resource) { - const std::string path = getPath(resource); - std::shared_ptr surface(SDL_LoadBMP(path.c_str()), SDL_FreeSurface); - if (surface) + if (resource) { - CBITMAP * bitmap = new CBITMAP; - bitmap->surface = surface; - return bitmap; + const std::string path = getPath(resource); + std::shared_ptr surface(SDL_LoadBMP(path.c_str()), SDL_FreeSurface); + if (surface) + { + CBITMAP * bitmap = new CBITMAP; + bitmap->surface = surface; + return bitmap; + } + else + { + std::cerr << "Cannot load: " << resource << " with path: " << path << std::endl; + return nullptr; + } } else { - std::cerr << "Cannot load: " << resource << " with path: " << path << std::endl; + std::cerr << "Cannot load invalid resource." << std::endl; return nullptr; } } diff --git a/source/frontends/sa2/main.cpp b/source/frontends/sa2/main.cpp index c16de7a6..16340820 100644 --- a/source/frontends/sa2/main.cpp +++ b/source/frontends/sa2/main.cpp @@ -23,6 +23,7 @@ #include "Video.h" #include "NTSC.h" #include "SaveState.h" +#include "RGBMonitor.h" namespace @@ -48,6 +49,7 @@ namespace MemInitialize(); VideoInitialize(); + VideoSwitchVideocardPalette(RGB_GetVideocard(), GetVideoType()); g_CardMgr.GetDisk2CardMgr().Reset(); HD_Reset(); @@ -283,3 +285,12 @@ int main(int, char**) return exit; } + +// Mockingboard +void registerSoundBuffer(IDirectSoundBuffer * buffer) +{ +} + +void unregisterSoundBuffer(IDirectSoundBuffer * buffer) +{ +} From 697a5b5c88c1087b228bbed08af7abd2bf729175 Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Fri, 9 Oct 2020 10:30:53 +0100 Subject: [PATCH 07/10] Rechange the order of initialisation. Need to find a better solution. Signed-off-by: Andrea Odetti --- source/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index ba914cf0..a794237d 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -28,7 +28,6 @@ add_library(appleii SHARED NTSC_CharSet.cpp CardManager.cpp Disk2CardManager.cpp - SaveState.cpp # uses g_CardMgr in m_ConfigNew (reverse order) Riff.cpp Configuration/PropertySheetHelper.cpp @@ -63,6 +62,7 @@ add_library(appleii SHARED linux/duplicates/SerialComms.cpp linux/duplicates/IPropertySheet.cpp linux/duplicates/Applewin.cpp # defines g_CardMgr (reverse order) + SaveState.cpp # uses g_CardMgr in m_ConfigNew (reverse order) Z80VICE/z80.cpp Z80VICE/z80mem.cpp From 274ef6a796234254f7fffe8249bbd8da8cd830cd Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Fri, 9 Oct 2020 10:31:15 +0100 Subject: [PATCH 08/10] Fix sa2 to work with recent code. Signed-off-by: Andrea Odetti --- source/frontends/ncurses/resources.cpp | 11 ++++++++--- source/frontends/ncurses/resources.h | 3 +++ source/frontends/sa2/bitmaps.cpp | 15 +++++++++------ source/frontends/sa2/main.cpp | 19 ++++++++++--------- 4 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 source/frontends/ncurses/resources.h diff --git a/source/frontends/ncurses/resources.cpp b/source/frontends/ncurses/resources.cpp index 343505b7..2175da74 100644 --- a/source/frontends/ncurses/resources.cpp +++ b/source/frontends/ncurses/resources.cpp @@ -25,7 +25,7 @@ namespace } } - std::string getResourcePath() + std::string getResourcePathImpl() { char self[1024] = {0}; const int ch = readlink("/proc/self/exe", self, sizeof(self)); @@ -51,7 +51,12 @@ namespace return std::string(); } - const std::string resourcePath = getResourcePath(); +} + +const std::string & getResourcePath() +{ + static const std::string path = getResourcePathImpl(); + return path; } HRSRC FindResource(void *, const char * filename, const char *) @@ -60,7 +65,7 @@ HRSRC FindResource(void *, const char * filename, const char *) if (filename) { - const std::string path = resourcePath + filename; + const std::string path = getResourcePath() + filename; int fd = open(path.c_str(), O_RDONLY); diff --git a/source/frontends/ncurses/resources.h b/source/frontends/ncurses/resources.h new file mode 100644 index 00000000..b092e587 --- /dev/null +++ b/source/frontends/ncurses/resources.h @@ -0,0 +1,3 @@ +#include + +const std::string & getResourcePath(); diff --git a/source/frontends/sa2/bitmaps.cpp b/source/frontends/sa2/bitmaps.cpp index 85352e74..408f7670 100644 --- a/source/frontends/sa2/bitmaps.cpp +++ b/source/frontends/sa2/bitmaps.cpp @@ -4,18 +4,19 @@ #include #include +#include struct CBITMAP : public CHANDLE { std::shared_ptr surface; }; -std::string getPath(const std::string & resource) +std::string getFilename(const std::string & resource) { - if (resource == "CHARSET40") return "resource/CHARSET4.BMP"; - if (resource == "CHARSET82") return "resource/CHARSET82.bmp"; - if (resource == "CHARSET8M") return "resource/CHARSET8M.bmp"; - if (resource == "CHARSET8C") return "resource/CHARSET8C.bmp"; + if (resource == "CHARSET40") return "CHARSET4.BMP"; + if (resource == "CHARSET82") return "CHARSET82.bmp"; + if (resource == "CHARSET8M") return "CHARSET8M.bmp"; + if (resource == "CHARSET8C") return "CHARSET8C.bmp"; return resource; } @@ -24,7 +25,9 @@ HBITMAP LoadBitmap(HINSTANCE hInstance, const char * resource) { if (resource) { - const std::string path = getPath(resource); + const std::string filename = getFilename(resource); + const std::string path = getResourcePath() + filename; + std::shared_ptr surface(SDL_LoadBMP(path.c_str()), SDL_FreeSurface); if (surface) { diff --git a/source/frontends/sa2/main.cpp b/source/frontends/sa2/main.cpp index 16340820..167c8b90 100644 --- a/source/frontends/sa2/main.cpp +++ b/source/frontends/sa2/main.cpp @@ -164,6 +164,16 @@ BYTE SpkrToggle (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG uExecutedCycles) return MemReadFloatingBus(uExecutedCycles); } + +// Mockingboard +void registerSoundBuffer(IDirectSoundBuffer * buffer) +{ +} + +void unregisterSoundBuffer(IDirectSoundBuffer * buffer) +{ +} + void run_sdl() { InitializeRegistry("applen.conf"); @@ -285,12 +295,3 @@ int main(int, char**) return exit; } - -// Mockingboard -void registerSoundBuffer(IDirectSoundBuffer * buffer) -{ -} - -void unregisterSoundBuffer(IDirectSoundBuffer * buffer) -{ -} From 01c059873f7000a0f14bc29871009187a10a5302 Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Fri, 9 Oct 2020 11:50:59 +0100 Subject: [PATCH 09/10] Let SDL2 do the refresh sync. Signed-off-by: Andrea Odetti --- source/frontends/sa2/main.cpp | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/source/frontends/sa2/main.cpp b/source/frontends/sa2/main.cpp index 167c8b90..62a607a6 100644 --- a/source/frontends/sa2/main.cpp +++ b/source/frontends/sa2/main.cpp @@ -139,6 +139,20 @@ namespace VideoRedrawScreen(); } + int getFPS() + { + SDL_DisplayMode current; + + int should_be_zero = SDL_GetCurrentDisplayMode(0, ¤t); + + if (should_be_zero) + { + throw std::string(SDL_GetError()); + } + + return current.refresh_rate; + } + } int MessageBox(HWND, const char * text, const char * caption, UINT type) @@ -207,6 +221,10 @@ void run_sdl() const Uint32 format = SDL_PIXELFORMAT_BGRA32; std::shared_ptr tex(SDL_CreateTexture(ren.get(), format, SDL_TEXTUREACCESS_STREAMING, width, height), SDL_DestroyTexture); + const int fps = getFPS(); + const DWORD uCyclesToExecute = int(g_fCurrentCLK6502 / fps); + const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame(); + bool quit = false; do { @@ -248,22 +266,16 @@ void run_sdl() } const bool bVideoUpdate = true; - DWORD uCyclesToExecute = 1000; const DWORD uActualCyclesExecuted = CpuExecute(uCyclesToExecute, bVideoUpdate); g_dwCyclesThisFrame += uActualCyclesExecuted; g_CardMgr.GetDisk2CardMgr().UpdateDriveState(uActualCyclesExecuted); - const UINT dwClksPerFrame = NTSC_GetCyclesPerFrame(); - if (g_dwCyclesThisFrame >= dwClksPerFrame) - { - if (g_dwCyclesThisFrame >= dwClksPerFrame) - { - const SDL_Rect srect = refreshTexture(tex); - renderScreen(ren, tex, srect); - } - g_dwCyclesThisFrame -= dwClksPerFrame; - } + // SDL2 seems to synch with screen refresh rate so we do not need to worry about timers + const SDL_Rect srect = refreshTexture(tex); + renderScreen(ren, tex, srect); + + g_dwCyclesThisFrame = (g_dwCyclesThisFrame + g_dwCyclesThisFrame) % dwClksPerFrame; } while (!quit); stopEmulator(); From 24621373dd557bcaf268650356e24a1b5747f1a8 Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Fri, 9 Oct 2020 19:13:42 +0100 Subject: [PATCH 10/10] Better way to share data between ncurses and sdl2. Signed-off-by: Andrea Odetti --- CMakeLists.txt | 1 + source/frontends/common2/CMakeLists.txt | 29 +++ .../{ncurses => common2}/config.h.in | 0 .../{ncurses => common2}/configuration.cpp | 2 +- .../{ncurses => common2}/configuration.h | 0 source/frontends/common2/programoptions.cpp | 96 ++++++++++ source/frontends/common2/programoptions.h | 20 +++ .../{ncurses => common2}/resources.cpp | 2 +- .../{ncurses => common2}/resources.h | 0 source/frontends/common2/utils.cpp | 63 +++++++ source/frontends/common2/utils.h | 6 + source/frontends/ncurses/CMakeLists.txt | 18 +- source/frontends/ncurses/main.cpp | 166 +----------------- source/frontends/sa2/CMakeLists.txt | 4 +- source/frontends/sa2/bitmaps.cpp | 2 +- source/frontends/sa2/main.cpp | 48 ++++- 16 files changed, 267 insertions(+), 190 deletions(-) create mode 100644 source/frontends/common2/CMakeLists.txt rename source/frontends/{ncurses => common2}/config.h.in (100%) rename source/frontends/{ncurses => common2}/configuration.cpp (98%) rename source/frontends/{ncurses => common2}/configuration.h (100%) create mode 100644 source/frontends/common2/programoptions.cpp create mode 100644 source/frontends/common2/programoptions.h rename source/frontends/{ncurses => common2}/resources.cpp (98%) rename source/frontends/{ncurses => common2}/resources.h (100%) create mode 100644 source/frontends/common2/utils.cpp create mode 100644 source/frontends/common2/utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index bd7ab6ae..442bb30a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ endif() include_directories(source) add_subdirectory(source) +add_subdirectory(source/frontends/common2) add_subdirectory(source/frontends/ncurses) add_subdirectory(source/frontends/qapple) add_subdirectory(source/frontends/sa2) diff --git a/source/frontends/common2/CMakeLists.txt b/source/frontends/common2/CMakeLists.txt new file mode 100644 index 00000000..7431ed5d --- /dev/null +++ b/source/frontends/common2/CMakeLists.txt @@ -0,0 +1,29 @@ +include(GNUInstallDirs) + +add_library(common2 STATIC + resources.cpp + configuration.cpp + programoptions.cpp + utils.cpp + ) + +find_package(Boost REQUIRED + COMPONENTS program_options + ) + +target_include_directories(common2 PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ${Boost_INCLUDE_DIRS} + ) + +target_link_libraries(common2 PRIVATE + Boost::program_options +) + +file(RELATIVE_PATH ROOT_PATH ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}) +file(RELATIVE_PATH SHARE_PATH ${CMAKE_INSTALL_FULL_BINDIR} ${CMAKE_INSTALL_FULL_DATADIR}/applewin) + +configure_file(config.h.in config.h) + +install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource + DESTINATION ${CMAKE_INSTALL_DATADIR}/applewin) diff --git a/source/frontends/ncurses/config.h.in b/source/frontends/common2/config.h.in similarity index 100% rename from source/frontends/ncurses/config.h.in rename to source/frontends/common2/config.h.in diff --git a/source/frontends/ncurses/configuration.cpp b/source/frontends/common2/configuration.cpp similarity index 98% rename from source/frontends/ncurses/configuration.cpp rename to source/frontends/common2/configuration.cpp index 88c4ca60..bbb54d7d 100644 --- a/source/frontends/ncurses/configuration.cpp +++ b/source/frontends/common2/configuration.cpp @@ -1,4 +1,4 @@ -#include "frontends/ncurses/configuration.h" +#include "frontends/common2/configuration.h" #include "Log.h" #include "linux/windows/files.h" diff --git a/source/frontends/ncurses/configuration.h b/source/frontends/common2/configuration.h similarity index 100% rename from source/frontends/ncurses/configuration.h rename to source/frontends/common2/configuration.h diff --git a/source/frontends/common2/programoptions.cpp b/source/frontends/common2/programoptions.cpp new file mode 100644 index 00000000..f63efb51 --- /dev/null +++ b/source/frontends/common2/programoptions.cpp @@ -0,0 +1,96 @@ +#include +#include + +#include "StdAfx.h" +#include "Memory.h" +#include + +namespace po = boost::program_options; + +bool getEmulatorOptions(int argc, const char * argv [], const std::string & version, EmulatorOptions & options) +{ + po::options_description desc("AppleWin " + version); + desc.add_options() + ("help,h", "Print this help message") + ("conf", "Save configuration on exit"); + + po::options_description diskDesc("Disk"); + diskDesc.add_options() + ("d1,1", po::value(), "Mount disk image in first drive") + ("d2,2", po::value(), "Mount disk image in second drive") + ("create,c", "Create missing disks"); + desc.add(diskDesc); + + po::options_description snapshotDesc("Snapshot"); + snapshotDesc.add_options() + ("load-state,ls", po::value(), "Load snapshot from file"); + desc.add(snapshotDesc); + + po::options_description memoryDesc("Memory"); + memoryDesc.add_options() + ("memclear,m", po::value(), "Memory initialization pattern [0..7]"); + desc.add(memoryDesc); + + po::options_description emulatorDesc("Emulator"); + emulatorDesc.add_options() + ("log", "Log to AppleWin.log") + ("headless,hl", "Headless: disable video") + ("ntsc,nt", "NTSC: execute NTSC code") + ("benchmark,b", "Benchmark emulator"); + desc.add(emulatorDesc); + + po::variables_map vm; + try + { + po::store(po::parse_command_line(argc, argv, desc), vm); + + if (vm.count("help")) + { + std::cout << "AppleWin " << version << " edition" << std::endl << std::endl << desc << std::endl; + return false; + } + + options.saveConfigurationOnExit = vm.count("conf"); + + if (vm.count("d1")) + { + options.disk1 = vm["d1"].as(); + } + + if (vm.count("d2")) + { + options.disk2 = vm["d2"].as(); + } + + options.createMissingDisks = vm.count("create") > 0; + + if (vm.count("load-state")) + { + options.snapshot = vm["load-state"].as(); + } + + if (vm.count("memclear")) + { + const int memclear = vm["memclear"].as(); + if (memclear >=0 && memclear < NUM_MIP) + options.memclear = memclear; + } + + options.benchmark = vm.count("benchmark") > 0; + options.headless = vm.count("headless") > 0; + options.log = vm.count("log") > 0; + options.ntsc = vm.count("ntsc") > 0; + + return true; + } + catch (const po::error& e) + { + std::cerr << "ERROR: " << e.what() << std::endl << desc << std::endl; + return false; + } + catch (const std::exception & e) + { + std::cerr << "ERROR: " << e.what() << std::endl; + return false; + } +} diff --git a/source/frontends/common2/programoptions.h b/source/frontends/common2/programoptions.h new file mode 100644 index 00000000..1e167e56 --- /dev/null +++ b/source/frontends/common2/programoptions.h @@ -0,0 +1,20 @@ +#include + + +struct EmulatorOptions +{ + std::string disk1; + std::string disk2; + bool createMissingDisks; + std::string snapshot; + int memclear; + bool log; + bool benchmark; + bool headless; + bool ntsc; + bool saveConfigurationOnExit; + + bool run; // false if options include "-h" +}; + +bool getEmulatorOptions(int argc, const char * argv [], const std::string & version, EmulatorOptions & options); diff --git a/source/frontends/ncurses/resources.cpp b/source/frontends/common2/resources.cpp similarity index 98% rename from source/frontends/ncurses/resources.cpp rename to source/frontends/common2/resources.cpp index 2175da74..a2b7699c 100644 --- a/source/frontends/ncurses/resources.cpp +++ b/source/frontends/common2/resources.cpp @@ -6,7 +6,7 @@ #include #include "Log.h" -#include "../ncurses/config.h" +#include "config.h" namespace { diff --git a/source/frontends/ncurses/resources.h b/source/frontends/common2/resources.h similarity index 100% rename from source/frontends/ncurses/resources.h rename to source/frontends/common2/resources.h diff --git a/source/frontends/common2/utils.cpp b/source/frontends/common2/utils.cpp new file mode 100644 index 00000000..d8d21d7e --- /dev/null +++ b/source/frontends/common2/utils.cpp @@ -0,0 +1,63 @@ +#include + +#include "StdAfx.h" +#include "Common.h" +#include "Applewin.h" +#include "CardManager.h" +#include "Disk.h" +#include "SaveState.h" + +#include +#include + +bool DoDiskInsert(const UINT slot, const int nDrive, const std::string & fileName, const bool createMissingDisk) +{ + std::string strPathName; + + if (fileName.empty()) + { + return false; + } + + if (fileName[0] == '/') + { + // Abs pathname + strPathName = fileName; + } + else + { + // Rel pathname + char szCWD[MAX_PATH] = {0}; + if (!GetCurrentDirectory(sizeof(szCWD), szCWD)) + return false; + + strPathName = szCWD; + strPathName.append("/"); + strPathName.append(fileName); + } + + Disk2InterfaceCard* pDisk2Card = dynamic_cast (g_CardMgr.GetObj(slot)); + ImageError_e Error = pDisk2Card->InsertDisk(nDrive, strPathName.c_str(), IMAGE_USE_FILES_WRITE_PROTECT_STATUS, createMissingDisk); + return Error == eIMAGE_ERROR_NONE; +} + +void setSnapshotFilename(const std::string & filename) +{ + // same logic as qapple + // setting chdir allows to load relative disks from the snapshot file (tests?) + // but if the snapshot file itself is relative, it wont work after a chdir + // so we convert to absolute first + char * absPath = realpath(filename.c_str(), nullptr); + if (absPath) + { + char * temp = strdup(absPath); + const char * dir = dirname(temp); + // dir points inside temp! + chdir(dir); + Snapshot_SetFilename(absPath); + + free(temp); + free(absPath); + Snapshot_LoadState(); + } +} diff --git a/source/frontends/common2/utils.h b/source/frontends/common2/utils.h new file mode 100644 index 00000000..30fbf397 --- /dev/null +++ b/source/frontends/common2/utils.h @@ -0,0 +1,6 @@ +#include +#include + +bool DoDiskInsert(const UINT slot, const int nDrive, const std::string & fileName, const bool createMissingDisk); + +void setSnapshotFilename(const std::string & filename); diff --git a/source/frontends/ncurses/CMakeLists.txt b/source/frontends/ncurses/CMakeLists.txt index 9f4330f4..ac8fa424 100644 --- a/source/frontends/ncurses/CMakeLists.txt +++ b/source/frontends/ncurses/CMakeLists.txt @@ -1,5 +1,4 @@ include(FindPkgConfig) -include(GNUInstallDirs) add_executable(applen main.cpp @@ -8,23 +7,16 @@ add_executable(applen evdevpaddle.cpp nframe.cpp asciiart.cpp - resources.cpp - configuration.cpp bitmaps.cpp ) pkg_search_module(NCURSESW REQUIRED ncursesw) pkg_search_module(LIBEVDEV REQUIRED libevdev) -find_package(Boost REQUIRED - COMPONENTS program_options - ) target_include_directories(applen PRIVATE - ${CMAKE_CURRENT_BINARY_DIR} ${NCURSESW_INCLUDE_DIRS} ${LIBEVDEV_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} - ${CMAKE_CURRENT_BINARY_DIR} ) target_compile_options(applen PRIVATE @@ -35,17 +27,9 @@ target_compile_options(applen PRIVATE target_link_libraries(applen PRIVATE ${NCURSESW_LIBRARIES} ${LIBEVDEV_LIBRARIES} - Boost::program_options appleii + common2 ) -file(RELATIVE_PATH ROOT_PATH ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}) -file(RELATIVE_PATH SHARE_PATH ${CMAKE_INSTALL_FULL_BINDIR} ${CMAKE_INSTALL_FULL_DATADIR}/applewin) - -configure_file(config.h.in config.h) - install(TARGETS applen DESTINATION bin) - -install(DIRECTORY ${CMAKE_SOURCE_DIR}/resource - DESTINATION ${CMAKE_INSTALL_DATADIR}/applewin) diff --git a/source/frontends/ncurses/main.cpp b/source/frontends/ncurses/main.cpp index ea731f17..af987d6b 100644 --- a/source/frontends/ncurses/main.cpp +++ b/source/frontends/ncurses/main.cpp @@ -4,9 +4,6 @@ #include #include #include -#include - -#include #include "Common.h" #include "CardManager.h" @@ -27,116 +24,13 @@ #include "linux/data.h" #include "linux/benchmark.h" -#include "frontends/ncurses/configuration.h" +#include "frontends/common2/configuration.h" +#include "frontends/common2/programoptions.h" +#include "frontends/common2/utils.h" #include "frontends/ncurses/world.h" namespace { - namespace po = boost::program_options; - - struct EmulatorOptions - { - std::string disk1; - std::string disk2; - bool createMissingDisks; - std::string snapshot; - int memclear; - bool log; - bool benchmark; - bool headless; - bool ntsc; - bool saveConfigurationOnExit; - - bool run; // false if options include "-h" - }; - - bool getEmulatorOptions(int argc, const char * argv [], EmulatorOptions & options) - { - po::options_description desc("AppleWin ncurses"); - desc.add_options() - ("help,h", "Print this help message") - ("conf", "Save configuration on exit"); - - po::options_description diskDesc("Disk"); - diskDesc.add_options() - ("d1,1", po::value(), "Mount disk image in first drive") - ("d2,2", po::value(), "Mount disk image in second drive") - ("create,c", "Create missing disks"); - desc.add(diskDesc); - - po::options_description snapshotDesc("Snapshot"); - snapshotDesc.add_options() - ("load-state,ls", po::value(), "Load snapshot from file"); - desc.add(snapshotDesc); - - po::options_description memoryDesc("Memory"); - memoryDesc.add_options() - ("memclear,m", po::value(), "Memory initialization pattern [0..7]"); - desc.add(memoryDesc); - - po::options_description emulatorDesc("Emulator"); - emulatorDesc.add_options() - ("log", "Log to AppleWin.log") - ("headless,hl", "Headless: disable video") - ("ntsc,nt", "NTSC: execute NTSC code") - ("benchmark,b", "Benchmark emulator"); - desc.add(emulatorDesc); - - po::variables_map vm; - try - { - po::store(po::parse_command_line(argc, argv, desc), vm); - - if (vm.count("help")) - { - std::cout << "AppleWin ncurses edition" << std::endl << std::endl << desc << std::endl; - return false; - } - - options.saveConfigurationOnExit = vm.count("conf"); - - if (vm.count("d1")) - { - options.disk1 = vm["d1"].as(); - } - - if (vm.count("d2")) - { - options.disk2 = vm["d2"].as(); - } - - options.createMissingDisks = vm.count("create") > 0; - - if (vm.count("load-state")) - { - options.snapshot = vm["load-state"].as(); - } - - if (vm.count("memclear")) - { - const int memclear = vm["memclear"].as(); - if (memclear >=0 && memclear < NUM_MIP) - options.memclear = memclear; - } - - options.benchmark = vm.count("benchmark") > 0; - options.headless = vm.count("headless") > 0; - options.log = vm.count("log") > 0; - options.ntsc = vm.count("ntsc") > 0; - - return true; - } - catch (const po::error& e) - { - std::cerr << "ERROR: " << e.what() << std::endl << desc << std::endl; - return false; - } - catch (const std::exception & e) - { - std::cerr << "ERROR: " << e.what() << std::endl; - return false; - } - } bool ContinueExecution(const EmulatorOptions & options) { @@ -229,63 +123,11 @@ namespace } } - bool DoDiskInsert(const UINT slot, const int nDrive, const std::string & fileName, const bool createMissingDisk) - { - std::string strPathName; - - if (fileName.empty()) - { - return false; - } - - if (fileName[0] == '/') - { - // Abs pathname - strPathName = fileName; - } - else - { - // Rel pathname - char szCWD[MAX_PATH] = {0}; - if (!GetCurrentDirectory(sizeof(szCWD), szCWD)) - return false; - - strPathName = szCWD; - strPathName.append("/"); - strPathName.append(fileName); - } - - Disk2InterfaceCard* pDisk2Card = dynamic_cast (g_CardMgr.GetObj(slot)); - ImageError_e Error = pDisk2Card->InsertDisk(nDrive, strPathName.c_str(), IMAGE_USE_FILES_WRITE_PROTECT_STATUS, createMissingDisk); - return Error == eIMAGE_ERROR_NONE; - } - - void setSnapshotFilename(const std::string & filename) - { - // same logic as qapple - // setting chdir allows to load relative disks from the snapshot file (tests?) - // but if the snapshot file itself is relative, it wont work after a chdir - // so we convert to absolute first - char * absPath = realpath(filename.c_str(), nullptr); - if (absPath) - { - char * temp = strdup(absPath); - const char * dir = dirname(temp); - // dir points inside temp! - chdir(dir); - Snapshot_SetFilename(absPath); - - free(temp); - free(absPath); - Snapshot_LoadState(); - } - } - int foo(int argc, const char * argv []) { EmulatorOptions options; options.memclear = g_nMemoryClearType; - const bool run = getEmulatorOptions(argc, argv, options); + const bool run = getEmulatorOptions(argc, argv, "ncurses", options); if (!run) return 1; diff --git a/source/frontends/sa2/CMakeLists.txt b/source/frontends/sa2/CMakeLists.txt index ce601f7d..5a85e99c 100644 --- a/source/frontends/sa2/CMakeLists.txt +++ b/source/frontends/sa2/CMakeLists.txt @@ -3,8 +3,6 @@ include(FindPkgConfig) add_executable(sa2 main.cpp bitmaps.cpp - ../ncurses/configuration.cpp - ../ncurses/resources.cpp ) find_package(Boost REQUIRED @@ -18,13 +16,13 @@ target_compile_features(sa2 PUBLIC cxx_std_17) target_include_directories(sa2 PRIVATE ${Boost_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS} - ${CMAKE_CURRENT_BINARY_DIR} ) target_link_libraries(sa2 PRIVATE Boost::program_options ${SDL2_LIBRARIES} appleii + common2 ) install(TARGETS sa2 diff --git a/source/frontends/sa2/bitmaps.cpp b/source/frontends/sa2/bitmaps.cpp index 408f7670..be6b3f14 100644 --- a/source/frontends/sa2/bitmaps.cpp +++ b/source/frontends/sa2/bitmaps.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include struct CBITMAP : public CHANDLE { diff --git a/source/frontends/sa2/main.cpp b/source/frontends/sa2/main.cpp index 62a607a6..d46a4ef6 100644 --- a/source/frontends/sa2/main.cpp +++ b/source/frontends/sa2/main.cpp @@ -5,7 +5,9 @@ #include "linux/interface.h" #include "linux/windows/misc.h" #include "linux/data.h" -#include "frontends/ncurses/configuration.h" +#include "frontends/common2/configuration.h" +#include "frontends/common2/utils.h" +#include "frontends/common2/programoptions.h" #include "StdAfx.h" #include "Common.h" @@ -30,6 +32,8 @@ namespace { void initialiseEmulator() { + InitializeRegistry("applen.conf"); + g_fh = fopen("/tmp/applewin.txt", "w"); setbuf(g_fh, nullptr); @@ -55,6 +59,35 @@ namespace HD_Reset(); } + void applyOptions(const EmulatorOptions & options) + { + if (options.log) + { + LogInit(); + } + + bool disksOk = true; + if (!options.disk1.empty()) + { + const bool ok = DoDiskInsert(SLOT6, DRIVE_1, options.disk1, options.createMissingDisks); + disksOk = disksOk && ok; + LogFileOutput("Init: DoDiskInsert(D1), res=%d\n", ok); + } + + if (!options.disk2.empty()) + { + const bool ok = DoDiskInsert(SLOT6, DRIVE_2, options.disk2, options.createMissingDisks); + disksOk = disksOk && ok; + LogFileOutput("Init: DoDiskInsert(D2), res=%d\n", ok); + } + + if (!options.snapshot.empty()) + { + setSnapshotFilename(options.snapshot); + } + + } + void stopEmulator() { CMouseInterface* pMouseCard = g_CardMgr.GetMouseCard(); @@ -188,9 +221,14 @@ void unregisterSoundBuffer(IDirectSoundBuffer * buffer) { } -void run_sdl() +void run_sdl(int argc, const char * argv []) { - InitializeRegistry("applen.conf"); + EmulatorOptions options; + options.memclear = g_nMemoryClearType; + const bool run = getEmulatorOptions(argc, argv, "SDL2", options); + + if (!run) + return; initialiseEmulator(); loadEmulator(); @@ -282,7 +320,7 @@ void run_sdl() uninitialiseEmulator(); } -int main(int, char**) +int main(int argc, const char * argv []) { //First we need to start up SDL, and make sure it went ok if (SDL_Init(SDL_INIT_VIDEO) != 0) @@ -295,7 +333,7 @@ int main(int, char**) try { - run_sdl(); + run_sdl(argc, argv); } catch (const std::exception & e) {