From b0a0342cf25d46f8b4edc58eb3addbb57f3f5943 Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Wed, 15 Apr 2020 13:50:07 +0100 Subject: [PATCH 01/15] why is required to update the badge url? :finnadie: --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index da5010d5..5b4a9407 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ | Windows (x86, x64) | |---------| -|![![Build status](https://ci.appveyor.com/api/projects/status/67mildjynhnlekk5/branch/master?svg=true)](https://ci.appveyor.com/project/Raffaello/sdl2-vga-terminal/branch/master)| +|[![Build status](https://ci.appveyor.com/api/projects/status/67mildjynhnlekk5/branch/master?svg=true)](https://ci.appveyor.com/project/Raffaello/sdl2-vga-terminal/branch/master)| It is just a VGA font terminal using SDL2. From 2d4f570b1eb132d69487a4d3e186c19e624af84d Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Thu, 16 Apr 2020 12:39:08 +0100 Subject: [PATCH 02/15] Codacy review (#10) * readme lints * update readme * fix remove sdl timer * fixed codacy issues * Update README.md --- README.md | 40 +++++++++---------- sdl2-vga-terminal/CMakeLists.txt | 1 + sdl2-vga-terminal/sdl2-vga-terminal-load-so.c | 24 ++++++++--- sdl2-vga-terminal/sdl2-vga-terminal-so.c | 2 +- sdl2-vga-terminal/src/VgaTerminal.cpp | 13 +++--- sdl2-vga-terminal/src/VgaTerminal.hpp | 5 ++- sdl2-vga-terminal/test/tests.cpp | 1 - 7 files changed, 50 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 5b4a9407..7cb1f11f 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ It is just a VGA font terminal using SDL2. -the VGA fonts are related to a `vgabios` project (http://savannah.nongnu.org/projects/vgabios/). +the VGA fonts are related to [vgabios](http://savannah.nongnu.org/projects/vgabios/) project. At the moment support only mode 3. @@ -16,7 +16,6 @@ It should be on 16 colors in the classic way, but can support more thanks to SDL It is just a matter of fonts and a terminal grid for displaying texts. - ## Compiling Use `vcpkg` and install `SDL2`. @@ -28,15 +27,12 @@ SDL2 Video sub-system has to be initialized before using `VgaTerminal` class. for extended ASCII chars to use as literal (eg: char 205), it is required to save the source code with the codepage 437 encoding (OEM United States / Extended ASCII / DOS Terminal). - -There is a demo usage as part of this cmake compilation too. - +There are few examples usage as part of this cmake compilation too. ## Screenshot This screenshot is also used in the snapshot test. - ![alt text](./sdl2-vga-terminal/test/snapshot/VgaTerminal.Snapshot.png "Title") ## Testing @@ -49,25 +45,25 @@ It could be a little bit risky, but it is a way to have generated expected resul The test suite take advantages of the option and will be compiled accordingly based on "dumping" or "testing". -please note if you are dumping the snapshot, you have to copy back to the `test/snapshot` directory to make the usable. +please note if you are dumping the snapshot, you have to copy back to the `test/snapshot` directory to make them usable. The filename generated are based on the test that are running, ideally: `[Test-suite.Test-name].png` -but doesn't really matter can be used any name, it all depends how the test is written of course. +Just as a convention. ## TODO -Some must and ides: - -- clear with bgCol, and only viewport. -- complete the cursor functionality (When typing show the cursor not blinking (reset timer?) -- CI with Azure Devops, travis, appveyor, sonarcloud lgtm, etc... -- decouple vga modes -- DAC Palette changing -- Cursor display -- doxygen / document the code -- use streams -- read -- unicode VGA font - -- some functions can be optimized using SDL_Surface functions/SDL functions +Some must and ideas: + +- move the examples in `examples` folder? +- clear with bgCol, and only viewport. +- complete the cursor functionality (When typing show the cursor not blinking (reset timer?) +- CI with Azure Devops, travis, appveyor, sonarcloud lgtm, etc... +- decouple vga modes +- DAC Palette changing +- Cursor display +- doxygen / document the code +- use streams +- read +- unicode VGA font +- some functions can be optimized using SDL_Surface functions/SDL functions diff --git a/sdl2-vga-terminal/CMakeLists.txt b/sdl2-vga-terminal/CMakeLists.txt index b2986dcd..237c7111 100644 --- a/sdl2-vga-terminal/CMakeLists.txt +++ b/sdl2-vga-terminal/CMakeLists.txt @@ -1,6 +1,7 @@ ο»Ώcmake_minimum_required (VERSION 3.8) set (CMAKE_CXX_STANDARD 17) +set (CMAKE_C_STANDARD 11) set (CMAKE_DEBUG_POSTFIX d) find_package(SDL2 CONFIG REQUIRED) diff --git a/sdl2-vga-terminal/sdl2-vga-terminal-load-so.c b/sdl2-vga-terminal/sdl2-vga-terminal-load-so.c index f6a2bd55..d6f52fd8 100644 --- a/sdl2-vga-terminal/sdl2-vga-terminal-load-so.c +++ b/sdl2-vga-terminal/sdl2-vga-terminal-load-so.c @@ -10,7 +10,9 @@ typedef void VGA_Terminal; #ifdef WIN32 + #include + typedef void(__cdecl* PROCWRITEXY)(VGA_Terminal*, uint8_t, uint8_t, char* str, uint8_t, uint8_t); typedef void(__cdecl* PROCDESTROY)(VGA_Terminal*); typedef void(__cdecl* PROCRENDER)(VGA_Terminal*); @@ -18,28 +20,36 @@ typedef VGA_Terminal* (__cdecl* PROCINIT)(); #endif #ifdef linux + #include + #endif #if defined(DEBUG) || !defined(NDBEBUG) + #define VGA_SO_NAME "vga-terminal-libd" + #else + #define VGA_SO_NAME "vga-terminal-lib" + #endif #ifdef WIN32 + void win32() { - const char* soname = VGA_SO_NAME ".dll"; + const char* soname = TEXT(VGA_SO_NAME ".dll"); HINSTANCE hinstLib; PROCINIT ProcAddInit = NULL; PROCDESTROY ProcAddDestroy = NULL; PROCWRITEXY ProcAddWriteXY = NULL; PROCRENDER ProcAddRender = NULL; BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; + printf("loading library: %s\n", soname); - hinstLib = LoadLibrary(TEXT("vga-terminal-libd.dll")); + hinstLib = LoadLibrary(soname); if (hinstLib != NULL) { ProcAddInit = (PROCINIT)GetProcAddress(hinstLib, "VGA_TERMINAL_init"); @@ -59,9 +69,14 @@ void win32() ProcAddDestroy(term); } // Free the DLL module. - fFreeResult = FreeLibrary(hinstLib); - } + if (!fFreeResult) { + fprintf(stderr, "unable to unload library\n"); + } + else { + printf("library unloaded.\n"); + } + } // If unable to call the DLL function, use an alternative. if (!fRunTimeLinkSuccess) { @@ -69,7 +84,6 @@ void win32() fprintf(stderr, "failed to load the DLL. Error %d\n", dw); } - } #endif diff --git a/sdl2-vga-terminal/sdl2-vga-terminal-so.c b/sdl2-vga-terminal/sdl2-vga-terminal-so.c index a46f6225..7a63e408 100644 --- a/sdl2-vga-terminal/sdl2-vga-terminal-so.c +++ b/sdl2-vga-terminal/sdl2-vga-terminal-so.c @@ -30,7 +30,7 @@ int main(int argc, char* args[]) while (quit--) { VGA_TERMINAL_render(term); SDL_Delay(1000); - } + }; VGA_TERMINAL_destroy(term); diff --git a/sdl2-vga-terminal/src/VgaTerminal.cpp b/sdl2-vga-terminal/src/VgaTerminal.cpp index 768586f8..f5c7b452 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.cpp +++ b/sdl2-vga-terminal/src/VgaTerminal.cpp @@ -32,8 +32,8 @@ bool VgaTerminal::terminalChar_t::operator==(const terminalChar_t& o) const VgaTerminal::~VgaTerminal() { - if (_cursorTimer != 0) { - SDL_RemoveTimer(_cursorTimer); + if (_timerId != 0) { + SDL_RemoveTimer(_timerId); } } @@ -45,9 +45,11 @@ VgaTerminal::VgaTerminal(const std::string &title, const int winFlags, const int VgaTerminal::VgaTerminal(const std::string &title, const int width, const int height, const int winFlags, const int drvIndex, const int renFlags) : Window(title, width, height, winFlags, drvIndex, renFlags), - _viewPortWidth(mode3.tw), _viewPortHeight(mode3.th), _viewPortX(0), _viewPortY(0) + _viewPortX(0), _viewPortY(0) { mode = mode3; + _viewPortWidth = mode.tw, _viewPortHeight = mode.th; + if (SDL_RenderSetLogicalSize(getRenderer(), mode.tw * mode.cw, mode.th * mode.ch) < 0) { throw std::runtime_error("unable to set logical rendering"); } @@ -69,7 +71,8 @@ VgaTerminal::VgaTerminal(const std::string &title, const int width, const int he } if((SDL_WasInit(SDL_INIT_TIMER) == SDL_INIT_TIMER) && (SDL_WasInit(SDL_INIT_EVENTS) == SDL_INIT_EVENTS)) { - if (SDL_AddTimer(cursor_time, _timerCallBack, this) == 0) { + _timerId = SDL_AddTimer(cursor_time, _timerCallBack, this); + if (_timerId == 0) { SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "[%s] %s: unable to install cursor callback.", typeid(*this).name(), __func__); } } @@ -348,7 +351,7 @@ uint32_t VgaTerminal::_timerCallBack(uint32_t interval, void* param) { SDL_Event event; SDL_UserEvent userevent; - VgaTerminal* that = (VgaTerminal*)param; + VgaTerminal* that = reinterpret_cast(param); that->_cursonOn = !that->_cursonOn; userevent.type = SDL_USEREVENT; diff --git a/sdl2-vga-terminal/src/VgaTerminal.hpp b/sdl2-vga-terminal/src/VgaTerminal.hpp index ced43c0e..0823f63b 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.hpp +++ b/sdl2-vga-terminal/src/VgaTerminal.hpp @@ -23,7 +23,7 @@ class VgaTerminal : public Window uint8_t* font; int numColors; uint8_t* palette; // BGR palette assumed (might be required a palette format flag?) - } videoMode_t; + }; // TODO keep only the 3 uint8_t here, // create a private one that embed this one and the other 2 bools. @@ -92,7 +92,8 @@ class VgaTerminal : public Window // these should be parameters? uint8_t cur_shape = 219; uint32_t cursor_time = 1000; - + + uint32_t _timerId = 0; static uint32_t _timerCallBack(uint32_t interval, void* param); void incrementCursorPosition() noexcept; diff --git a/sdl2-vga-terminal/test/tests.cpp b/sdl2-vga-terminal/test/tests.cpp index d4fd7007..dd25123d 100644 --- a/sdl2-vga-terminal/test/tests.cpp +++ b/sdl2-vga-terminal/test/tests.cpp @@ -130,7 +130,6 @@ TEST(VgaTerminal, SetViewport2) std::string termTitle = "Hello Test"; VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); - auto r = term.getViewport(); term.setViewPort(10, 10, 10, 10); auto e = term.getViewport(); EXPECT_EQ(10, e.x); From 19823ac131422a84e255e9d2abdb0a3626552b46 Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Thu, 16 Apr 2020 12:44:30 +0100 Subject: [PATCH 03/15] review codacy unused var --- sdl2-vga-terminal/src/VgaTerminal.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdl2-vga-terminal/src/VgaTerminal.hpp b/sdl2-vga-terminal/src/VgaTerminal.hpp index 0823f63b..ded69459 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.hpp +++ b/sdl2-vga-terminal/src/VgaTerminal.hpp @@ -10,7 +10,7 @@ class VgaTerminal : public Window { public: - typedef struct videoMode_t + typedef struct { uint8_t mode; // video mode (only mode 3 available at the moment) //uint16_t sw; // screen width @@ -23,7 +23,7 @@ class VgaTerminal : public Window uint8_t* font; int numColors; uint8_t* palette; // BGR palette assumed (might be required a palette format flag?) - }; + } videoMode_t; // TODO keep only the 3 uint8_t here, // create a private one that embed this one and the other 2 bools. From 244f0c8e203b7537a31f8bc26d9127ad25101cda Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Thu, 16 Apr 2020 12:45:14 +0100 Subject: [PATCH 04/15] review codacy unused var --- sdl2-vga-terminal/test/tests.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sdl2-vga-terminal/test/tests.cpp b/sdl2-vga-terminal/test/tests.cpp index dd25123d..d6d9efd2 100644 --- a/sdl2-vga-terminal/test/tests.cpp +++ b/sdl2-vga-terminal/test/tests.cpp @@ -108,7 +108,6 @@ TEST(VgaTerminal, SetViewport1) std::string termTitle = "Hello Test"; VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); - auto r = term.getViewport(); term.setViewPort(0, 0, 1, 1); auto e = term.getViewport(); EXPECT_EQ(0, e.x); From 07fd640c6d233ef82c6362bf3330e8323c986a59 Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Thu, 16 Apr 2020 16:37:07 +0100 Subject: [PATCH 05/15] Cherry picks (#12) * refacto cmake tests file * uinittest update * .. * Rename README.md to Readme.md --- README.md => Readme.md | 0 sdl2-vga-terminal/src/VgaTerminal.cpp | 2 +- sdl2-vga-terminal/src/Window.cpp | 2 +- sdl2-vga-terminal/test/CMakeLists.txt | 33 ++++++++++-------------- sdl2-vga-terminal/test/tests.cpp | 37 ++++++++++++++++++--------- 5 files changed, 41 insertions(+), 33 deletions(-) rename README.md => Readme.md (100%) diff --git a/README.md b/Readme.md similarity index 100% rename from README.md rename to Readme.md diff --git a/sdl2-vga-terminal/src/VgaTerminal.cpp b/sdl2-vga-terminal/src/VgaTerminal.cpp index f5c7b452..499bb652 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.cpp +++ b/sdl2-vga-terminal/src/VgaTerminal.cpp @@ -51,7 +51,7 @@ VgaTerminal::VgaTerminal(const std::string &title, const int width, const int he _viewPortWidth = mode.tw, _viewPortHeight = mode.th; if (SDL_RenderSetLogicalSize(getRenderer(), mode.tw * mode.cw, mode.th * mode.ch) < 0) { - throw std::runtime_error("unable to set logical rendering"); + throw std::runtime_error(std::string("unable to set logical rendering. Error: ") + SDL_GetError()); } p.ncolors = mode.numColors; diff --git a/sdl2-vga-terminal/src/Window.cpp b/sdl2-vga-terminal/src/Window.cpp index bc9047ba..a782a2da 100644 --- a/sdl2-vga-terminal/src/Window.cpp +++ b/sdl2-vga-terminal/src/Window.cpp @@ -4,7 +4,7 @@ Window::Window(const std::string &title, const int width, const int height, const int winFlags, const int drvIndex, const int renFlags) { if (SDL_WasInit(SDL_INIT_VIDEO) != SDL_INIT_VIDEO) { - throw std::runtime_error("video wasn't inited"); + throw std::runtime_error(std::string("video wasn't inited. Error: ") + SDL_GetError()); } if ((winFlags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { diff --git a/sdl2-vga-terminal/test/CMakeLists.txt b/sdl2-vga-terminal/test/CMakeLists.txt index cc922ca0..ce52bb0d 100644 --- a/sdl2-vga-terminal/test/CMakeLists.txt +++ b/sdl2-vga-terminal/test/CMakeLists.txt @@ -1,41 +1,36 @@ cmake_minimum_required (VERSION 3.8) -find_package(GTest CONFIG REQUIRED) -find_package(sdl2-image CONFIG REQUIRED) - option(TEST_DUMP_SNAPSHOT "running test dumping the expected output instead of verifing it" OFF) option(WITH_SNAPSHOT "running snapshot test" OFF) -add_executable(runUnitTests "tests.cpp") +find_package(GTest CONFIG REQUIRED) if (TEST_DUMP_SNAPSHOT) set (WITH_SNAPSHOT bool ON) add_compile_definitions(TEST_DUMP_SNAPSHOT) else() + add_executable(runUnitTests "tests.cpp") add_test(UnitTestsInMain runUnitTests) + target_link_libraries(runUnitTests PRIVATE vga-terminal GTest::gtest GTest::gmock) + add_custom_command(TARGET runUnitTests POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + ) endif() -target_link_libraries(runUnitTests PRIVATE vga-terminal GTest::gtest GTest::gmock) - -add_custom_command(TARGET runUnitTests POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ -) - - if (WITH_SNAPSHOT) + find_package(SDL2-image CONFIG REQUIRED) + add_executable(runSnapshotTests "snapshotTest.cpp") + target_link_libraries(runSnapshotTests PRIVATE vga-terminal GTest::gtest SDL2::SDL2_image) add_test(SnapshotTestsInMain runSnapshotTests) - add_custom_command(TARGET runUnitTests POST_BUILD - # COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ - # COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ - # COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/snapshot $/snapshot ) - - target_link_libraries(runSnapshotTests PRIVATE vga-terminal GTest::gtest SDL2::SDL2_image) endif() diff --git a/sdl2-vga-terminal/test/tests.cpp b/sdl2-vga-terminal/test/tests.cpp index d6d9efd2..0ea26a53 100644 --- a/sdl2-vga-terminal/test/tests.cpp +++ b/sdl2-vga-terminal/test/tests.cpp @@ -9,7 +9,9 @@ TEST(VgaTerminal, CannotInit) { } TEST(VgaTerminal, HelloWorld_Window) { - SDL_Init(SDL_INIT_VIDEO); + SDL_SetMainReady(); // Not required, but for CI test. + ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO)); + std::string termTitle = "Hello Test"; VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); @@ -20,7 +22,8 @@ TEST(VgaTerminal, HelloWorld_Window) { } TEST(VgaTerminal, HelloWorld_Text) { - SDL_Init(SDL_INIT_VIDEO); + ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO)); + std::string termTitle = "Hello Test"; VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); @@ -34,7 +37,8 @@ TEST(VgaTerminal, HelloWorld_Text) { } TEST(VgaTerminal, ScrollDown) { - SDL_Init(SDL_INIT_VIDEO); + ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO)); + std::string termTitle = "Hello Test"; VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); @@ -53,7 +57,8 @@ TEST(VgaTerminal, SetViewportNull) using ::testing::StartsWith; using ::testing::EndsWith; - SDL_Init(SDL_INIT_VIDEO); + ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO)); + std::string termTitle = "Hello Test"; VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); @@ -104,7 +109,8 @@ TEST(VgaTerminal, SetViewportNull) TEST(VgaTerminal, SetViewport1) { - SDL_Init(SDL_INIT_VIDEO); + ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO)); + std::string termTitle = "Hello Test"; VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); @@ -125,7 +131,8 @@ TEST(VgaTerminal, SetViewport1) TEST(VgaTerminal, SetViewport2) { - SDL_Init(SDL_INIT_VIDEO); + ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO)); + std::string termTitle = "Hello Test"; VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); @@ -145,8 +152,10 @@ TEST(VgaTerminal, SetViewport2) SDL_Quit(); } -TEST(VgaTerminal, moveCursorCircle) { - SDL_Init(SDL_INIT_VIDEO); +TEST(VgaTerminal, moveCursorCircle) +{ + ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO)); + std::string termTitle = "Hello Test"; VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); @@ -166,8 +175,10 @@ TEST(VgaTerminal, moveCursorCircle) { SDL_Quit(); } -TEST(VgaTerminal, moveCursorBorder) { - SDL_Init(SDL_INIT_VIDEO); +TEST(VgaTerminal, moveCursorBorder) +{ + ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO)); + std::string termTitle = "Hello Test"; VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); @@ -187,8 +198,10 @@ TEST(VgaTerminal, moveCursorBorder) { SDL_Quit(); } -TEST(VgaTerminal, ViewportMoveCursorBorder) { - SDL_Init(SDL_INIT_VIDEO); +TEST(VgaTerminal, ViewportMoveCursorBorder) +{ + ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO)); + std::string termTitle = "Hello Test"; VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); term.setViewPort(10, 10, 10, 10); From adea14bbf75c4c8c550c3a3bc49a229bf793eadb Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Fri, 17 Apr 2020 09:15:59 +0100 Subject: [PATCH 06/15] renamed tests --- sdl2-vga-terminal/test/tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdl2-vga-terminal/test/tests.cpp b/sdl2-vga-terminal/test/tests.cpp index 0ea26a53..d0e3496e 100644 --- a/sdl2-vga-terminal/test/tests.cpp +++ b/sdl2-vga-terminal/test/tests.cpp @@ -8,7 +8,7 @@ TEST(VgaTerminal, CannotInit) { ASSERT_THROW(VgaTerminal term = VgaTerminal("", 0, -1, 0), std::runtime_error); } -TEST(VgaTerminal, HelloWorld_Window) { +TEST(VgaTerminal, HelloWorldWindow) { SDL_SetMainReady(); // Not required, but for CI test. ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO)); @@ -21,7 +21,7 @@ TEST(VgaTerminal, HelloWorld_Window) { SDL_Quit(); } -TEST(VgaTerminal, HelloWorld_Text) { +TEST(VgaTerminal, HelloWorldText) { ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO)); std::string termTitle = "Hello Test"; From 3b6b7806208cacf8a72480fe6274f97255fc1ffd Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Fri, 17 Apr 2020 09:38:54 +0100 Subject: [PATCH 07/15] shared/static build option --- sdl2-vga-terminal/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sdl2-vga-terminal/CMakeLists.txt b/sdl2-vga-terminal/CMakeLists.txt index 237c7111..6857d088 100644 --- a/sdl2-vga-terminal/CMakeLists.txt +++ b/sdl2-vga-terminal/CMakeLists.txt @@ -6,9 +6,10 @@ set (CMAKE_DEBUG_POSTFIX d) find_package(SDL2 CONFIG REQUIRED) -############################ Shared lib ###################################### +############################ Shared/Static lib ###################################### +option(BUILD_SHARED_LIBS "build shared library" on) include(GenerateExportHeader) -add_library(vga-terminal-lib SHARED) +add_library(vga-terminal-lib) generate_export_header( vga-terminal-lib BASE_NAME vga-terminal-lib From fc9cf1a9889bb6dd1e5317365588f750e1ff4de8 Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Fri, 17 Apr 2020 15:11:29 +0100 Subject: [PATCH 08/15] reorganizing for shared and static lib (#13) * refactor cmake object name to vga-terminal-obj plust add runtime test for SO * move examples into example dir * [cmake] add static lib and refactor install rules * static lib to be linked with static sdl2 as option off * fixed cmake exports for static lib * rename readme * Apply suggestions from code review --- CMakeLists.txt | 7 ++ Readme.md => README.md | 5 +- sdl2-vga-terminal/CMakeLists.txt | 110 +++++++++++------- sdl2-vga-terminal/examples/CMakeLists.txt | 31 +++++ .../sdl2-vga-terminal-load-so.c | 4 +- .../{ => examples}/sdl2-vga-terminal-so.c | 2 +- .../{ => examples}/sdl2-vga-terminal.cpp | 0 sdl2-vga-terminal/include/vga-terminal.h | 5 + sdl2-vga-terminal/test/CMakeLists.txt | 15 ++- sdl2-vga-terminal/test/so-test.cpp | 24 ++++ 10 files changed, 150 insertions(+), 53 deletions(-) rename Readme.md => README.md (91%) create mode 100644 sdl2-vga-terminal/examples/CMakeLists.txt rename sdl2-vga-terminal/{ => examples}/sdl2-vga-terminal-load-so.c (97%) rename sdl2-vga-terminal/{ => examples}/sdl2-vga-terminal-so.c (93%) rename sdl2-vga-terminal/{ => examples}/sdl2-vga-terminal.cpp (100%) create mode 100644 sdl2-vga-terminal/test/so-test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7272bc9c..cd293b1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,13 @@ endif() project ("sdl2-vga-terminal" VERSION 0.1 DESCRIPTION "Vga Terminal on SDL2") +option(WITH_EXAMPLES "build examples" ON) +option(WITH_TEST "build test" ON) +option(TEST_DUMP_SNAPSHOT "running test dumping the expected output instead of verifing it" OFF) +option(WITH_SNAPSHOT "running snapshot test" OFF) +option(WITH_SDL2_STATIC "linking STATIC LIB with SDL2 STATIC" OFF) + + enable_testing() # Include sub-projects. add_subdirectory ("sdl2-vga-terminal") diff --git a/Readme.md b/README.md similarity index 91% rename from Readme.md rename to README.md index 7cb1f11f..4b4c2caf 100644 --- a/Readme.md +++ b/README.md @@ -55,13 +55,10 @@ Just as a convention. Some must and ideas: -- move the examples in `examples` folder? +- add tests for the cmake configuration and install files, expect them to be "there". - clear with bgCol, and only viewport. -- complete the cursor functionality (When typing show the cursor not blinking (reset timer?) -- CI with Azure Devops, travis, appveyor, sonarcloud lgtm, etc... - decouple vga modes - DAC Palette changing -- Cursor display - doxygen / document the code - use streams - read diff --git a/sdl2-vga-terminal/CMakeLists.txt b/sdl2-vga-terminal/CMakeLists.txt index 6857d088..7e3ced09 100644 --- a/sdl2-vga-terminal/CMakeLists.txt +++ b/sdl2-vga-terminal/CMakeLists.txt @@ -6,81 +6,107 @@ set (CMAKE_DEBUG_POSTFIX d) find_package(SDL2 CONFIG REQUIRED) -############################ Shared/Static lib ###################################### -option(BUILD_SHARED_LIBS "build shared library" on) + +############################ Shared lib ###################################### include(GenerateExportHeader) -add_library(vga-terminal-lib) +add_library(vga-terminal SHARED) generate_export_header( - vga-terminal-lib - BASE_NAME vga-terminal-lib + vga-terminal + BASE_NAME vga-terminal EXPORT_MACRO_NAME VGA_TERMINAL_EXPORT EXPORT_FILE_NAME vga-terminal-export.h STATIC_DEFINE vga-terminal-lib_BUILD_AS_STATIC ) install( - TARGETS vga-terminal-lib - EXPORT vga-terminal-lib-config + TARGETS vga-terminal + EXPORT vga-terminal-config DESTINATION lib - PUBLIC_HEADER DESTINATION inc + PUBLIC_HEADER DESTINATION include ) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/vga-terminal.h - $/vga-terminal-export.h - DESTINATION inc + $/vga-terminal-export.h + DESTINATION include +) +install(FILES + $ + DESTINATION lib ) -export(TARGETS vga-terminal-lib +export(TARGETS vga-terminal FILE ${CMAKE_BINARY_DIR}/vga-terminal.cmake ) install(EXPORT - vga-terminal-lib-config DESTINATION cmake + vga-terminal-config DESTINATION cmake ) -target_include_directories(vga-terminal-lib PUBLIC - $> +target_include_directories(vga-terminal PUBLIC + $> $ $ ) -target_sources(vga-terminal-lib PRIVATE +target_sources(vga-terminal PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/Window.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/VgaTerminal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/vga-terminal.cpp ) -target_link_libraries(vga-terminal-lib SDL2::SDL2 SDL2::SDL2main) +target_link_libraries(vga-terminal SDL2::SDL2 SDL2::SDL2main) -################ Shared code among exe and tests ############################# -add_library(vga-terminal OBJECT) -target_sources(vga-terminal PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/src/VgaTerminal.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/Window.cpp +########################### Static Lib ####################################### +add_library(vga-terminal-static STATIC) +install( + TARGETS vga-terminal-static + EXPORT vga-terminal-static-config + DESTINATION static/lib + PUBLIC_HEADER DESTINATION static/include +) +install(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/VgaTerminal.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/Window.hpp + DESTINATION static/include ) -target_include_directories(vga-terminal PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) -target_link_libraries(vga-terminal PUBLIC SDL2::SDL2 SDL2::SDL2main) - +export(TARGETS vga-terminal-static + FILE ${CMAKE_BINARY_DIR}/vga-terminal-static.cmake +) +install(EXPORT + vga-terminal-static-config DESTINATION static/cmake +) +target_include_directories(vga-terminal-static PUBLIC + $ + $ +) +target_sources(vga-terminal-static PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/src/Window.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/VgaTerminal.cpp +) +target_link_libraries(vga-terminal-static SDL2::SDL2 SDL2::SDL2main) -############################## Main Example ################################## -add_executable (${PROJECT_NAME} "sdl2-vga-terminal.cpp") -add_dependencies(${PROJECT_NAME} vga-terminal) -target_link_libraries(${PROJECT_NAME} vga-terminal) +################ Shared code among exe and tests ############################# +add_library(vga-terminal-obj OBJECT) +target_sources(vga-terminal-obj PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/src/VgaTerminal.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/Window.cpp +) -################## C example using SO/DLL with lazy loading ################## -add_executable (${PROJECT_NAME}-so "sdl2-vga-terminal-so.c") -add_dependencies(${PROJECT_NAME}-so vga-terminal-lib) -target_link_libraries(${PROJECT_NAME}-so vga-terminal-lib) -if(MSVC) - target_link_options(${PROJECT_NAME}-so PRIVATE - "/INCREMENTAL" - "/DELAYLOAD:$" - "/DELAY:UNLOAD" +target_include_directories(vga-terminal-obj PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) +if(WITH_SDL2_STATIC) + target_link_libraries(vga-terminal-obj PUBLIC SDL2::SDL2-static SDL2::SDL2main) +else() + install(FILES + $ + DESTINATION static/lib ) + target_link_libraries(vga-terminal-obj PUBLIC SDL2::SDL2 SDL2::SDL2main) endif() - -################## C example using SO/DLL run-time loading ################## -add_executable (${PROJECT_NAME}-load-so "sdl2-vga-terminal-load-so.c") -target_link_libraries(${PROJECT_NAME}-load-so PUBLIC SDL2::SDL2 SDL2::SDL2main) +### Examples +if(WITH_EXAMPLES) + add_subdirectory("examples") +endif() -############################### tests +############################### tests ######################################## +if(WITH_TEST) add_subdirectory("test") +endif() diff --git a/sdl2-vga-terminal/examples/CMakeLists.txt b/sdl2-vga-terminal/examples/CMakeLists.txt new file mode 100644 index 00000000..4524741d --- /dev/null +++ b/sdl2-vga-terminal/examples/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required (VERSION 3.8) + + +############################## Main Example ################################## +add_executable (${PROJECT_NAME} "sdl2-vga-terminal.cpp") +add_dependencies(${PROJECT_NAME} vga-terminal-obj) +target_link_libraries(${PROJECT_NAME} vga-terminal-obj) + + +################## C example using SO/DLL with lazy loading ################## +add_executable (${PROJECT_NAME}-so "sdl2-vga-terminal-so.c") +add_dependencies(${PROJECT_NAME}-so vga-terminal) +target_link_libraries(${PROJECT_NAME}-so vga-terminal) +add_custom_command(TARGET "${PROJECT_NAME}-so" POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ +) +if(MSVC) + target_link_options(${PROJECT_NAME}-so PRIVATE + "/INCREMENTAL" + "/DELAYLOAD:$" + "/DELAY:UNLOAD" + ) +endif() + + +################## C example using SO/DLL run-time loading ################## +add_executable (${PROJECT_NAME}-load-so "sdl2-vga-terminal-load-so.c") +target_link_libraries(${PROJECT_NAME}-load-so PUBLIC SDL2::SDL2 SDL2::SDL2main) +add_custom_command(TARGET "${PROJECT_NAME}-load-so" POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ +) diff --git a/sdl2-vga-terminal/sdl2-vga-terminal-load-so.c b/sdl2-vga-terminal/examples/sdl2-vga-terminal-load-so.c similarity index 97% rename from sdl2-vga-terminal/sdl2-vga-terminal-load-so.c rename to sdl2-vga-terminal/examples/sdl2-vga-terminal-load-so.c index d6f52fd8..2959fefb 100644 --- a/sdl2-vga-terminal/sdl2-vga-terminal-load-so.c +++ b/sdl2-vga-terminal/examples/sdl2-vga-terminal-load-so.c @@ -27,11 +27,11 @@ typedef VGA_Terminal* (__cdecl* PROCINIT)(); #if defined(DEBUG) || !defined(NDBEBUG) -#define VGA_SO_NAME "vga-terminal-libd" +#define VGA_SO_NAME "vga-terminald" #else -#define VGA_SO_NAME "vga-terminal-lib" +#define VGA_SO_NAME "vga-terminal" #endif diff --git a/sdl2-vga-terminal/sdl2-vga-terminal-so.c b/sdl2-vga-terminal/examples/sdl2-vga-terminal-so.c similarity index 93% rename from sdl2-vga-terminal/sdl2-vga-terminal-so.c rename to sdl2-vga-terminal/examples/sdl2-vga-terminal-so.c index 7a63e408..200997b9 100644 --- a/sdl2-vga-terminal/sdl2-vga-terminal-so.c +++ b/sdl2-vga-terminal/examples/sdl2-vga-terminal-so.c @@ -40,7 +40,7 @@ int main(int argc, char* args[]) #else #define PFIX "" #endif - int t = __FUnloadDelayLoadedDLL2("vga-terminal-lib" PFIX ".dll"); + int t = __FUnloadDelayLoadedDLL2("vga-terminal" PFIX ".dll"); printf("unloaded? : %d\n", t); getchar(); #endif // WIN32 diff --git a/sdl2-vga-terminal/sdl2-vga-terminal.cpp b/sdl2-vga-terminal/examples/sdl2-vga-terminal.cpp similarity index 100% rename from sdl2-vga-terminal/sdl2-vga-terminal.cpp rename to sdl2-vga-terminal/examples/sdl2-vga-terminal.cpp diff --git a/sdl2-vga-terminal/include/vga-terminal.h b/sdl2-vga-terminal/include/vga-terminal.h index 1dfd5943..55bf1edd 100644 --- a/sdl2-vga-terminal/include/vga-terminal.h +++ b/sdl2-vga-terminal/include/vga-terminal.h @@ -1,3 +1,8 @@ +/*********************************************** + *** TODO: export all the required methods *** + *** just done the bare basic *** + ***********************************************/ + #pragma once #include diff --git a/sdl2-vga-terminal/test/CMakeLists.txt b/sdl2-vga-terminal/test/CMakeLists.txt index ce52bb0d..c11d1297 100644 --- a/sdl2-vga-terminal/test/CMakeLists.txt +++ b/sdl2-vga-terminal/test/CMakeLists.txt @@ -1,7 +1,5 @@ cmake_minimum_required (VERSION 3.8) -option(TEST_DUMP_SNAPSHOT "running test dumping the expected output instead of verifing it" OFF) -option(WITH_SNAPSHOT "running snapshot test" OFF) find_package(GTest CONFIG REQUIRED) @@ -11,7 +9,7 @@ if (TEST_DUMP_SNAPSHOT) else() add_executable(runUnitTests "tests.cpp") add_test(UnitTestsInMain runUnitTests) - target_link_libraries(runUnitTests PRIVATE vga-terminal GTest::gtest GTest::gmock) + target_link_libraries(runUnitTests PRIVATE vga-terminal-obj GTest::gtest GTest::gmock) add_custom_command(TARGET runUnitTests POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ @@ -23,7 +21,7 @@ if (WITH_SNAPSHOT) find_package(SDL2-image CONFIG REQUIRED) add_executable(runSnapshotTests "snapshotTest.cpp") - target_link_libraries(runSnapshotTests PRIVATE vga-terminal GTest::gtest SDL2::SDL2_image) + target_link_libraries(runSnapshotTests PRIVATE vga-terminal-obj GTest::gtest SDL2::SDL2_image) add_test(SnapshotTestsInMain runSnapshotTests) add_custom_command(TARGET runUnitTests POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ @@ -33,5 +31,14 @@ if (WITH_SNAPSHOT) ) endif() +add_executable(runSOTest "so-test.cpp") +add_test(SOTest runSOTest) +target_link_libraries(runSOTest PRIVATE vga-terminal GTest::gtest) +add_custom_command(TARGET runSOTest POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + ) + diff --git a/sdl2-vga-terminal/test/so-test.cpp b/sdl2-vga-terminal/test/so-test.cpp new file mode 100644 index 00000000..343e99ce --- /dev/null +++ b/sdl2-vga-terminal/test/so-test.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +TEST(VgaTerminalSO, simpleRunningTest) +{ + // TODO: Very basic, need improvement, + // just for basic runtime using of SO. + ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER)); + + + VGA_Terminal* term = VGA_TERMINAL_init(); + VGA_TERMINAL_writeXY(term, 0, 0, "test", 10, 0); + VGA_TERMINAL_render(term); + VGA_TERMINAL_destroy(term); + + SDL_Quit(); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} From a9a5137f96753a7711e7189c923b13c5d6252425 Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Fri, 17 Apr 2020 23:15:23 +0100 Subject: [PATCH 09/15] fix r/b channel palette --- sdl2-vga-terminal/src/VgaTerminal.cpp | 4 ++-- sdl2-vga-terminal/test/snapshotTest.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sdl2-vga-terminal/src/VgaTerminal.cpp b/sdl2-vga-terminal/src/VgaTerminal.cpp index 499bb652..65a6bee9 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.cpp +++ b/sdl2-vga-terminal/src/VgaTerminal.cpp @@ -59,9 +59,9 @@ VgaTerminal::VgaTerminal(const std::string &title, const int width, const int he p.colors = pCol.get(); for (int i = 0, i3 = 0; i < p.ncolors; i++, i3+=3) { - p.colors[i].r = RESIZE_VGA_PALETTE(mode.palette[i3 + 2]); + p.colors[i].r = RESIZE_VGA_PALETTE(mode.palette[i3 + 0]); p.colors[i].g = RESIZE_VGA_PALETTE(mode.palette[i3 + 1]); - p.colors[i].b = RESIZE_VGA_PALETTE(mode.palette[i3 + 0]); + p.colors[i].b = RESIZE_VGA_PALETTE(mode.palette[i3 + 2]); p.colors[i].a = 255; } diff --git a/sdl2-vga-terminal/test/snapshotTest.cpp b/sdl2-vga-terminal/test/snapshotTest.cpp index cfe3c798..b1477283 100644 --- a/sdl2-vga-terminal/test/snapshotTest.cpp +++ b/sdl2-vga-terminal/test/snapshotTest.cpp @@ -37,9 +37,9 @@ TEST(VgaTerminal, Snapshot) { term.write((char)i, i, 255 - i); } - term.writeXY(32, 11, "ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»", 11, 4); - term.writeXY(32, 12, "Ί Hello World!! Ί", 11, 4); - term.writeXY(32, 13, "ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ", 11, 4); + term.writeXY(32, 11, "ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»", 14, 1); + term.writeXY(32, 12, "Ί Hello World!! Ί", 14, 1); + term.writeXY(32, 13, "ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ", 14, 1); term.render(); SDL_Delay(1000); SDL_Surface* snapshot = getScreenshot(term); From 81191a1a93ae0f04bff0fff6375e6ce65e94a28b Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Fri, 17 Apr 2020 23:57:24 +0100 Subject: [PATCH 10/15] autoscroll flag --- sdl2-vga-terminal/src/VgaTerminal.cpp | 8 +++++- sdl2-vga-terminal/src/VgaTerminal.hpp | 2 +- sdl2-vga-terminal/test/CMakeLists.txt | 2 +- .../test/snapshot/VgaTerminal.Snapshot.png | Bin 12320 -> 12251 bytes sdl2-vga-terminal/test/snapshotTest.cpp | 23 ++++++++++-------- sdl2-vga-terminal/test/tests.cpp | 18 ++++++++++++++ 6 files changed, 40 insertions(+), 13 deletions(-) diff --git a/sdl2-vga-terminal/src/VgaTerminal.cpp b/sdl2-vga-terminal/src/VgaTerminal.cpp index 65a6bee9..efce65c3 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.cpp +++ b/sdl2-vga-terminal/src/VgaTerminal.cpp @@ -375,7 +375,13 @@ void VgaTerminal::incrementCursorPosition() noexcept if (++_curY >= h) { _curY = h - 1; - scrollDownGrid(); + if (autoScroll) { + scrollDownGrid(); + } + else { + // stay in the same position + _curX = _viewPortX + _viewPortWidth - 1; + } } } } diff --git a/sdl2-vga-terminal/src/VgaTerminal.hpp b/sdl2-vga-terminal/src/VgaTerminal.hpp index ded69459..ac8df38a 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.hpp +++ b/sdl2-vga-terminal/src/VgaTerminal.hpp @@ -72,7 +72,7 @@ class VgaTerminal : public Window uint8_t curDefaultCol = 7; bool showCursor = true; - + bool autoScroll = true; private: std::unique_ptr pCol; SDL_Palette p; diff --git a/sdl2-vga-terminal/test/CMakeLists.txt b/sdl2-vga-terminal/test/CMakeLists.txt index c11d1297..352eba92 100644 --- a/sdl2-vga-terminal/test/CMakeLists.txt +++ b/sdl2-vga-terminal/test/CMakeLists.txt @@ -23,7 +23,7 @@ if (WITH_SNAPSHOT) add_executable(runSnapshotTests "snapshotTest.cpp") target_link_libraries(runSnapshotTests PRIVATE vga-terminal-obj GTest::gtest SDL2::SDL2_image) add_test(SnapshotTestsInMain runSnapshotTests) - add_custom_command(TARGET runUnitTests POST_BUILD + add_custom_command(TARGET runSnapshotTests POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ diff --git a/sdl2-vga-terminal/test/snapshot/VgaTerminal.Snapshot.png b/sdl2-vga-terminal/test/snapshot/VgaTerminal.Snapshot.png index 8048641a691b3bf23d003d68b281c4f5f19e1abe..f6b9334f0ab91585e14cb9b3e64f29c1e60c9fef 100644 GIT binary patch literal 12251 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 literal 12320 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 diff --git a/sdl2-vga-terminal/test/snapshotTest.cpp b/sdl2-vga-terminal/test/snapshotTest.cpp index b1477283..c44ae9af 100644 --- a/sdl2-vga-terminal/test/snapshotTest.cpp +++ b/sdl2-vga-terminal/test/snapshotTest.cpp @@ -2,7 +2,8 @@ #include #include -std::string generateSnapshotFilename() { +std::string generateSnapshotFilename() +{ std::string snapshotFilename = ::testing::UnitTest::GetInstance()->current_test_info()->test_case_name(); snapshotFilename += '.'; snapshotFilename += ::testing::UnitTest::GetInstance()->current_test_info()->name(); @@ -11,7 +12,8 @@ std::string generateSnapshotFilename() { return snapshotFilename; } -SDL_Surface* getScreenshot(const VgaTerminal& term) { +SDL_Surface* getScreenshot(const VgaTerminal& term) +{ int w = 0, h = 0; const uint32_t format = SDL_PIXELFORMAT_ABGR8888; @@ -25,7 +27,8 @@ SDL_Surface* getScreenshot(const VgaTerminal& term) { return snapshot; } -TEST(VgaTerminal, Snapshot) { +TEST(VgaTerminal, Snapshot) +{ SDL_Init(SDL_INIT_VIDEO); IMG_Init(IMG_INIT_PNG); std::string termTitle = "Hello Test"; @@ -34,7 +37,7 @@ TEST(VgaTerminal, Snapshot) { std::string snapshotFilename = generateSnapshotFilename(); for (int i = 0; i < 256; i++) { - term.write((char)i, i, 255 - i); + term.write(static_cast(i), i, 255 - i); } term.writeXY(32, 11, "ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»", 14, 1); @@ -51,11 +54,11 @@ TEST(VgaTerminal, Snapshot) { #else SDL_Surface* image = IMG_Load(("snapshot/" + snapshotFilename).c_str()); - ASSERT_EQ(image->format->format, snapshot->format->format); - ASSERT_EQ(image->format->BytesPerPixel, snapshot->format->BytesPerPixel); - ASSERT_EQ(image->pitch, snapshot->pitch); - ASSERT_EQ(image->w, snapshot->w); - ASSERT_EQ(image->h, snapshot->h); + EXPECT_EQ(image->format->format, snapshot->format->format); + EXPECT_EQ(image->format->BytesPerPixel, snapshot->format->BytesPerPixel); + EXPECT_EQ(image->pitch, snapshot->pitch); + EXPECT_EQ(image->w, snapshot->w); + EXPECT_EQ(image->h, snapshot->h); if (SDL_LockSurface(image) != 0) { GTEST_LOG_(ERROR) << "unable to access image" << SDL_GetError(); @@ -66,7 +69,7 @@ TEST(VgaTerminal, Snapshot) { } int size = image->pitch * image->h; - ASSERT_EQ(0, SDL_memcmp(image->pixels, snapshot->pixels, size)); + EXPECT_EQ(0, SDL_memcmp(image->pixels, snapshot->pixels, size)); SDL_UnlockSurface(image); SDL_UnlockSurface(snapshot); diff --git a/sdl2-vga-terminal/test/tests.cpp b/sdl2-vga-terminal/test/tests.cpp index d0e3496e..97347547 100644 --- a/sdl2-vga-terminal/test/tests.cpp +++ b/sdl2-vga-terminal/test/tests.cpp @@ -215,6 +215,24 @@ TEST(VgaTerminal, ViewportMoveCursorBorder) SDL_Quit(); } + +TEST(VgaTerminal, NoAutoScroll) +{ + ASSERT_EQ(0, SDL_Init(SDL_INIT_VIDEO)); + + std::string termTitle = "Test"; + VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); + term.autoScroll = false; + term.writeXY(79, 24, "0", 7, 0); + EXPECT_EQ(79, term.getX()); + EXPECT_EQ(24, term.getY()); + + term.writeXY(79, 20, "0", 7, 0); + EXPECT_EQ(0, term.getX()); + EXPECT_EQ(21, term.getY()); + + SDL_Quit(); +} #endif int main(int argc, char** argv) { From 9e9e039a51ff6dda1a5e46454e9ca31f15af8628 Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Sat, 18 Apr 2020 00:12:30 +0100 Subject: [PATCH 11/15] vgaterminal getMode method --- sdl2-vga-terminal/src/VgaTerminal.cpp | 6 ++++++ sdl2-vga-terminal/src/VgaTerminal.hpp | 10 ++++------ sdl2-vga-terminal/test/tests.cpp | 10 +++++----- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/sdl2-vga-terminal/src/VgaTerminal.cpp b/sdl2-vga-terminal/src/VgaTerminal.cpp index efce65c3..56b18dd5 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.cpp +++ b/sdl2-vga-terminal/src/VgaTerminal.cpp @@ -418,3 +418,9 @@ void VgaTerminal::scrollDownGrid() noexcept } } +const VgaTerminal::videoMode_t VgaTerminal::getMode() const noexcept +{ + return mode; +} + + diff --git a/sdl2-vga-terminal/src/VgaTerminal.hpp b/sdl2-vga-terminal/src/VgaTerminal.hpp index ac8df38a..a3aa17b4 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.hpp +++ b/sdl2-vga-terminal/src/VgaTerminal.hpp @@ -13,16 +13,13 @@ class VgaTerminal : public Window typedef struct { uint8_t mode; // video mode (only mode 3 available at the moment) - //uint16_t sw; // screen width - //uint16_t sh; // height uint8_t tw; // terminal width uint8_t th; // hieght uint8_t cw; // char width uint8_t ch; // height | font size - //uint8_t fs; // font size uint8_t* font; int numColors; - uint8_t* palette; // BGR palette assumed (might be required a palette format flag?) + uint8_t* palette; // RGB palette assumed (might be required a palette format flag?) } videoMode_t; // TODO keep only the 3 uint8_t here, @@ -38,8 +35,6 @@ class VgaTerminal : public Window typedef std::pair position_t; - static const videoMode_t mode3; - VgaTerminal() = delete; VgaTerminal(const std::string &title, const int winFlags, const int drvIndex, const int renFlags); VgaTerminal(const std::string &title, const int width, const int height, const int winFlags, const int drvIndex, const int renFlags); @@ -73,7 +68,10 @@ class VgaTerminal : public Window uint8_t curDefaultCol = 7; bool showCursor = true; bool autoScroll = true; + + const videoMode_t getMode() const noexcept; private: + static const videoMode_t mode3; std::unique_ptr pCol; SDL_Palette p; videoMode_t mode; diff --git a/sdl2-vga-terminal/test/tests.cpp b/sdl2-vga-terminal/test/tests.cpp index 97347547..4416bbda 100644 --- a/sdl2-vga-terminal/test/tests.cpp +++ b/sdl2-vga-terminal/test/tests.cpp @@ -42,12 +42,12 @@ TEST(VgaTerminal, ScrollDown) { std::string termTitle = "Hello Test"; VgaTerminal term = VgaTerminal(termTitle, SDL_WINDOW_HIDDEN, -1, 0); - term.writeXY(VgaTerminal::mode3.tw - 1, VgaTerminal::mode3.th - 1, termTitle, 7, 1); + term.writeXY(term.getMode().tw - 1, term.getMode().th - 1, termTitle, 7, 1); uint8_t termTitleLength = static_cast(termTitle.size()); - - ASSERT_EQ(VgaTerminal::position_t(termTitleLength - 1, VgaTerminal::mode3.th - 1), term.getXY()); - ASSERT_EQ('H', term.at(VgaTerminal::mode3.tw - 1, VgaTerminal::mode3.th - 2).c); - ASSERT_EQ('T', term.at(5, VgaTerminal::mode3.th - 1).c); + + ASSERT_EQ(VgaTerminal::position_t(termTitleLength - 1, term.getMode().th - 1), term.getXY()); + ASSERT_EQ('H', term.at(term.getMode().tw - 1, term.getMode().th - 2).c); + ASSERT_EQ('T', term.at(5, term.getMode().th - 1).c); SDL_Quit(); } From 7cc4cc4ef8724f5d7b10471d26b1916b763ef4f8 Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Sat, 18 Apr 2020 19:29:12 +0100 Subject: [PATCH 12/15] code review --- sdl2-vga-terminal/src/VgaTerminal.cpp | 1 - sdl2-vga-terminal/src/VgaTerminal.hpp | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/sdl2-vga-terminal/src/VgaTerminal.cpp b/sdl2-vga-terminal/src/VgaTerminal.cpp index 56b18dd5..ce3427e5 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.cpp +++ b/sdl2-vga-terminal/src/VgaTerminal.cpp @@ -39,7 +39,6 @@ VgaTerminal::~VgaTerminal() VgaTerminal::VgaTerminal(const std::string &title, const int winFlags, const int drvIndex, const int renFlags) : VgaTerminal(title, mode3.tw * mode3.cw, mode3.th * mode3.ch, winFlags, drvIndex, renFlags) - { } diff --git a/sdl2-vga-terminal/src/VgaTerminal.hpp b/sdl2-vga-terminal/src/VgaTerminal.hpp index a3aa17b4..2aff76b5 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.hpp +++ b/sdl2-vga-terminal/src/VgaTerminal.hpp @@ -12,11 +12,11 @@ class VgaTerminal : public Window public: typedef struct { - uint8_t mode; // video mode (only mode 3 available at the moment) - uint8_t tw; // terminal width - uint8_t th; // hieght - uint8_t cw; // char width - uint8_t ch; // height | font size + uint8_t mode; // video mode (only mode 3 available at the moment) + uint8_t tw; // terminal width + uint8_t th; // hieght + uint8_t cw; // char width + uint8_t ch; // height | font size uint8_t* font; int numColors; uint8_t* palette; // RGB palette assumed (might be required a palette format flag?) From a18d3e0955cf049e35032a530c3b0a6ba64a2c39 Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Sat, 18 Apr 2020 20:53:44 +0100 Subject: [PATCH 13/15] clean code --- sdl2-vga-terminal/src/VgaTerminal.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sdl2-vga-terminal/src/VgaTerminal.cpp b/sdl2-vga-terminal/src/VgaTerminal.cpp index ce3427e5..a398bcbf 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.cpp +++ b/sdl2-vga-terminal/src/VgaTerminal.cpp @@ -16,7 +16,6 @@ const VgaTerminal::videoMode_t VgaTerminal::mode3 = { static_cast (25), // th static_cast (8), // cw static_cast (VGA_FONT_SIZE_16), // ch - //static_cast (16) // fs vgafont16, PALETTE_3_COLORS, palette3, From a88cec5ce6062a9186cf21b43520cb761e6c69c3 Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Sun, 19 Apr 2020 16:15:14 +0100 Subject: [PATCH 14/15] [WIP] draft, got stuck on rendering --- README.md | 1 + build_wasm.sh | 10 +++ sdl2-vga-terminal/examples/wasm.cpp | 97 +++++++++++++++++++++++++++ sdl2-vga-terminal/src/VgaTerminal.cpp | 2 +- sdl2-vga-terminal/src/Window.cpp | 1 + 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 build_wasm.sh create mode 100644 sdl2-vga-terminal/examples/wasm.cpp diff --git a/README.md b/README.md index 4b4c2caf..0a5a10d0 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Just as a convention. Some must and ideas: +- web assembly example,build experimentation? - add tests for the cmake configuration and install files, expect them to be "there". - clear with bgCol, and only viewport. - decouple vga modes diff --git a/build_wasm.sh b/build_wasm.sh new file mode 100644 index 00000000..08c29481 --- /dev/null +++ b/build_wasm.sh @@ -0,0 +1,10 @@ +#/bin/bash + +### More as a reminder to build it. + +mkdir build +cd build +## emcc need to be in the path. (run source emcsdk_env.sh) +emcc -std=c++17 ../sdl2-vga-terminal/examples/wasm.cpp ../sdl2-vga-terminal/src/Window.cpp ../sdl2-vga-terminal/src/VgaTerminal.cpp -I ../sdl2-vga-terminal/src/ -s USE_SDL=2 -o v.html +python -m http.server 8080 + diff --git a/sdl2-vga-terminal/examples/wasm.cpp b/sdl2-vga-terminal/examples/wasm.cpp new file mode 100644 index 00000000..8719f37f --- /dev/null +++ b/sdl2-vga-terminal/examples/wasm.cpp @@ -0,0 +1,97 @@ +// sdl2-vga-terminal.cpp : Defines the entry point for the application. +// + +#include +#include +#include + +#ifdef __EMSCRIPTEN__ +#include +#endif + +using namespace std; + +void main_loop(void) +{ + VgaTerminal term1 = VgaTerminal("VgaTerminal", 720, 400, 0, -1, 0); + + /*for (int i = 0; i < 256; i++) { + term1.write((char)i, i, 255 - i); + }*/ + + term1.showCursor = false; + term1.write("Hello World!!!", 7, 0); + term1.render(); + + //term1.writeXY(10, 15, "ΙΝΝΝΝΝΝΝΝΝ»", 12, 3); +//term1.writeXY(10, 16, "Ί Ί", 12, 3); +//term1.writeXY(10, 17, "ΘΝΝΝΝΝΝΝΝΝΌ", 12, 3); +//term1.gotoXY(12, 16); term1.write(3, 1, 15); +//term1.gotoXY(14, 16); term1.write(4, 15, 1); +//term1.gotoXY(16, 16); term1.write(5, 0, 15); +//term1.gotoXY(18, 16); term1.write(6, 15, 0); + +#ifdef EMSCRIPTEN + emscripten_cancel_main_loop(); +#endif +} + +extern "C" int main(int argc, char* args[]) +{ + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS) != 0) { + SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Unable to initialize SDL: %s", SDL_GetError()); + return 1; + } + + int numVideoDrivers = SDL_GetNumVideoDrivers(); + if (numVideoDrivers < 1) { + SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "no video drivers: %s", SDL_GetError()); + return 1; + } + cout << "Video Drivers:" << endl; + for (int i = 0; i < numVideoDrivers; i++) { + std::cout << i << ". " << SDL_GetVideoDriver(i) << endl; + } + + int numRenderDrivers = SDL_GetNumRenderDrivers(); + if (numRenderDrivers < 1) { + SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "no render drivers: %s", SDL_GetError()); + } + cout << "Render Drivers:" << endl; + for (int i = 0; i < numRenderDrivers; i++) { + SDL_RendererInfo ri; + SDL_GetRenderDriverInfo(i, &ri); + std::cout << i << ". " << ri.name << " --- Num Tex fmt: " << ri.num_texture_formats << endl; + } + + int numVideoDisplay = SDL_GetNumVideoDisplays(); + if (numVideoDisplay <= 0) { + SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "no Video displays: %s", SDL_GetError()); + } + cout << "Num Video Displays:" << numVideoDisplay << endl; + for (int i = 0; i < numVideoDisplay; i++) { + int numDisplayModes = SDL_GetNumDisplayModes(i); + if (numDisplayModes < 1) { + SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "no display mode: %s", SDL_GetError()); + } + cout << "Display Modes of index " << i << ':' << endl; + for (int j = 0; j < numDisplayModes; j++) { + SDL_DisplayMode dm; + SDL_GetDisplayMode(i, j, &dm); + std::cout << i << "." << j << ". " << dm.w << " x " << dm.h << " Hz: " << dm.refresh_rate << " pxl: " << dm.format << endl; + } + } + + // --- end SDL2 system init and info + + + // TODO: main loop is the problem, emscripten_set_main_loop has to be set up before + // something when i am creating the VgaTerminal object .... not sure + //VgaTerminal term1 = VgaTerminal("VgaTerminal", 720, 400, 0, -1, 0); +#ifdef EMSCRIPTEN + emscripten_set_main_loop(main_loop, 0, 1); +#endif + + SDL_Quit(); + return 0; +} diff --git a/sdl2-vga-terminal/src/VgaTerminal.cpp b/sdl2-vga-terminal/src/VgaTerminal.cpp index a398bcbf..621b87ee 100644 --- a/sdl2-vga-terminal/src/VgaTerminal.cpp +++ b/sdl2-vga-terminal/src/VgaTerminal.cpp @@ -75,7 +75,7 @@ VgaTerminal::VgaTerminal(const std::string &title, const int width, const int he } } else { - SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "[% s] % s: TIMER or EVENTS not inited.", typeid(*this).name(), __func__); + SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "[%s] %s: TIMER or EVENTS not inited.", typeid(*this).name(), __func__); } } diff --git a/sdl2-vga-terminal/src/Window.cpp b/sdl2-vga-terminal/src/Window.cpp index a782a2da..0e800432 100644 --- a/sdl2-vga-terminal/src/Window.cpp +++ b/sdl2-vga-terminal/src/Window.cpp @@ -1,6 +1,7 @@ #include "Window.hpp" #include + Window::Window(const std::string &title, const int width, const int height, const int winFlags, const int drvIndex, const int renFlags) { if (SDL_WasInit(SDL_INIT_VIDEO) != SDL_INIT_VIDEO) { From 9a6bf579cce229078d61fa248f08cb2b8f65e860 Mon Sep 17 00:00:00 2001 From: Raffaello Bertini Date: Sun, 19 Apr 2020 16:37:41 +0100 Subject: [PATCH 15/15] [wip] ??? --- sdl2-vga-terminal/examples/wasm.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sdl2-vga-terminal/examples/wasm.cpp b/sdl2-vga-terminal/examples/wasm.cpp index 8719f37f..1b476742 100644 --- a/sdl2-vga-terminal/examples/wasm.cpp +++ b/sdl2-vga-terminal/examples/wasm.cpp @@ -36,6 +36,18 @@ void main_loop(void) #endif } +void renderWrapper(void* term) +{ + if (nullptr != term) { + VgaTerminal* _term = (VgaTerminal*)term; + _term->render(); + } + +#ifdef EMSCRIPTEN + emscripten_cancel_main_loop(); +#endif +} + extern "C" int main(int argc, char* args[]) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS) != 0) { @@ -89,9 +101,10 @@ extern "C" int main(int argc, char* args[]) // something when i am creating the VgaTerminal object .... not sure //VgaTerminal term1 = VgaTerminal("VgaTerminal", 720, 400, 0, -1, 0); #ifdef EMSCRIPTEN - emscripten_set_main_loop(main_loop, 0, 1); + //void emscripten_set_main_loop_arg(em_arg_callback_func func, void* arg, int fps, int simulate_infinite_loop) + emscripten_set_main_loop(main_loop, 0, 0); #endif - + //emscripten_set_main_loop_arg(renderWrapper, (void*)&term1, 0, 0); SDL_Quit(); return 0; }