Ported all of the generic gui code to OmniaFramework

This commit is contained in:
OmniaX-Dev 2026-03-05 22:19:23 +01:00
parent 327d0dd108
commit d0e8f5d43d
13 changed files with 64 additions and 602 deletions

View file

@ -33,10 +33,6 @@ list(APPEND RUNTIME_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/src/runtime/DragonRuntime.cpp
${CMAKE_CURRENT_LIST_DIR}/src/runtime/ConfigLoader.cpp
${CMAKE_CURRENT_LIST_DIR}/src/gui/Window.cpp
${CMAKE_CURRENT_LIST_DIR}/src/gui/RawTextRenderer.cpp
${CMAKE_CURRENT_LIST_DIR}/src/gui/Renderer.cpp
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualCPU.cpp
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualRAM.cpp
${CMAKE_CURRENT_LIST_DIR}/src/hardware/MemoryMapper.cpp
@ -55,10 +51,6 @@ list(APPEND DEBUGGER_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/src/debugger/Debugger.cpp
${CMAKE_CURRENT_LIST_DIR}/src/debugger/DebuggerNew.cpp
${CMAKE_CURRENT_LIST_DIR}/src/gui/Window.cpp
${CMAKE_CURRENT_LIST_DIR}/src/gui/RawTextRenderer.cpp
${CMAKE_CURRENT_LIST_DIR}/src/gui/Renderer.cpp
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualCPU.cpp
${CMAKE_CURRENT_LIST_DIR}/src/hardware/VirtualRAM.cpp
${CMAKE_CURRENT_LIST_DIR}/src/hardware/MemoryMapper.cpp
@ -188,7 +180,7 @@ endif (UNIX)
target_link_libraries(${RUNTIME_TARGET} SDL2main SDL2 SDL2_image)
target_link_libraries(${DEBUGGER_TARGET} SDL2main SDL2 SDL2_image)
target_link_libraries(${RUNTIME_TARGET} ostd)
target_link_libraries(${RUNTIME_TARGET} ostd ogfx)
target_link_libraries(${DEBUGGER_TARGET} ostd ogfx)
target_link_libraries(${ASSEMBLER_TARGET} ostd)
target_link_libraries(${TOOLS_TARGET} ostd)

View file

@ -1,5 +1,5 @@
## --
## -- This file is automatically generated by the DragonAssembler (version 0.4.1640)
## -- This file is automatically generated by the DragonAssembler (version 0.4.1641)
## -- Please do not modify this file in any way.
## --

View file

@ -1 +1 @@
1641
1642

View file

@ -1,104 +0,0 @@
#include "RawTextRenderer.hpp"
#include <ostd/Utils.hpp>
#include <ostd/Geometry.hpp>
#include <ostd/Defines.hpp>
namespace dragon
{
void RawTextRenderer::initialize(void)
{
for (char c = ' '; c <= '~'; c++)
characterMap[c] = getCharacterIndex(c);
}
bool RawTextRenderer::drawString(ostd::String str, uint32_t column, uint32_t row, uint32_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint32_t* fontPixels, ostd::Color color, ostd::Color background)
{
ostd::String se(str);
if (se == "") return false;
if (row >= CONSOLE_CHARS_V) return false;
if (column >= CONSOLE_CHARS_H) return false;
if (column + str.len() > CONSOLE_CHARS_H) return false;
int32_t x = column * FONT_CHAR_W;
int32_t y = row * FONT_CHAR_H;
for (auto& c : str)
{
drawCharacter((uint8_t*)screenPixels, screenWidth, screenHeight, (uint8_t*)fontPixels, x, y, c, color, background);
x += FONT_CHAR_W;
}
s_cursor_pos_x = x;
if (s_cursor_pos_x >= CONSOLE_CHARS_H)
s_cursor_pos_x = 0;
return true;
}
int32_t RawTextRenderer::getCharacterIndex(char c)
{
using namespace ostd;
int32_t charIndex = (int)c - 32;
IPoint charCoords = CONVERT_1D_2D(charIndex, FONT_H_CHARS);
charCoords.x *= FONT_CHAR_W * 4;
charCoords.y *= FONT_CHAR_H;
charIndex = CONVERT_2D_1D(charCoords.x, charCoords.y, (FONT_H_CHARS * FONT_CHAR_W * 4));
return charIndex;
}
ostd::Color RawTextRenderer::applyTint(ostd::Color baseColor, ostd::Color tintColor)
{
auto nBase = baseColor.getNormalizedColor();
auto nTint = tintColor.getNormalizedColor();
float r = nBase.r * nTint.r;
float g = nBase.r * nTint.g;
float b = nBase.r * nTint.b;
ostd::Color::FloatCol nTinted(r, g, b, 1.0f);
return ostd::Color(nTinted);
}
void RawTextRenderer::drawCharacter(uint8_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint8_t* fontPixels, int32_t x, int32_t y, char c, ostd::Color color, ostd::Color background)
{
using namespace ostd;
int32_t charIndex = characterMap[c];
IPoint charCoords = CONVERT_1D_2D(charIndex, (FONT_CHAR_W * FONT_H_CHARS * 4));
int32_t screenx = x * 4, screeny = y;
ostd::Color tintedColor;
bool applyBackground = false;
for (int32_t y = charCoords.y; y < charCoords.y + (FONT_CHAR_H); y += 1)
{
for (int32_t x = charCoords.x; x < charCoords.x + (FONT_CHAR_W * 4); x += 4)
{
int32_t index = CONVERT_2D_1D(x, y, (FONT_CHAR_W * FONT_H_CHARS * 4));
int32_t screenIndex = CONVERT_2D_1D(screenx, screeny, (screenWidth * 4));
screenx += 4;
if (fontPixels[index] == 0x00 && fontPixels[index + 1] == 0x00 && fontPixels[index + 2] == 0x00)
{
if (background.a == 0)
continue;
applyBackground = true;
}
if (applyBackground)
{
screenPixels[screenIndex + 0] = background.b;
screenPixels[screenIndex + 1] = background.g;
screenPixels[screenIndex + 2] = background.r;
screenPixels[screenIndex + 3] = 255;
applyBackground = false;
continue;
}
tintedColor = applyTint({ fontPixels[index], fontPixels[index + 1], fontPixels[index + 2], 255 }, color);
screenPixels[screenIndex + 0] = tintedColor.b;
screenPixels[screenIndex + 1] = tintedColor.g;
screenPixels[screenIndex + 2] = tintedColor.r;
screenPixels[screenIndex + 3] = fontPixels[index + 3];
}
screeny += 1;
screenx = x * 4;
}
}
}

View file

@ -1,32 +0,0 @@
#pragma once
#include <unordered_map>
#include <ostd/Color.hpp>
namespace dragon
{
class RawTextRenderer
{
private:
inline static std::unordered_map<char, int32_t> characterMap;
public:
static void initialize(void);
static bool drawString(ostd::String str, uint32_t column, uint32_t row, uint32_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint32_t* fontPixels, ostd::Color color = { 255, 255, 255, 255 }, ostd::Color background = { 255, 255, 255, 0 });
private:
static int32_t getCharacterIndex(char c);
static ostd::Color applyTint(ostd::Color baseColor, ostd::Color tintColor);
static void drawCharacter(uint8_t* screenPixels, int32_t screenWidth, int32_t screenHeight, uint8_t* fontPixels, int32_t x, int32_t y, char c, ostd::Color color = { 255, 255, 255, 255 }, ostd::Color background = { 255, 255, 255, 0 });
public:
inline static constexpr int32_t FONT_CHAR_W = 11;
inline static constexpr int32_t FONT_CHAR_H = 26;
inline static constexpr int32_t FONT_V_CHARS = 6;
inline static constexpr int32_t FONT_H_CHARS = 16;
inline static constexpr int32_t CONSOLE_CHARS_H = 90;
inline static constexpr int32_t CONSOLE_CHARS_V = 21;
inline static int8_t s_cursor_pos_x = 0;
};
}

View file

@ -1,70 +0,0 @@
#include "Renderer.hpp"
#include "Window.hpp"
#include <ostd/Utils.hpp>
namespace dragon
{
Renderer::~Renderer(void)
{
if (isInvalid()) return;
ostd::Utils::destroyArray(m_pixels);
SDL_DestroyTexture(m_texture);
}
void Renderer::initialize(Window& parent)
{
if (isValid()) return; //TODO: Error
if (!parent.isValid() || !parent.isInitialized())
return; //TODO: Error
m_parent = &parent;
m_pixels = ostd::Utils::createArray<uint32_t>(parent.getWindowWidth() * parent.getWindowHeight());
m_texture = SDL_CreateTexture(parent.getSDLRenderer(), SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, parent.getWindowWidth(), parent.getWindowHeight());
m_windowWidth = parent.getWindowWidth();
m_windowHeight = parent.getWindowHeight();
setTypeName("dragon::Renderer");
enableSignals();
connectSignal(ostd::tBuiltinSignals::WindowResized);
validate();
}
void Renderer::handleSignal(ostd::tSignal& signal)
{
if (isInvalid()) return;
if (signal.ID == ostd::tBuiltinSignals::WindowResized)
{
m_pixels = ostd::Utils::resizeArray<uint32_t>(m_pixels, m_parent->getWindowWidth() * m_parent->getWindowHeight());
SDL_DestroyTexture(m_texture);
m_texture = SDL_CreateTexture(m_parent->getSDLRenderer(), SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, m_parent->getWindowWidth(), m_parent->getWindowHeight());
m_windowWidth = m_parent->getWindowWidth();
m_windowHeight = m_parent->getWindowHeight();
updateBuffer();
displayBuffer();
}
}
void Renderer::updateBuffer(void)
{
if (isInvalid()) return;
SDL_UpdateTexture(m_texture, NULL, m_pixels, m_windowWidth * 4);
}
void Renderer::displayBuffer(void)
{
if (isInvalid()) return;
SDL_Rect rect { 0, 0, m_windowWidth, m_windowHeight };
SDL_RenderCopy(m_parent->getSDLRenderer(), m_texture, NULL, &rect);
}
void Renderer::clear(const ostd::Color& color)
{
if (isInvalid()) return;
for (int32_t y = 0; y < m_windowHeight; y++)
{
for (uint32_t x = 0; x < m_windowWidth; x++)
{
int32_t index = CONVERT_2D_1D(x, y, m_windowWidth);
m_pixels[index] = color.asInteger(ostd::Color::eColorFormat::ARGB);
}
}
}
}

View file

@ -1,29 +0,0 @@
#pragma once
#include <ostd/Color.hpp>
#include "../tools/SDLInclude.hpp" // IWYU pragma: keep
namespace dragon
{
class Window;
class Renderer : public ostd::BaseObject
{
public:
inline Renderer(void) { invalidate(); }
~Renderer(void);
void initialize(Window& parent);
void handleSignal(ostd::tSignal& signal) override;
void updateBuffer(void);
void displayBuffer(void);
inline uint32_t* getScreenPixels(void) { return m_pixels; }
void clear(const ostd::Color& color);
private:
uint32_t* m_pixels { nullptr };
SDL_Texture* m_texture { nullptr };
Window* m_parent { nullptr };
int32_t m_windowWidth { 0 };
int32_t m_windowHeight { 0 };
};
}

View file

@ -1,176 +0,0 @@
#include "Window.hpp"
namespace dragon
{
Window::~Window(void)
{
onDestroy();
SDL_FreeSurface(m_fontSurface);
SDL_DestroyRenderer(m_renderer);
SDL_DestroyWindow(m_window);
IMG_Quit();
SDL_Quit();
}
void Window::initialize(int32_t width, int32_t height, const ostd::String& windowTitle, const ostd::String& fontPath)
{
if (m_initialized) return;
m_windowWidth = width;
m_windowHeight = height;
m_title = windowTitle;
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
printf( "SDL could not initialize! Error: %s\n", SDL_GetError() );
exit(1);
}
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
printf( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
exit(2);
}
m_window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_windowWidth, m_windowHeight, SDL_WINDOW_RESIZABLE);
SDL_SetWindowResizable(m_window, SDL_FALSE);
m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED);
SDL_SetWindowMinimumSize(m_window, m_windowWidth, m_windowHeight);
SDL_SetWindowTitle(m_window, m_title.c_str());
m_fontSurface = SDL_LoadBMP(fontPath.c_str());
if (m_fontSurface == NULL)
out.bg(ostd::ConsoleColors::Red).p("Error loading font.").reset().nl();
m_fontPixels = (uint32_t*)m_fontSurface->pixels;
SDL_Surface* icon = IMG_Load("icon.png");
if (icon == NULL)
{
printf("Failed to load icon: %s\n", IMG_GetError());
}
else
{
SDL_SetWindowIcon(m_window, icon);
SDL_FreeSurface(icon);
}
m_initialized = true;
m_running = true;
setTypeName("dragon::Window");
enableSignals(true);
validate();
onInitialize();
}
void Window::update(void)
{
if (!m_initialized) return;
Uint64 start = SDL_GetPerformanceCounter();
handleEvents();
if (m_refreshScreen)
SDL_RenderClear(m_renderer);
onUpdate();
onRender();
SDL_RenderPresent(m_renderer);
Uint64 end = SDL_GetPerformanceCounter();
float elapsed = (end - start) / (float)SDL_GetPerformanceFrequency();
m_redrawAccumulator += elapsed;
if (m_redrawAccumulator >= 0.2f)
{
onFixedUpdate();
m_redrawAccumulator = 0.0f;
}
end = SDL_GetPerformanceCounter();
elapsed = (end - start) / (float)SDL_GetPerformanceFrequency();
m_timeAccumulator += elapsed;
if (m_timeAccumulator >= 0.5f)
{
onSlowUpdate();
m_fps = (int32_t)(1.0f / elapsed);
m_timeAccumulator = 0.0f;
}
}
void Window::setSize(int32_t width, int32_t height)
{
if (!isInitialized()) return;
SDL_SetWindowSize(m_window, width, height);
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::WindowResized, ostd::tSignalPriority::RealTime);
}
void Window::setTitle(const ostd::String& title)
{
if (!isInitialized()) return;
m_title = title;
SDL_SetWindowTitle(m_window, m_title.c_str());
}
void Window::handleEvents(void)
{
if (!m_initialized) return;
auto l_getMouseState = [this](void) -> MouseEventData {
int32_t mx = 0, my = 0;
uint32_t btn = SDL_GetMouseState(&mx, &my);
MouseEventData::eButton button = MouseEventData::eButton::None;
switch (btn)
{
case SDL_BUTTON(1): button = MouseEventData::eButton::Left; break;
case SDL_BUTTON(2): button = MouseEventData::eButton::Middle; break;
case SDL_BUTTON(3): button = MouseEventData::eButton::Right; break;
default: button = MouseEventData::eButton::None; break;
}
MouseEventData mmd(*this, mx, my, button);
return mmd;
};
SDL_Event event;
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
m_running = false;
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::WindowClosed, ostd::tSignalPriority::Normal, *this);
}
else if (event.type == SDL_WINDOWEVENT)
{
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
WindowResizedData wrd(*this, m_windowWidth, m_windowHeight, 0, 0);
SDL_GetWindowSize(m_window, &m_windowWidth, &m_windowHeight);
wrd.new_width = m_windowWidth;
wrd.new_height = m_windowHeight;
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::WindowResized, ostd::tSignalPriority::RealTime, wrd);
}
}
else if (event.type == SDL_MOUSEMOTION)
{
MouseEventData mmd = l_getMouseState();
if (isMouseDragEventEnabled() && mmd.button != MouseEventData::eButton::None)
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::WindowClosed, ostd::tSignalPriority::RealTime, mmd);
else
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::MouseMoved, ostd::tSignalPriority::RealTime, mmd);
}
else if (event.type == SDL_MOUSEBUTTONDOWN)
{
MouseEventData mmd = l_getMouseState();
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::MousePressed, ostd::tSignalPriority::RealTime, mmd);
}
else if (event.type == SDL_MOUSEBUTTONUP)
{
MouseEventData mmd = l_getMouseState();
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::MouseReleased, ostd::tSignalPriority::RealTime, mmd);
}
else if (event.type == SDL_KEYDOWN)
{
KeyEventData ked(*this, (int32_t)event.key.keysym.sym, 0, KeyEventData::eKeyEvent::Pressed);
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::KeyPressed, ostd::tSignalPriority::RealTime, ked);
}
else if (event.type == SDL_KEYUP)
{
KeyEventData ked(*this, (int32_t)event.key.keysym.sym, 0, KeyEventData::eKeyEvent::Released);
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::KeyReleased, ostd::tSignalPriority::RealTime, ked);
}
else if (event.type == SDL_TEXTINPUT)
{
KeyEventData ked(*this, 0, event.text.text[0], KeyEventData::eKeyEvent::Text);
ostd::SignalHandler::emitSignal(ostd::tBuiltinSignals::TextEntered, ostd::tSignalPriority::RealTime, ked);
}
}
}
}

View file

@ -1,117 +0,0 @@
#pragma once
#include "../tools/SDLInclude.hpp" // IWYU pragma: keep
#include <ostd/Utils.hpp>
#include <ostd/Signals.hpp>
#include <ostd/IOHandlers.hpp>
namespace dragon
{
class Window : public ostd::BaseObject
{
public:
inline Window(void) { }
~Window(void);
inline Window(int32_t width, int32_t height, const ostd::String& windowTitle, const ostd::String& fontPath) { initialize(width, height, windowTitle, fontPath); }
void initialize(int32_t width, int32_t height, const ostd::String& windowTitle, const ostd::String& fontPath);
void update(void);
void setSize(int32_t width, int32_t height);
void setTitle(const ostd::String& title);
inline virtual void onRender(void) { }
inline virtual void onUpdate(void) { }
inline virtual void onFixedUpdate(void) { }
inline virtual void onSlowUpdate(void) { }
inline virtual void onInitialize(void) { }
inline virtual void onDestroy(void) { }
inline bool isInitialized(void) const { return m_initialized; }
inline bool isRunning(void) const { return m_running; }
inline bool isVisible(void) const { return m_visible; }
inline void hide(void) { SDL_HideWindow(m_window); m_visible = false; }
inline void show(void) { SDL_ShowWindow(m_window); m_visible = true; }
inline ostd::String getTitle(void) const { return m_title; }
inline int32_t getFPS(void) const { return m_fps; }
inline int32_t getWindowWidth(void) const { return m_windowWidth; }
inline int32_t getWindowHeight(void) const { return m_windowHeight; }
inline SDL_Renderer* getSDLRenderer(void) const { return m_renderer; }
inline bool isMouseDragEventEnabled(void) const { return m_deagEventEnabled; }
inline void enableMouseDragEvent(bool enable = true) { m_deagEventEnabled = enable; }
private:
void handleEvents(void);
protected:
ostd::ConsoleOutputHandler out;
SDL_Window* m_window { nullptr };
SDL_Renderer* m_renderer { nullptr };
SDL_Surface* m_fontSurface { nullptr };
uint32_t* m_fontPixels { nullptr };
bool m_refreshScreen { true };
private:
int32_t m_windowWidth { 0 };
int32_t m_windowHeight { 0 };
ostd::String m_title { "" };
int32_t m_fps { 0 };
float m_timeAccumulator { 0.0f };
float m_redrawAccumulator { 0.0f };
bool m_deagEventEnabled { false };
bool m_running { false };
bool m_initialized { false };
bool m_visible { true };
};
class WindowResizedData : public ostd::BaseObject
{
public:
inline WindowResizedData(Window& parent, int32_t _oldx, int32_t _oldy, int32_t _newx, int32_t _newy) : parentWindow(parent), old_width(_oldx), old_height(_oldy), new_width(_newx), new_height(_newy)
{
setTypeName("dragon::WindowResizedData");
validate();
}
public:
int32_t new_width;
int32_t new_height;
int32_t old_width;
int32_t old_height;
Window& parentWindow;
};
class MouseEventData : public ostd::BaseObject
{
public: enum class eButton { None = 0, Left, Middle, Right };
public:
inline MouseEventData(Window& parent, int32_t mousex, int32_t mousey, eButton btn) : parentWindow(parent), position_x(mousex), position_y(mousey), button(btn)
{
setTypeName("dragon::MouseEventData");
validate();
}
public:
int32_t position_x;
int32_t position_y;
eButton button;
Window& parentWindow;
};
class KeyEventData : public ostd::BaseObject
{
public: enum class eKeyEvent { Pressed = 0, Released, Text };
public:
inline KeyEventData(Window& parent, int32_t key, char _text, eKeyEvent evt) : parentWindow(parent), keyCode(key), text(_text), eventType(evt)
{
setTypeName("dragon::KeyEventData");
validate();
}
public:
int32_t keyCode;
char text;
eKeyEvent eventType;
Window& parentWindow;
};
}

View file

@ -1,5 +1,5 @@
#include "VirtualDisplay.hpp"
#include "../gui/RawTextRenderer.hpp"
#include <ogfx/PixelRenderer.hpp>
#include "../runtime/DragonRuntime.hpp"
#include "../tools/GlobalData.hpp"
@ -10,7 +10,7 @@ namespace dragon
void VirtualDisplay::onInitialize(void)
{
m_renderer.initialize(*this);
RawTextRenderer::initialize();
ogfx::PixelRenderer::TextRenderer::initialize();
text16_load_palettes();
m_currentPaletteID = DragonRuntime::machine_config.text16_palette;
@ -44,9 +44,9 @@ namespace dragon
{
auto& line = m_singleTextLines[i];
if (invert_colors == 0)
RawTextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground, config.singleColor_background);
ogfx::PixelRenderer::TextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_foreground, config.singleColor_background);
else
RawTextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_background, config.singleColor_foreground);
ogfx::PixelRenderer::TextRenderer::drawString(line, 0, i, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_background, config.singleColor_foreground);
}
m_refreshScreen = false;
}
@ -58,14 +58,14 @@ namespace dragon
uint8_t clear_color = mem.read8(vga_addr + tRegisters::ClearColor);
ostd::Color clearColor = m_text16_Currentpalette->getColor(clear_color);
m_renderer.clear(clearColor);
for (int32_t i = 0; i < RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::CONSOLE_CHARS_H; i++)
for (int32_t i = 0; i < ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V * ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H; i++)
{
auto& cell = m_text16_buffer[i];
ostd::Color background = m_text16_Currentpalette->getColor(cell.backgroundColor);
ostd::Color foreground = m_text16_Currentpalette->getColor(cell.foregroundColor);
char character = static_cast<char>(cell.character);
auto xy = CONVERT_1D_2D(i, RawTextRenderer::CONSOLE_CHARS_H);
RawTextRenderer::drawString(ostd::String().addChar(character), xy.x, xy.y, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, foreground, background);
auto xy = CONVERT_1D_2D(i, ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H);
ogfx::PixelRenderer::TextRenderer::drawString(ostd::String().addChar(character), xy.x, xy.y, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, foreground, background);
}
m_refreshScreen = false;
}
@ -147,9 +147,9 @@ namespace dragon
int16_t y = mem.read16(vga_addr + tRegisters::MemControllerY);
//TODO: Remove this override used for testing purposes
// for (int32_t i = 0; i < RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::CONSOLE_CHARS_H; i++)
// for (int32_t i = 0; i < ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V * ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H; i++)
// {
// auto xy = CONVERT_1D_2D(i, RawTextRenderer::CONSOLE_CHARS_H);
// auto xy = CONVERT_1D_2D(i, ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H);
// DragonRuntime::vGraphicsInterface.writeVRAM_16Colors(static_cast<uint8_t>(xy.x), static_cast<uint8_t>(xy.y), c++, 0, 15);
// if (c > 'Z')
// c = 'A';
@ -189,7 +189,7 @@ namespace dragon
mem.write8(vga_addr + tRegisters::Signal, tSignalValues::Continue);
}
void VirtualDisplay::onFixedUpdate(void)
void VirtualDisplay::onFixedUpdate(double frameTime_s)
{
auto& config = DragonRuntime::machine_config;
auto& mem = DragonRuntime::memMap;
@ -200,20 +200,15 @@ namespace dragon
{
m_refreshScreen = true;
dragon::hw::interface::Graphics::tText16_Cell outTextCell;
for (int32_t i = 0; i < RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::CONSOLE_CHARS_H; i++)
for (int32_t i = 0; i < ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V * ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H; i++)
{
auto xy = CONVERT_1D_2D(i, RawTextRenderer::CONSOLE_CHARS_H);
auto xy = CONVERT_1D_2D(i, ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H);
DragonRuntime::vGraphicsInterface.readVRAM_16Colors(xy.x, xy.y, outTextCell);
m_text16_buffer[i] = outTextCell;
}
}
}
void VirtualDisplay::onSlowUpdate(void)
{
std::cout << (int)getFPS() << "\n";
}
void VirtualDisplay::__redraw_screen(void)
{
m_renderer.updateBuffer();
@ -232,9 +227,9 @@ namespace dragon
{
m_singleTextLines.push_back(ostd::String().addChar(c));
if (invert_colors == 0)
RawTextRenderer::drawString(ostd::String().addChar(c), 0, 0, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground, config.singleColor_background);
ogfx::PixelRenderer::TextRenderer::drawString(ostd::String().addChar(c), 0, 0, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_foreground, config.singleColor_background);
else
RawTextRenderer::drawString(ostd::String().addChar(c), 0, 0, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_background, config.singleColor_foreground);
ogfx::PixelRenderer::TextRenderer::drawString(ostd::String().addChar(c), 0, 0, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_background, config.singleColor_foreground);
return;
}
auto& line = m_singleTextLines[m_singleTextLines.size() - 1];
@ -242,26 +237,26 @@ namespace dragon
m_singleTextLines.push_back("");
else if (isprint(c))
{
if (line.len() == RawTextRenderer::CONSOLE_CHARS_H)
if (line.len() == ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H)
{
m_singleTextLines.push_back(ostd::String().addChar(c));
auto& line = m_singleTextLines[m_singleTextLines.size() - 1];
if (invert_colors == 0)
RawTextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground, config.singleColor_background);
ogfx::PixelRenderer::TextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_foreground, config.singleColor_background);
else
RawTextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_background, config.singleColor_foreground);
ogfx::PixelRenderer::TextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_background, config.singleColor_foreground);
}
else
{
line.addChar(c);
if (invert_colors == 0)
RawTextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_foreground, config.singleColor_background);
ogfx::PixelRenderer::TextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_foreground, config.singleColor_background);
else
RawTextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_fontPixels, config.singleColor_background, config.singleColor_foreground);
ogfx::PixelRenderer::TextRenderer::drawString(ostd::String().addChar(c), line.len() - 1, m_singleTextLines.size() - 1, m_renderer.getScreenPixels(), getWindowWidth(), getWindowHeight(), m_font.m_fontPixels, config.singleColor_background, config.singleColor_foreground);
}
}
else return;
if (m_singleTextLines.size() == RawTextRenderer::CONSOLE_CHARS_V + 1)
if (m_singleTextLines.size() == ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V + 1)
{
m_refreshScreen = true;
m_singleTextLines.erase(m_singleTextLines.begin());
@ -270,7 +265,7 @@ namespace dragon
void VirtualDisplay::single_text_add_char_to_buffer(char c)
{
if (c == '\n' || m_singleTextBuffer.len() == RawTextRenderer::CONSOLE_CHARS_H)
if (c == '\n' || m_singleTextBuffer.len() == ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H)
{
single_text_print_buffer_and_flush();
single_text_add_char_to_line(c);
@ -311,7 +306,7 @@ namespace dragon
void VirtualDisplay::text16_init_buffer(void)
{
for (int32_t i = 0; i < RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::CONSOLE_CHARS_H; i++)
for (int32_t i = 0; i < ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V * ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H; i++)
m_text16_buffer.push_back({ 0, 0, ' ' });
}

View file

@ -1,7 +1,7 @@
#pragma once
#include "../gui/Window.hpp"
#include "../gui/Renderer.hpp"
#include <ogfx/WindowBase.hpp>
#include <ogfx/PixelRenderer.hpp>
#include "../hardware/VirtualIODevices.hpp"
namespace dragon
@ -9,13 +9,13 @@ namespace dragon
namespace data { class IBiosVideoPalette; }
namespace hw
{
class VirtualDisplay : public Window
class VirtualDisplay : public ogfx::WindowBase
{
public: struct tRegisters
{
inline static constexpr uint8_t VideoMode = 0x00;
inline static constexpr uint8_t ClearColor = 0x01;
inline static constexpr uint8_t Palette = 0x02;
inline static constexpr uint8_t VideoMode = 0x00;
inline static constexpr uint8_t ClearColor = 0x01;
inline static constexpr uint8_t Palette = 0x02;
inline static constexpr uint8_t Signal = 0x03;
inline static constexpr uint8_t TextSingleCharacter = 0x04;
inline static constexpr uint8_t TextSingleInvertColors = 0x05;
@ -31,35 +31,36 @@ namespace dragon
};
public: struct tVideoModeValues
{
inline static constexpr uint8_t TextSingleColor = 0x00;
inline static constexpr uint8_t Text16Colors = 0x01;
inline static constexpr uint8_t TextSingleColor = 0x00;
inline static constexpr uint8_t Text16Colors = 0x01;
};
public: struct tSignalValues
{
inline static constexpr uint8_t Continue = 0x00;
inline static constexpr uint8_t Continue = 0x00;
inline static constexpr uint8_t TextSingleColor_DirectPrintChar = 0x02;
inline static constexpr uint8_t TextSingleColor_StoreChar = 0x03;
inline static constexpr uint8_t TextSingleColor_DirectPrintBuffAndFlush = 0x04;
inline static constexpr uint8_t TextSingleColor_FlushBuffer = 0x05;
inline static constexpr uint8_t TextSingleColor_DirectPrintBuffNoFlush = 0x06;
inline static constexpr uint8_t TextSingleColor_DirectPrintChar = 0x02;
inline static constexpr uint8_t TextSingleColor_StoreChar = 0x03;
inline static constexpr uint8_t TextSingleColor_DirectPrintBuffAndFlush = 0x04;
inline static constexpr uint8_t TextSingleColor_FlushBuffer = 0x05;
inline static constexpr uint8_t TextSingleColor_DirectPrintBuffNoFlush = 0x06;
inline static constexpr uint8_t TextSingleColor_DirectPrintString = 0x07;
inline static constexpr uint8_t Text16Color_SwapBuffers = 0x10;
inline static constexpr uint8_t Text16Color_WriteMemory = 0x11;
inline static constexpr uint8_t Text16Color_Scroll = 0x12;
inline static constexpr uint8_t RefreshScreen = 0xE0;
inline static constexpr uint8_t ClearSCreen = 0xE1;
inline static constexpr uint8_t RedrawScreen = 0xE2;
inline static constexpr uint8_t RefreshScreen = 0xE0;
inline static constexpr uint8_t ClearSCreen = 0xE1;
inline static constexpr uint8_t RedrawScreen = 0xE2;
};
public:
inline void setFont(const ostd::String& fontPath) { m_font.init(fontPath); }
void onInitialize(void) override;
void onDestroy(void) override;
void onRender(void) override;
void onUpdate(void) override;
void onFixedUpdate(void) override;
void onSlowUpdate(void) override;
void onFixedUpdate(double frameTime_s) override;
inline void redrawScreen(void) { m_redrawScreen = true; }
@ -79,7 +80,8 @@ namespace dragon
void text16_load_palettes(void);
private:
Renderer m_renderer;
ogfx::PixelRenderer m_renderer;
ogfx::PixelRenderer::Font m_font;
std::vector<ostd::String> m_singleTextLines;
ostd::String m_singleTextBuffer { "" };
@ -92,4 +94,4 @@ namespace dragon
bool m_redrawScreen { true };
};
}
}
}

View file

@ -6,7 +6,7 @@
#include "VirtualCPU.hpp"
#include "../runtime/DragonRuntime.hpp"
#include "../gui/RawTextRenderer.hpp"
#include <ogfx/PixelRenderer.hpp>
//TODO: Fix all access functions (reads and writes) ensuring the address is not out of bounds.
// Right now the check is done, but just to push an error if out of bounds; the address
@ -173,18 +173,18 @@ namespace dragon
const auto& state = SDL_GetKeyboardState(nullptr);
if (signal.ID == ostd::tBuiltinSignals::KeyPressed || signal.ID == ostd::tBuiltinSignals::KeyReleased)
{
KeyEventData& ked = (KeyEventData&)signal.userData;
ogfx::KeyEventData& ked = (ogfx::KeyEventData&)signal.userData;
m_modifiersBitFiels = __construct_modifiers_bitfield();
__write16(tRegisters::Modifiers, (int16_t)m_modifiersBitFiels.value);
__write16(tRegisters::KeyCode, __sdl_key_code_convert(ked.keyCode));
if (ked.eventType == KeyEventData::eKeyEvent::Pressed)
if (ked.eventType == ogfx::KeyEventData::eKeyEvent::Pressed)
cpu.handleInterrupt(data::InterruptCodes::KeyPressed, true);
else if (ked.eventType == KeyEventData::eKeyEvent::Pressed)
else if (ked.eventType == ogfx::KeyEventData::eKeyEvent::Pressed)
cpu.handleInterrupt(data::InterruptCodes::KeyReleased, true);
}
else if (signal.ID == ostd::tBuiltinSignals::TextEntered)
{
KeyEventData& ked = (KeyEventData&)signal.userData;
ogfx::KeyEventData& ked = (ogfx::KeyEventData&)signal.userData;
m_modifiersBitFiels = __construct_modifiers_bitfield();
__write16(tRegisters::Modifiers, (int16_t)m_modifiersBitFiels.value);
__write16(tRegisters::KeyCode, (int16_t)ked.text);
@ -661,7 +661,7 @@ namespace dragon
{
m_videoMemory.init(0xFFFF);
m_vramStart = data::MemoryMapAddresses::VideoCardInterface_End - data::MemoryMapAddresses::VideoCardInterface_Start;
m_16Color_frameSize = RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::CONSOLE_CHARS_V * m_16Color_cellSize;
m_16Color_frameSize = ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H * ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V * m_16Color_cellSize;
m_16Color_currentFrameAddr = m_vramStart;
m_16Color_secondFrameAddr = m_vramStart + m_16Color_frameSize;
}
@ -737,7 +737,7 @@ namespace dragon
bool Graphics::readVRAM_16Colors(uint8_t x, uint8_t y, Graphics::tText16_Cell& outTextCell)
{
uint16_t cellOffset = static_cast<uint16_t>(CONVERT_2D_1D(x, y, RawTextRenderer::CONSOLE_CHARS_H)) * 4;
uint16_t cellOffset = static_cast<uint16_t>(CONVERT_2D_1D(x, y, ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H)) * 4;
cellOffset += m_16Color_currentFrameAddr;
int8_t outVal = 0;
if (!m_videoMemory.r_Byte(cellOffset + tText16_CellStructure::character, outVal))
@ -754,7 +754,7 @@ namespace dragon
bool Graphics::writeVRAM_16Colors(uint8_t x, uint8_t y, uint8_t character, uint8_t background, uint8_t foreground)
{
uint16_t cellOffset = static_cast<uint16_t>(CONVERT_2D_1D(x, y, RawTextRenderer::CONSOLE_CHARS_H)) * 4;
uint16_t cellOffset = static_cast<uint16_t>(CONVERT_2D_1D(x, y, ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H)) * 4;
if (!readFlag(tFlags::DoubleBufferingEnabled))
cellOffset += m_16Color_currentFrameAddr;
else
@ -800,7 +800,7 @@ namespace dragon
void Graphics::scroll_16Colors(void)
{
int32_t line_len = (RawTextRenderer::CONSOLE_CHARS_H * 4);
int32_t line_len = (ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H * 4);
for (int32_t i = m_16Color_currentFrameAddr + line_len; i < m_16Color_currentFrameAddr + m_16Color_frameSize; i += 4)
{
int32_t k = i;

View file

@ -1,6 +1,6 @@
#include "DragonRuntime.hpp"
#include <ostd/Defines.hpp>
#include "../gui/RawTextRenderer.hpp"
#include <ogfx/PixelRenderer.hpp>
namespace dragon
{
@ -144,9 +144,10 @@ namespace dragon
if (verbose)
out.fg(ostd::ConsoleColors::Magenta).p(" Initializing virtual display:").nl();
int32_t w = RawTextRenderer::CONSOLE_CHARS_H * RawTextRenderer::FONT_CHAR_W; //60 * 16;
int32_t h = RawTextRenderer::CONSOLE_CHARS_V * RawTextRenderer::FONT_CHAR_H; //60 * 9;
vDisplay.initialize(w, h, "DragonVM", "font.bmp");
int32_t w = ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H * ogfx::PixelRenderer::TextRenderer::FONT_CHAR_W; //60 * 16;
int32_t h = ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V * ogfx::PixelRenderer::TextRenderer::FONT_CHAR_H; //60 * 9;
vDisplay.initialize(w, h, "DragonVM");
vDisplay.setFont("font.bmp");
if (hideVirtualDisplay)
vDisplay.hide();
if (verbose)
@ -320,8 +321,8 @@ namespace dragon
vCMOS.write16(data::CMOSRegisters::MemorySize, data::MemoryMapAddresses::Memory_End);
vCMOS.write16(data::CMOSRegisters::ClockSpeed, machine_config.clock_rate_sec);
vCMOS.write8(data::CMOSRegisters::ScreenRedrawRate, machine_config.screen_redraw_rate_per_second);
vCMOS.write16(data::CMOSRegisters::ScreenWidth, static_cast<int16_t>(RawTextRenderer::CONSOLE_CHARS_H));
vCMOS.write16(data::CMOSRegisters::ScreenHeight, static_cast<int16_t>(RawTextRenderer::CONSOLE_CHARS_V));
vCMOS.write16(data::CMOSRegisters::ScreenWidth, static_cast<int16_t>(ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_H));
vCMOS.write16(data::CMOSRegisters::ScreenHeight, static_cast<int16_t>(ogfx::PixelRenderer::TextRenderer::CONSOLE_CHARS_V));
vCMOS.write16(data::CMOSRegisters::StackSize, 0x1000);
ostd::BitField_16 disk_list_bitfield;
disk_list_bitfield.value = 0;