From 15d9d1265fc8d544e824c23671b3a1d0fb90409d Mon Sep 17 00:00:00 2001 From: OmniaX-Dev Date: Sun, 12 Apr 2026 14:48:24 +0200 Subject: [PATCH] Implemented new BasicRenderer2D with native SFML3 (and remove SDL3_gfx dependency) --- .clangd | 3 +- CMakeLists.txt | 7 - other/TODO.txt | 3 + other/build.nr | 2 +- other/create_release.sh | 3 - src/ogfx/gui/RawTextInput.cpp | 6 +- src/ogfx/gui/Window.cpp | 1 + src/ogfx/gui/Window.hpp | 1 + src/ogfx/gui/WindowOutputHandler.cpp | 16 +- src/ogfx/gui/widgets/CheckBox.cpp | 2 +- src/ogfx/gui/widgets/Label.cpp | 2 +- src/ogfx/render/BasicRenderer.cpp | 1116 ++++- src/ogfx/render/BasicRenderer.hpp | 111 +- src/ogfx/render/FontUtils.cpp | 280 -- src/ogfx/render/FontUtils.hpp | 91 - src/ogfx/resources/Image.hpp | 2 +- src/ogfx/utils/SDLInclude.hpp | 1 - src/ogfx/vendor/sdl3_gfx/SDL3_framerate.c | 189 - src/ogfx/vendor/sdl3_gfx/SDL3_framerate.h | 100 - src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives.c | 3794 ----------------- src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives.h | 241 -- .../vendor/sdl3_gfx/SDL3_gfxPrimitives_font.h | 3106 -------------- src/ogfx/vendor/sdl3_gfx/SDL3_imageFilter.c | 1617 ------- src/ogfx/vendor/sdl3_gfx/SDL3_imageFilter.h | 161 - src/ogfx/vendor/sdl3_gfx/SDL3_rotozoom.c | 1636 ------- src/ogfx/vendor/sdl3_gfx/SDL3_rotozoom.h | 123 - src/ostd/data/Color.cpp | 44 +- src/ostd/data/Color.hpp | 26 +- src/ostd/io/IOHandlers.hpp | 1 - src/ostd/io/Json.cpp | 8 +- src/ostd/math/Geometry.hpp | 91 +- src/test/GraphicsWindowTest.cpp | 41 +- src/test/GuiTest.cpp | 27 +- 33 files changed, 1266 insertions(+), 11586 deletions(-) delete mode 100644 src/ogfx/render/FontUtils.cpp delete mode 100644 src/ogfx/render/FontUtils.hpp delete mode 100644 src/ogfx/vendor/sdl3_gfx/SDL3_framerate.c delete mode 100644 src/ogfx/vendor/sdl3_gfx/SDL3_framerate.h delete mode 100644 src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives.c delete mode 100644 src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives.h delete mode 100644 src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives_font.h delete mode 100644 src/ogfx/vendor/sdl3_gfx/SDL3_imageFilter.c delete mode 100644 src/ogfx/vendor/sdl3_gfx/SDL3_imageFilter.h delete mode 100644 src/ogfx/vendor/sdl3_gfx/SDL3_rotozoom.c delete mode 100644 src/ogfx/vendor/sdl3_gfx/SDL3_rotozoom.h diff --git a/.clangd b/.clangd index 32169b9..122ab09 100644 --- a/.clangd +++ b/.clangd @@ -1,3 +1,2 @@ CompileFlags: - CompilationDatabase: bin - Add: ["--target=x86_64-w64-mingw32"] \ No newline at end of file + CompilationDatabase: bin \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 53e6a9b..aac59d2 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,12 +79,6 @@ list(APPEND OSTD_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/src/ostd/utils/Time.cpp ) list(APPEND OGFX_SOURCE_FILES - # sdl3_gfx - ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/vendor/sdl3_gfx/SDL3_framerate.c - ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives.c - ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/vendor/sdl3_gfx/SDL3_imageFilter.c - ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/vendor/sdl3_gfx/SDL3_rotozoom.c - # gui ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/RawTextInput.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/Window.cpp @@ -100,7 +94,6 @@ list(APPEND OGFX_SOURCE_FILES # render ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/FontUtils.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/PixelRenderer.cpp # resources diff --git a/other/TODO.txt b/other/TODO.txt index 0ba0158..91db5f1 100644 --- a/other/TODO.txt +++ b/other/TODO.txt @@ -11,6 +11,9 @@ ***Implement margin for widgets ***Implement mouse scroll callback Add theme caching +Implement callback for state changes in checkbox +FIX: WindowOutputHandler text rendering +find a way to add fixed update to gui::Window Implement following widgets: diff --git a/other/build.nr b/other/build.nr index fd57c18..8cb1ed8 100644 --- a/other/build.nr +++ b/other/build.nr @@ -1 +1 @@ -2054 +2056 diff --git a/other/create_release.sh b/other/create_release.sh index 0a0aa33..71f6dd4 100755 --- a/other/create_release.sh +++ b/other/create_release.sh @@ -56,7 +56,6 @@ cp -r ../src/ostd/vendor/nlohmann $RELEASE_DIR/include/ostd/vendor/ # OGFX -mkdir -p $RELEASE_DIR/include/ogfx/vendor/sdl3_gfx mkdir -p $RELEASE_DIR/include/ogfx/gui mkdir -p $RELEASE_DIR/include/ogfx/gui/widgets mkdir -p $RELEASE_DIR/include/ogfx/render @@ -68,5 +67,3 @@ find ../src/ogfx/gui/widgets -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/ find ../src/ogfx/render -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/include/ogfx/render \; find ../src/ogfx/resources -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/include/ogfx/resources \; find ../src/ogfx/utils -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/include/ogfx/utils \; -find ../src/ogfx/vendor -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/include/ogfx/vendor \; -find ../src/ogfx/vendor/sdl3_gfx -maxdepth 1 -name "*.h*" -exec cp {} $RELEASE_DIR/include/ogfx/vendor/sdl3_gfx \; diff --git a/src/ogfx/gui/RawTextInput.cpp b/src/ogfx/gui/RawTextInput.cpp index 59180ae..4cd5c47 100644 --- a/src/ogfx/gui/RawTextInput.cpp +++ b/src/ogfx/gui/RawTextInput.cpp @@ -169,12 +169,12 @@ namespace ogfx tmpStr2 = ""; char c = text[i]; tmpStr1 += c; - int32_t strWidth1 = parent.m_gfx->getStringSize(tmpStr1, parent.m_fontSize).x; + int32_t strWidth1 = parent.m_gfx->getStringDimensions(tmpStr1, parent.m_fontSize).x; if (relativePosition.x > strWidth1) continue; found = true; tmpStr2 = tmpStr1.new_substr(0, tmpStr1.len() - 1); - int32_t strWidth2 = (tmpStr2.len() > 0 ? parent.m_gfx->getStringSize(tmpStr2, parent.m_fontSize).x : 0); + int32_t strWidth2 = (tmpStr2.len() > 0 ? parent.m_gfx->getStringDimensions(tmpStr2, parent.m_fontSize).x : 0); int32_t d1 = (int32_t)std::abs(relativePosition.x - strWidth2); int32_t d2 = (int32_t)std::abs(strWidth1 - relativePosition.x); if (d1 > d2) @@ -221,7 +221,7 @@ namespace ogfx if (m_cursorPosition > 0 && m_text != "") { ostd::String s1 = m_text.new_substr(0, m_cursorPosition); - strSize = gfx.getStringSize(s1, m_fontSize); + strSize = gfx.getStringDimensions(s1, m_fontSize); } gfx.outlinedRect(*this, m_theme.backgroundColor, m_theme.borderColor, 2); diff --git a/src/ogfx/gui/Window.cpp b/src/ogfx/gui/Window.cpp index 137e461..f501e90 100644 --- a/src/ogfx/gui/Window.cpp +++ b/src/ogfx/gui/Window.cpp @@ -593,6 +593,7 @@ namespace ogfx m_rootWidget.__update(); m_rootWidget.__draw(m_gfx); onRedraw(m_gfx); + m_gfx.endFrame(); after_render(); } } diff --git a/src/ogfx/gui/Window.hpp b/src/ogfx/gui/Window.hpp index b6a168d..8b75671 100644 --- a/src/ogfx/gui/Window.hpp +++ b/src/ogfx/gui/Window.hpp @@ -213,6 +213,7 @@ namespace ogfx inline virtual void onClose(void) { } inline virtual void onSDLEvent(SDL_Event& event) { } inline virtual void onRedraw(BasicRenderer2D& gfx) { } + inline virtual void onUpdate(void) { } inline virtual void onSignal(ostd::Signal& signal) { } protected: diff --git a/src/ogfx/gui/WindowOutputHandler.cpp b/src/ogfx/gui/WindowOutputHandler.cpp index 66b9e40..ab41f29 100644 --- a/src/ogfx/gui/WindowOutputHandler.cpp +++ b/src/ogfx/gui/WindowOutputHandler.cpp @@ -40,8 +40,9 @@ namespace ogfx void GraphicsWindowOutputHandler::setMonospaceFont(const String& filePath) { - m_renderer.setFont(filePath); - m_renderer.setFontSize(m_fontSize); + //TODO: Fix + // m_renderer.setFont(filePath); + // m_renderer.setFontSize(m_fontSize); __update_char_size(); } @@ -54,8 +55,8 @@ namespace ogfx } bool GraphicsWindowOutputHandler::isReady(void) - { - return m_window != nullptr && m_renderer.getTTFRenderer().hasOpenFont() && m_fontSize > 0; + {//TODO: Fix + return m_window != nullptr && /* m_renderer.getTTFRenderer().hasOpenFont() &&*/ m_fontSize > 0; } void GraphicsWindowOutputHandler::resetCursorPosition(void) @@ -119,7 +120,8 @@ namespace ogfx void GraphicsWindowOutputHandler::setFontSize(int32_t fontSize) { m_fontSize = fontSize; - m_renderer.setFontSize(m_fontSize); + //TODO: Fix + // m_renderer.setFontSize(m_fontSize); __update_char_size(); } @@ -132,7 +134,7 @@ namespace ogfx { if (fontSize > 0) { - auto size = m_renderer.getStringSize("A", fontSize); + auto size = m_renderer.getStringDimensions("A", fontSize); return { (float)size.x, (float)size.y }; } return m_charSize; @@ -426,7 +428,7 @@ namespace ogfx void GraphicsWindowOutputHandler::__update_char_size(void) { - auto size = m_renderer.getStringSize("A", m_fontSize); + auto size = m_renderer.getStringDimensions("A", m_fontSize); m_charSize = { (float)size.x, (float)size.y }; } diff --git a/src/ogfx/gui/widgets/CheckBox.cpp b/src/ogfx/gui/widgets/CheckBox.cpp index f59c3c5..e623b41 100644 --- a/src/ogfx/gui/widgets/CheckBox.cpp +++ b/src/ogfx/gui/widgets/CheckBox.cpp @@ -85,7 +85,7 @@ namespace ogfx void CheckBox::__update_size(ogfx::BasicRenderer2D& gfx) { - auto size = gfx.getStringSize(getText(), getFontSize()); + auto size = gfx.getStringDimensions(getText(), getFontSize()); m_checkSize = { static_cast(size.y), static_cast(size.y) }; size.x += m_spacing + m_checkSize.x; size.x += getPadding().left(); diff --git a/src/ogfx/gui/widgets/Label.cpp b/src/ogfx/gui/widgets/Label.cpp index 645001d..6aaf3a4 100644 --- a/src/ogfx/gui/widgets/Label.cpp +++ b/src/ogfx/gui/widgets/Label.cpp @@ -72,7 +72,7 @@ namespace ogfx void Label::__update_size(ogfx::BasicRenderer2D& gfx) { - auto size = gfx.getStringSize(getText(), getFontSize()); + auto size = gfx.getStringDimensions(getText(), getFontSize()); size.x += getPadding().left(); size.x += getPadding().right(); size.y += getPadding().top(); diff --git a/src/ogfx/render/BasicRenderer.cpp b/src/ogfx/render/BasicRenderer.cpp index 508ece1..3a2da45 100644 --- a/src/ogfx/render/BasicRenderer.cpp +++ b/src/ogfx/render/BasicRenderer.cpp @@ -20,15 +20,65 @@ #include "BasicRenderer.hpp" #include "../gui/Window.hpp" +#include "../resources/UbuntuMonoRegularTTF.hpp" + +#define COLOR_CAST(ostd_color) std::bit_cast(ostd_color.getNormalizedColor()) +#define QUAD_INDICES_ARR { 0, 1, 2, 2, 3, 0 } namespace ogfx { - void BasicRenderer2D::init(WindowCore& window) + // ===================================================== SIGNAL HANDLER ===================================================== + BasicRenderer2D::SignalHandler::SignalHandler(BasicRenderer2D& parent) : m_parent(parent) + { + enableSignals(); + connectSignal(ostd::BuiltinSignals::BeforeSDLShutdown); + setTypeName("ostd::GraphicsWindowOutputHandler::SignalHandler"); + validate(); + } + + void BasicRenderer2D::SignalHandler::handleSignal(ostd::Signal& signal) + { + if (signal.ID == ostd::BuiltinSignals::BeforeSDLShutdown) + { + m_parent.closeFont(); + } + } + // ===================================================== SIGNAL HANDLER ===================================================== + + + + + + // ===================================================== UTILS ===================================================== + BasicRenderer2D::~BasicRenderer2D(void) + { + closeFont(); + } + + int32_t BasicRenderer2D::init(WindowCore& window) { m_window = &window; - m_ttfr.init(window.getSDLRenderer()); + if (m_initialized) return set_error_state(tErrors::NoError); + init_arrays(); m_initialized = true; - setDefaultFont(); + return set_error_state(tErrors::NoError); + } + + void BasicRenderer2D::flushBatch(void) + { + if (!m_initialized || m_vertexCount == 0) + return; + SDL_RenderGeometry(m_window->getSDLRenderer(), m_texture, m_vertices.data(), m_vertexCount, m_indices.data(), m_indexCount); + m_drawCallCount++; + m_texture = nullptr; + m_vertexCount = 0; + m_indexCount = 0; + } + + void BasicRenderer2D::endFrame(void) + { + flushBatch(); + m_drawCallCount = 0; } void BasicRenderer2D::pushClippingRect(const ostd::Rectangle& rect, bool additive) @@ -40,6 +90,10 @@ namespace ogfx if (additive && !m_clipStack.empty()) finalRect = m_clipStack.back().getIntersection(rect, false); + if (!m_clipStack.empty() && m_clipStack.back() == finalRect) + return; + flushBatch(); + m_clipStack.push_back(finalRect); SDL_Rect r; @@ -58,6 +112,7 @@ namespace ogfx m_clipStack.pop_back(); + flushBatch(); if (m_clipStack.empty()) { SDL_SetRenderClipRect(m_window->getSDLRenderer(), nullptr); @@ -75,175 +130,1018 @@ namespace ogfx SDL_SetRenderClipRect(m_window->getSDLRenderer(), &r); } - void BasicRenderer2D::setFont(const ostd::String& fontFilePath) + int32_t BasicRenderer2D::loadDefaultFont(int32_t fontSize) { - if (!m_initialized) return; - m_ttfr.openFont(fontFilePath, m_ttfr.getFontSize()); + return openFont(ubuntu_mono_regular_ttf_data, ubuntu_mono_regular_ttf_size, fontSize); } - void BasicRenderer2D::setDefaultFont(void) + void BasicRenderer2D::closeFont(void) { - if (!m_initialized) return; - m_ttfr.loadDefaultFont(m_ttfr.getFontSize()); + if (!m_initialized || !m_fontOpen) return; + if (m_font != nullptr) + TTF_CloseFont(m_font); + m_font = nullptr; + m_fontOpen = false; + m_fontSize = DefaultFontSize; + m_fontFromMemory = false; + set_error_state(tErrors::NoError); } - void BasicRenderer2D::setFontSize(int32_t fontSize) + int32_t BasicRenderer2D::openFont(const ostd::String& fontPath, int32_t fontSize) { - if (!m_initialized) return; - m_ttfr.setFontSize(fontSize); + if (!m_initialized) return set_error_state(tErrors::Uninitialized); + if (m_fontOpen) closeFont(); + if (fontSize <= 0) + fontSize = m_fontSize; + else + m_fontSize = fontSize; + m_font = TTF_OpenFont(fontPath.c_str(), fontSize); + if (m_font == nullptr) + { + print_ttf_error("TTF_OpenFont"); + return set_error_state(tErrors::FailedToOpenFontFile); + } + m_fontOpen = true; + m_fontFromMemory = false; + return set_error_state(tErrors::NoError); } - void BasicRenderer2D::drawImage(ogfx::Image& image, const ostd::Vec2& position, const ostd::Rectangle& rect) + int32_t BasicRenderer2D::openFont(const ostd::UByte resource_data[], uint32_t data_size, int32_t fontSize) + { + if (!m_initialized) return set_error_state(tErrors::Uninitialized); + if (data_size < 100) // Arbitrary 100 bytes + return set_error_state(tErrors::FailedToOpenFontFile); + if (m_fontOpen) closeFont(); + if (fontSize <= 0) + fontSize = m_fontSize; + else + m_fontSize = fontSize; + SDL_IOStream* rw = SDL_IOFromConstMem(resource_data, data_size); + m_font = TTF_OpenFontIO(rw, true, fontSize); + if (m_font == nullptr) + { + print_ttf_error("TTF_OpenFont"); + return set_error_state(tErrors::FailedToOpenFontFile); + } + m_fontOpen = true; + m_fontFromMemory = true; + return set_error_state(tErrors::NoError); + } + + int32_t BasicRenderer2D::setFontSize(int32_t fontSize) + { + if (!m_initialized) + return set_error_state(tErrors::Uninitialized); + if (!m_fontOpen) + return set_error_state(tErrors::NoFont); + if (m_font == nullptr) + return set_error_state(tErrors::NullFont); + if (fontSize == m_fontSize || fontSize <= 0) return set_error_state(tErrors::NoError); + TTF_SetFontSize(m_font, fontSize); + return set_error_state(tErrors::NoError); + } + + ostd::IPoint BasicRenderer2D::getStringDimensions(const ostd::String& message, int32_t fontSize) + { + if (!m_initialized) + { + set_error_state(tErrors::Uninitialized); + return { 0, 0 }; + } + if (!m_fontOpen) + { + set_error_state(tErrors::NoFont); + return { 0, 0 }; + } + if (m_font == nullptr) + { + set_error_state(tErrors::NullFont); + return { 0, 0 }; + } + setFontSize(fontSize); + SDL_Surface* surf = TTF_RenderText_Blended(m_font, message.c_str(), message.len(), { 0, 0, 0, 255 }); + if (surf == nullptr) + { + set_error_state(tErrors::TTFRenderTextBlendedFail); + print_ttf_error("TTF_RenderText_Blended"); + return { 0, 0 }; + } + SDL_Texture* texture = SDL_CreateTextureFromSurface(m_window->getSDLRenderer(), surf); + if (texture == nullptr) + { + set_error_state(tErrors::TTFCreateTextureFromSurfaceFail); + print_ttf_error("SDL_CreateTextureFromSurface"); + return { 0, 0 }; + } + SDL_DestroySurface(surf); + + float w = 0, h = 0; + SDL_GetTextureSize(texture, &w, &h); + SDL_DestroyTexture(texture); + return { static_cast(w), static_cast(h) }; + } + // ===================================================== UTILS ===================================================== + + + + + + // ===================================================== SPECIALIZED ===================================================== + void BasicRenderer2D::drawImage(const ogfx::Image& image, const ostd::Vec2& position, const ostd::Vec2& size, const ostd::Rectangle& srcRect) { - if (!m_initialized) return; - if (!image.isLoaded()) return; - SDL_FRect texr; - texr.x = position.x; - texr.y = position.y; - texr.w = image.getSize().x; - texr.h = image.getSize().y; - SDL_FRect srcRect; - srcRect.x = rect.x; - srcRect.y = rect.y; - srcRect.w = rect.w; - srcRect.h = rect.w; - if (srcRect.x == 0 && srcRect.y == 0 && srcRect.w == 0 && srcRect.h == 0) - SDL_RenderTexture(m_window->getSDLRenderer(), image.getSDLTexture(), nullptr, &texr); + if (!m_initialized || !image.isLoaded()) + return; + + SDL_Texture* tex = image.getSDLTexture(); + if (!tex) + return; + + ostd::Vec2 texSize = image.getSize(); + + // 1. Resolve source rectangle + float sx, sy, sw, sh; + if (srcRect.w == 0 && srcRect.h == 0) + { + // Use entire texture + sx = 0.0f; + sy = 0.0f; + sw = texSize.x; + sh = texSize.y; + } else { - texr.w = srcRect.w; - texr.h = srcRect.h; - SDL_RenderTexture(m_window->getSDLRenderer(), image.getSDLTexture(), &srcRect, &texr); + sx = srcRect.x; + sy = srcRect.y; + sw = srcRect.w; + sh = srcRect.h; } + + // 2. Resolve destination rectangle + float dx = position.x; + float dy = position.y; + float dw = (size.x == 0) ? sw : size.x; + float dh = (size.y == 0) ? sh : size.y; + float x1 = dx; + float y1 = dy; + float x2 = dx + dw; + float y2 = dy + dh; + + // 3. Build quad vertices + ostd::Vec2 verts[4] = { + { x1, y1 }, + { x2, y1 }, + { x2, y2 }, + { x1, y2 } + }; + + // 4. Build UVs (normalized) + ostd::Vec2 uvs[4] = { + { sx / texSize.x, sy / texSize.y }, + { (sx + sw) / texSize.x, sy / texSize.y }, + { (sx + sw) / texSize.x, (sy + sh) / texSize.y }, + { sx / texSize.x, (sy + sh) / texSize.y } + }; + + // 5. Push quad + uint32_t inds[6] = QUAD_INDICES_ARR; + push_polygon(verts, uvs, 4, inds, 6, ostd::Colors::White, tex); } - void BasicRenderer2D::drawAnimation(const Animation& anim, const ostd::Vec2& position) + void BasicRenderer2D::drawAnimation(const Animation& anim, const ostd::Vec2& position, const ostd::Vec2& size) { if (!m_initialized) return; if (!anim.hasImage()) return; - Image img = anim.getSpriteSheet(); + const Image& img = anim.getSpriteSheet(); if (!img.isLoaded() || !img.isValid()) return; - drawImage(img, position, anim.getFrameRect()); + drawImage(img, position, size, anim.getFrameRect()); } void BasicRenderer2D::drawString(const ostd::String& str, const ostd::Vec2& position, const ostd::Color& color, int32_t fontSize) { if (!m_initialized) return; - if (!m_ttfr.isValid()) return; - m_ttfr.renderText(str, (int32_t)std::round(position.x), (int32_t)std::round(position.y), color, fontSize); } void BasicRenderer2D::drawCenteredString(const ostd::String& str, const ostd::Vec2& center, const ostd::Color& color, int32_t fontSize) { if (!m_initialized) return; - if (!m_ttfr.isValid()) return; - m_ttfr.renderCenteredText(str, (int32_t)std::round(center.x), (int32_t)std::round(center.y), color, fontSize); } + // ===================================================== SPECIALIZED ===================================================== - void BasicRenderer2D::drawLine(const ostd::FLine& line, const ostd::Color& color, int32_t thickness) + + + + + // ===================================================== PRIMITIVES ===================================================== + void BasicRenderer2D::drawLine(const ostd::FLine& line, const ostd::Color& color, int32_t thickness, bool rounded) { - if (!m_initialized) return; - thickLineRGBA(m_window->getSDLRenderer(), (int32_t)std::round(line.p1.x), (int32_t)std::round(line.p1.y), (int32_t)std::round(line.p2.x), (int32_t)std::round(line.p2.y), thickness, color.r, color.g, color.b, color.a); + if (!m_initialized || thickness <= 0) return; + + using namespace ostd; + + Vec2 p1 = line.p1.asVec2(); + Vec2 p2 = line.p2.asVec2(); + + Vec2 dir = (p2 - p1).normalize(); + Vec2 perp = { -dir.y, dir.x }; // 90° rotation + float half = thickness * 0.5f; + Vec2 off = perp * half; + + std::array verts = {{ + p1 - off, + p1 + off, + p2 + off, + p2 - off + }}; + std::array inds = QUAD_INDICES_ARR; + + push_polygon(verts.data(), nullptr, 4, inds.data(), 6, color, nullptr); + + if (!rounded || thickness < 4) + return; + + int segments = std::max(6, int(thickness * 0.75f)); + generate_half_circle(p1, -dir, half, segments, color); + generate_half_circle(p2, dir, half, segments, color); } void BasicRenderer2D::drawRect(const ostd::Rectangle& rect, const ostd::Color& color, int32_t thickness) { - if (!m_initialized) return; - float x1 = rect.x; - float y1 = rect.y; - float x2 = rect.x + rect.w; - float y2 = rect.y + rect.h; - if (thickness == 1) - rectangleRGBA(m_window->getSDLRenderer(), (int32_t)std::round(x1), (int32_t)std::round(y1), (int32_t)std::round(x2), (int32_t)std::round(y2), color.r, color.g, color.b, color.a); - else if (thickness > 1) - { - for (int32_t i = 0; i < thickness; i++) - rectangleRGBA(m_window->getSDLRenderer(), (int32_t)std::round(x1 + i), (int32_t)std::round(y1 + i), (int32_t)std::round(x2 - i), (int32_t)std::round(y2 - i), color.r, color.g, color.b, color.a); - } + if (!m_initialized || thickness <= 0) + return; + + float half = thickness * 0.5f; + + // Inset rectangle so the outline stays inside the original bounds + float x1 = rect.x + half; + float y1 = rect.y + half; + float x2 = rect.x + rect.w - half; + float y2 = rect.y + rect.h - half; + + // Top + drawLine({ {x1, y1}, {x2, y1} }, color, thickness, false); + + // Right + drawLine({ {x2, y1 - half}, {x2, y2 + half} }, color, thickness, false); + + // Bottom + drawLine({ {x2, y2}, {x1, y2} }, color, thickness, false); + + // Left + drawLine({ {x1, y2 + half}, {x1, y1 - half} }, color, thickness, false); } - void BasicRenderer2D::drawRoundRect(const ostd::Rectangle& rect, const ostd::Color& color, int32_t radius, int32_t thickness) + void BasicRenderer2D::drawRoundRect(const ostd::Rectangle& rect, const ostd::Color& color, float radius, int32_t thickness) { - if (!m_initialized) return; - float x1 = rect.x; - float y1 = rect.y; - float x2 = rect.x + rect.w; - float y2 = rect.y + rect.h; - if (thickness == 1) - roundedRectangleRGBA(m_window->getSDLRenderer(), (int32_t)std::round(x1), (int32_t)std::round(y1), (int32_t)std::round(x2), (int32_t)std::round(y2), radius, color.r, color.g, color.b, color.a); - else if (thickness > 1) - { - for (int32_t i = 0; i < thickness; i++) - roundedRectangleRGBA(m_window->getSDLRenderer(), (int32_t)std::round(x1 + i), (int32_t)std::round(y1 + i), (int32_t)std::round(x2 - i), (int32_t)std::round(y2 - i), radius, color.r, color.g, color.b, color.a); - } + if (!m_initialized || thickness <= 0) + return; + + // Clamp radius so it never exceeds half the smallest dimension + radius = std::max(0.0f, std::min(radius, std::min(rect.w, rect.h) * 0.5f)); + + float half = thickness * 0.5f; + + // Inset rectangle so the border stays INSIDE the given bounds + float x1 = rect.x + half; + float y1 = rect.y + half; + float x2 = rect.x + rect.w - half; + float y2 = rect.y + rect.h - half; + + // Corner centers + ostd::Vec2 TL { x1 + radius, y1 + radius }; + ostd::Vec2 TR { x2 - radius, y1 + radius }; + ostd::Vec2 BR { x2 - radius, y2 - radius }; + ostd::Vec2 BL { x1 + radius, y2 - radius }; + + // Straight edges (shortened to meet the arcs cleanly) + drawLine({ {x1 + radius, y1}, {x2 - radius, y1} }, color, thickness, false); // top + drawLine({ {x2, y1 + radius}, {x2, y2 - radius} }, color, thickness, false); // right + drawLine({ {x2 - radius, y2}, {x1 + radius, y2} }, color, thickness, false); // bottom + drawLine({ {x1, y2 - radius}, {x1, y1 + radius} }, color, thickness, false); // left + + // Number of segments for smooth arcs + int segments = std::max(6, int(radius * 0.75f)); + + // Quarter‑ellipse strokes (each is 90°) + generate_ellipse_stroke(TL, radius, radius, thickness, M_PI, M_PI + M_PI * 0.5f, color, segments); // TL + generate_ellipse_stroke(TR, radius, radius, thickness, 1.5f * M_PI, 2.0f * M_PI, color, segments); // TR + generate_ellipse_stroke(BR, radius, radius, thickness, 0.0f, M_PI * 0.5f, color, segments); // BR + generate_ellipse_stroke(BL, radius, radius, thickness, M_PI * 0.5f, M_PI, color, segments); // BL } - void BasicRenderer2D::drawCircle(const ostd::Vec2& center, int32_t radius, const ostd::Color& color, int32_t thickness) + void BasicRenderer2D::drawCircle(const ostd::Vec2& center, float radius, const ostd::Color& color, int32_t thickness) { - if (!m_initialized) return; - if (thickness == 1) - circleRGBA(m_window->getSDLRenderer(), (int32_t)std::round(center.x), (int32_t)std::round(center.y), radius, color.r, color.g, color.b, color.a); - else if (thickness > 1) - { - for (int32_t i = 0; i < thickness; i++) - circleRGBA(m_window->getSDLRenderer(), (int32_t)std::round(center.x), (int32_t)std::round(center.y), radius - i, color.r, color.g, color.b, color.a); - } + if (!m_initialized || thickness <= 0) + return; + int segments = std::max(12, int(radius * 0.75f)); + generate_ellipse_stroke(center, radius, radius, thickness, 0.0f, 2.0f * M_PI, color, segments); + } + + void BasicRenderer2D::drawCircle(const ostd::Rectangle& rect, const ostd::Color& color, int32_t thickness) + { + if (!m_initialized || thickness <= 0) + return; + + ostd::Vec2 center { + rect.x + rect.w * 0.5f, + rect.y + rect.h * 0.5f + }; + + float radius = std::min(rect.w, rect.h) * 0.5f; + drawCircle(center, radius, color, thickness); + } + + void BasicRenderer2D::drawEllipse(const ostd::Rectangle& rect, const ostd::Color& color, int32_t thickness) + { + if (!m_initialized || thickness <= 0) + return; + + ostd::Vec2 center = { rect.x + rect.w*0.5f, rect.y + rect.h*0.5f }; + float rx = rect.w * 0.5f; + float ry = rect.h * 0.5f; + + int segments = std::max(12, int(std::max(rx, ry) * 0.75f)); + generate_ellipse_stroke(center, rx, ry, thickness, 0.0f, 2.0f * M_PI, color, segments); } void BasicRenderer2D::fillRect(const ostd::Rectangle& rect, const ostd::Color& color) { - if (!m_initialized) return; - float x1 = rect.x; - float y1 = rect.y; - float x2 = rect.x + rect.w; - float y2 = rect.y + rect.h; - boxRGBA(m_window->getSDLRenderer(), (int32_t)std::round(x1), (int32_t)std::round(y1), (int32_t)std::round(x2), (int32_t)std::round(y2), color.r, color.g, color.b, color.a); + if (!m_initialized) + return; + + float x1 = rect.x; + float y1 = rect.y; + float x2 = rect.x + rect.w; + float y2 = rect.y + rect.h; + + ostd::Vec2 verts[4] = { + { x1, y1 }, + { x2, y1 }, + { x2, y2 }, + { x1, y2 } + }; + uint32_t inds[6] = QUAD_INDICES_ARR; + push_polygon(verts, nullptr, 4, inds, 6, color, nullptr); } - void BasicRenderer2D::fillRoundRect(const ostd::Rectangle& rect, const ostd::Color& color, int32_t radius) + void BasicRenderer2D::fillRoundRect(const ostd::Rectangle& rect, const ostd::Color& color, float radius) { - if (!m_initialized) return; - float x1 = rect.x; - float y1 = rect.y; - float x2 = rect.x + rect.w; - float y2 = rect.y + rect.h; - roundedBoxRGBA(m_window->getSDLRenderer(), (int32_t)std::round(x1), (int32_t)std::round(y1), (int32_t)std::round(x2), (int32_t)std::round(y2), radius, color.r, color.g, color.b, color.a); + if (!m_initialized) + return; + + // Clamp radius + radius = std::max(0.0f, std::min(radius, std::min(rect.w, rect.h) * 0.5f)); + + float x1 = rect.x; + float y1 = rect.y; + float x2 = rect.x + rect.w; + float y2 = rect.y + rect.h; + + float cx1 = x1 + radius; + float cy1 = y1 + radius; + float cx2 = x2 - radius; + float cy2 = y2 - radius; + + // Number of segments for smooth corners + int segments = std::max(6, int(radius * 0.75f)); + + // + // 1. Fill the center rectangle + // + { + ostd::Vec2 verts[4] = { + { cx1, cy1 }, + { cx2, cy1 }, + { cx2, cy2 }, + { cx1, cy2 } + }; + uint32_t inds[6] = { 0,1,2, 2,3,0 }; + push_polygon(verts, nullptr, 4, inds, 6, color, nullptr); + } + + // + // 2. Fill the four side rectangles + // + + // Top + if (radius > 0) + { + ostd::Vec2 verts[4] = { + { x1 + radius, y1 }, + { x2 - radius, y1 }, + { x2 - radius, y1 + radius }, + { x1 + radius, y1 + radius } + }; + uint32_t inds[6] = { 0,1,2, 2,3,0 }; + push_polygon(verts, nullptr, 4, inds, 6, color, nullptr); + } + + // Bottom + { + ostd::Vec2 verts[4] = { + { x1 + radius, y2 - radius }, + { x2 - radius, y2 - radius }, + { x2 - radius, y2 }, + { x1 + radius, y2 } + }; + uint32_t inds[6] = { 0,1,2, 2,3,0 }; + push_polygon(verts, nullptr, 4, inds, 6, color, nullptr); + } + + // Left + { + ostd::Vec2 verts[4] = { + { x1, y1 + radius }, + { x1 + radius, y1 + radius }, + { x1 + radius, y2 - radius }, + { x1, y2 - radius } + }; + uint32_t inds[6] = { 0,1,2, 2,3,0 }; + push_polygon(verts, nullptr, 4, inds, 6, color, nullptr); + } + + // Right + { + ostd::Vec2 verts[4] = { + { x2 - radius, y1 + radius }, + { x2, y1 + radius }, + { x2, y2 - radius }, + { x2 - radius, y2 - radius } + }; + uint32_t inds[6] = { 0,1,2, 2,3,0 }; + push_polygon(verts, nullptr, 4, inds, 6, color, nullptr); + } + + // + // 3. Fill the four rounded corners (quarter ellipses) + // + + generate_filled_ellipse_stroke({cx1, cy1}, radius, radius, M_PI, color, segments); // TL + generate_filled_ellipse_stroke({cx2, cy1}, radius, radius, 1.5f * M_PI, color, segments); // TR + generate_filled_ellipse_stroke({cx2, cy2}, radius, radius, 0.0f, color, segments); // BR + generate_filled_ellipse_stroke({cx1, cy2}, radius, radius, 0.5f * M_PI, color, segments); // BL } - void BasicRenderer2D::fillCircle(const ostd::Vec2& center, int32_t radius, const ostd::Color& color) + void BasicRenderer2D::fillCircle(const ostd::Vec2& center, float radius, const ostd::Color& color) { - if (!m_initialized) return; - filledCircleRGBA(m_window->getSDLRenderer(), (int32_t)std::round(center.x), (int32_t)std::round(center.y), radius, color.r, color.g, color.b, color.a); + if (!m_initialized) + return; + + int segments = std::max(12, int(radius * 0.75f)); + generate_filled_ellipse(center, radius, radius, color, segments); } - void BasicRenderer2D::outlinedRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness, bool outlineInward) + void BasicRenderer2D::fillCircle(const ostd::Rectangle& rect, const ostd::Color& color) { - if (!m_initialized) return; - fillRect(rect, fillColor); - float t = static_cast(outlineThickness); - ostd::Rectangle offset = { 0, 0, 0, 0 }; - if (!outlineInward) - offset = { -t, -t, t * 2, t * 2 }; - drawRect(rect + offset , outlineColor, outlineThickness); + if (!m_initialized) + return; + + ostd::Vec2 center { + rect.x + rect.w * 0.5f, + rect.y + rect.h * 0.5f + }; + + float radius = std::min(rect.w, rect.h) * 0.5f; + fillCircle(center, radius, color); } - void BasicRenderer2D::outlinedRoundRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t radius, int32_t outlineThickness, bool outlineInward) + void BasicRenderer2D::fillEllipse(const ostd::Rectangle& rect, const ostd::Color& color) { - if (!m_initialized) return; - fillRoundRect(rect, fillColor, radius); - float t = static_cast(outlineThickness); - ostd::Rectangle offset = { 0, 0, 0, 0 }; - if (!outlineInward) - offset = { -t, -t, t * 2, t * 2 }; - drawRoundRect(rect + offset, outlineColor, radius, outlineThickness); + if (!m_initialized) + return; + + ostd::Vec2 center { + rect.x + rect.w * 0.5f, + rect.y + rect.h * 0.5f + }; + + float radiusX = rect.w * 0.5f; + float radiusY = rect.h * 0.5f; + + int segments = std::max(12, int(std::max(radiusX, radiusY) * 0.75f)); + generate_filled_ellipse(center, radiusX, radiusY, color, segments); } - void BasicRenderer2D::outlinedCircle(const ostd::Vec2& center, int32_t radius, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness, bool outlineInward) + void BasicRenderer2D::outlinedRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness) { if (!m_initialized) return; - fillCircle(center, radius, fillColor); - radius = (outlineInward ? radius : radius + outlineThickness); + ostd::Rectangle offset = { 1, 1, -2, -2 }; + fillRect(rect + offset, fillColor); + drawRect(rect , outlineColor, outlineThickness); + } + + void BasicRenderer2D::outlinedRoundRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, float radius, int32_t outlineThickness) + { + if (!m_initialized) return; + ostd::Rectangle offset = { 1, 1, -2, -2 }; + fillRoundRect(rect + offset, fillColor, radius); + drawRoundRect(rect, outlineColor, radius, outlineThickness); + } + + void BasicRenderer2D::outlinedCircle(const ostd::Vec2& center, float radius, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness) + { + if (!m_initialized) return; + fillCircle(center, radius - 1, fillColor); drawCircle(center, radius, outlineColor, outlineThickness); } + void BasicRenderer2D::outlinedCircle(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness) + { + if (!m_initialized) + return; + + ostd::Vec2 center { + rect.x + rect.w * 0.5f, + rect.y + rect.h * 0.5f + }; + + float radius = std::min(rect.w, rect.h) * 0.5f; + outlinedCircle(center, radius, fillColor, outlineColor, outlineThickness); + } + + void BasicRenderer2D::outlinedEllipse(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness) + { + if (!m_initialized) return; + ostd::Rectangle offset = { 1, 1, -2, -2 }; + fillEllipse(rect + offset, fillColor); + drawEllipse(rect, outlineColor, outlineThickness); + } + // ===================================================== PRIMITIVES ===================================================== + + + + + + // ===================================================== PRIVATE HELPERS ===================================================== + void BasicRenderer2D::init_arrays(void) + { + for (auto& v : m_vertices) + { + v.color = COLOR_CAST(ostd::Colors::Transparent); + v.position = { 0, 0 }; + v.tex_coord = { 0, 0 }; + } + for (auto& i : m_indices) + i = 0; + } + + void BasicRenderer2D::generate_half_circle(const ostd::Vec2& center, const ostd::Vec2& dir, float radius, int segments, const ostd::Color& color) + { + // Ensure we have room + if (m_vertexCount + segments + 2 >= MaxVertices || m_indexCount + segments * 3 >= MaxIndices) + flushBatch(); + + SDL_FColor col = COLOR_CAST(color); + + // Index of the center vertex + int centerIndex = m_vertexCount; + + // Push center vertex + m_vertices[m_vertexCount++] = { + { center.x, center.y }, + col, + { 0.0f, 0.0f }, + }; + + // Compute the base angle from the direction vector + float baseAngle = std::atan2(dir.y, dir.x); + + // Half circle spans 180 degrees + float startAngle = baseAngle - M_PI * 0.5f; + float endAngle = baseAngle + M_PI * 0.5f; + + // Generate arc vertices + for (int i = 0; i <= segments; i++) + { + float t = float(i) / float(segments); + float angle = startAngle + t * (endAngle - startAngle); + + float x = center.x + std::cos(angle) * radius; + float y = center.y + std::sin(angle) * radius; + + m_vertices[m_vertexCount++] = { + { x, y }, + col, + { 0.0f, 0.0f } + }; + } + + // Generate triangle fan indices + for (int i = 0; i < segments; i++) + { + m_indices[m_indexCount++] = centerIndex; + m_indices[m_indexCount++] = centerIndex + 1 + i; + m_indices[m_indexCount++] = centerIndex + 2 + i; + } + } + + void BasicRenderer2D::generate_quarter_circle(const ostd::Vec2& center, float radius, float thickness, float startAngle, const ostd::Color& color, int segments) + { + float half = thickness * 0.5f; + + float outerR = radius + half; + float innerR = radius - half; + + if (innerR < 0.0f) + innerR = 0.0f; + + // Ensure capacity + if (m_vertexCount + (segments + 1) * 2 >= MaxVertices || m_indexCount + segments * 6 >= MaxIndices) + flushBatch(); + + SDL_FColor col = COLOR_CAST(color); + + int base = m_vertexCount; + + float endAngle = startAngle + M_PI * 0.5f; + + // Generate vertices: outer arc + inner arc + for (int i = 0; i <= segments; i++) + { + float t = float(i) / float(segments); + float angle = startAngle + t * (endAngle - startAngle); + + float cs = std::cos(angle); + float sn = std::sin(angle); + + // Outer arc + m_vertices[m_vertexCount++] = { + { center.x + cs * outerR, center.y + sn * outerR }, + col, + { 0, 0 } + }; + + // Inner arc + m_vertices[m_vertexCount++] = { + { center.x + cs * innerR, center.y + sn * innerR }, + col, + { 0, 0 } + }; + } + + // Generate indices (triangle strip converted to triangles) + for (int i = 0; i < segments; i++) + { + int o0 = base + i * 2; + int i0 = o0 + 1; + int o1 = o0 + 2; + int i1 = o0 + 3; + + // Triangle 1 + m_indices[m_indexCount++] = o0; + m_indices[m_indexCount++] = o1; + m_indices[m_indexCount++] = i0; + + // Triangle 2 + m_indices[m_indexCount++] = o1; + m_indices[m_indexCount++] = i1; + m_indices[m_indexCount++] = i0; + } + } + + void BasicRenderer2D::generate_circle_stroke(const ostd::Vec2& center, float radius, float thickness, const ostd::Color& color, int segments) + { + float half = thickness * 0.5f; + + float outerR = radius + half; + float innerR = radius - half; + if (innerR < 0.0f) + innerR = 0.0f; + + // Ensure capacity + if (m_vertexCount + (segments + 1) * 2 >= MaxVertices || m_indexCount + segments * 6 >= MaxIndices) + flushBatch(); + + SDL_FColor col = COLOR_CAST(color); + + int base = m_vertexCount; + + // Generate vertices: outer arc + inner arc + for (int i = 0; i <= segments; i++) + { + float t = float(i) / float(segments); + float angle = t * (2.0f * M_PI); + + float cs = std::cos(angle); + float sn = std::sin(angle); + + // Outer arc + m_vertices[m_vertexCount++] = { + { center.x + cs * outerR, center.y + sn * outerR }, + col, + { 0, 0 } + }; + + // Inner arc + m_vertices[m_vertexCount++] = { + { center.x + cs * innerR, center.y + sn * innerR }, + col, + { 0, 0 } + }; + } + + // Generate indices (triangle strip → triangles) + for (int i = 0; i < segments; i++) + { + int o0 = base + i * 2; + int i0 = o0 + 1; + int o1 = o0 + 2; + int i1 = o0 + 3; + + // Triangle 1 + m_indices[m_indexCount++] = o0; + m_indices[m_indexCount++] = o1; + m_indices[m_indexCount++] = i0; + + // Triangle 2 + m_indices[m_indexCount++] = o1; + m_indices[m_indexCount++] = i1; + m_indices[m_indexCount++] = i0; + } + } + + void BasicRenderer2D::generate_ellipse_stroke(const ostd::Vec2& center, float radiusX, float radiusY, float thickness, float startAngle, float endAngle, const ostd::Color& color, int segments) + { + float half = thickness * 0.5f; + + float outerRX = radiusX + half; + float outerRY = radiusY + half; + float innerRX = std::max(0.0f, radiusX - half); + float innerRY = std::max(0.0f, radiusY - half); + + // Ensure capacity + if (m_vertexCount + (segments + 1) * 2 >= MaxVertices || + m_indexCount + segments * 6 >= MaxIndices) + { + flushBatch(); + } + + SDL_FColor col = COLOR_CAST(color); + + int base = m_vertexCount; + + float angleRange = endAngle - startAngle; + + // Generate vertices: outer arc + inner arc + for (int i = 0; i <= segments; i++) + { + float t = float(i) / float(segments); + float angle = startAngle + t * angleRange; + + float cs = std::cos(angle); + float sn = std::sin(angle); + + // Outer arc + m_vertices[m_vertexCount++] = { + { center.x + cs * outerRX, center.y + sn * outerRY }, + col, + { 0, 0 } + }; + + // Inner arc + m_vertices[m_vertexCount++] = { + { center.x + cs * innerRX, center.y + sn * innerRY }, + col, + { 0, 0 } + }; + } + + // Generate indices (triangle strip → triangles) + for (int i = 0; i < segments; i++) + { + int o0 = base + i * 2; + int i0 = o0 + 1; + int o1 = o0 + 2; + int i1 = o0 + 3; + + // Triangle 1 + m_indices[m_indexCount++] = o0; + m_indices[m_indexCount++] = o1; + m_indices[m_indexCount++] = i0; + + // Triangle 2 + m_indices[m_indexCount++] = o1; + m_indices[m_indexCount++] = i1; + m_indices[m_indexCount++] = i0; + } + } + + void BasicRenderer2D::generate_filled_ellipse_stroke(const ostd::Vec2& center, float radiusX, float radiusY, float startAngle, const ostd::Color& color, int segments) + { + // Ensure capacity + if (m_vertexCount + segments + 2 >= MaxVertices || m_indexCount + segments * 3 >= MaxIndices) + flushBatch(); + + SDL_FColor col = COLOR_CAST(color); + + int base = m_vertexCount; + + // Center vertex + m_vertices[m_vertexCount++] = { + { center.x, center.y }, + col, + { 0, 0 } + }; + + float endAngle = startAngle + M_PI * 0.5f; + + for (int i = 0; i <= segments; i++) + { + float t = float(i) / float(segments); + float angle = startAngle + t * (endAngle - startAngle); + + float x = center.x + std::cos(angle) * radiusX; + float y = center.y + std::sin(angle) * radiusY; + + m_vertices[m_vertexCount++] = { + { x, y }, + col, + { 0, 0 } + }; + } + + // Triangle fan indices + for (int i = 0; i < segments; i++) + { + m_indices[m_indexCount++] = base; + m_indices[m_indexCount++] = base + 1 + i; + m_indices[m_indexCount++] = base + 2 + i; + } + } + + void BasicRenderer2D::generate_filled_ellipse(const ostd::Vec2& center, float radiusX, float radiusY, const ostd::Color& color, int segments) + { + // Ensure capacity + if (m_vertexCount + segments + 2 >= MaxVertices || m_indexCount + segments * 3 >= MaxIndices) + flushBatch(); + + SDL_FColor col = COLOR_CAST(color); + + int base = m_vertexCount; + + // Center vertex + m_vertices[m_vertexCount++] = { + { center.x, center.y }, + col, + { 0, 0 } + }; + + // Outer ring vertices + for (int i = 0; i <= segments; i++) + { + float t = float(i) / float(segments); + float angle = t * (2.0f * M_PI); + + float x = center.x + std::cos(angle) * radiusX; + float y = center.y + std::sin(angle) * radiusY; + + m_vertices[m_vertexCount++] = { + { x, y }, + col, + { 0, 0 } + }; + } + + // Triangle fan indices + for (int i = 0; i < segments; i++) + { + m_indices[m_indexCount++] = base; + m_indices[m_indexCount++] = base + 1 + i; + m_indices[m_indexCount++] = base + 2 + i; + } + } + + void BasicRenderer2D::push_polygon(const ostd::Vec2* verts, const ostd::Vec2* texCoords, uint32_t vertCount, const uint32_t* inds, uint32_t indexCount, const ostd::Color& color, SDL_Texture* texture) + { + if (!m_initialized || vertCount <= 0 || indexCount <= 0) + return; + + if (vertCount > MaxVertices || indexCount > MaxIndices) + { + OX_ERROR("Maximum number of vertices exceeded in single draw call."); + return; + } + if (texture != m_texture) + flushBatch(); + m_texture = texture; + if (m_vertexCount + vertCount >= MaxVertices || m_indexCount + indexCount >= MaxIndices) + flushBatch(); + + SDL_FColor col = COLOR_CAST(color); + + int base = m_vertexCount; + bool hasTexCoords = texCoords != nullptr; + for (int i = 0; i < vertCount; i++) + { + ostd::Vec2 tc { 0.0f, 0.0f }; + if (hasTexCoords) + tc = texCoords[i]; + m_vertices[m_vertexCount++] = { + { verts[i].x, verts[i].y }, + col, + { tc.x, tc.y }, + }; + } + for (int i = 0; i < indexCount; i++) + m_indices[m_indexCount++] = base + inds[i]; + } + + void BasicRenderer2D::print_ttf_error(const ostd::String& funcName) + { + m_out.fg(ostd::ConsoleColors::Red).p(funcName).p("(...) failed: ").p(ostd::String(SDL_GetError())).reset().nl(); + } + + void BasicRenderer2D::renderText(const ostd::String& message, int32_t x, int32_t y, const ostd::Color& color, int32_t fontSize) + { + if (!m_initialized) + { + set_error_state(tErrors::Uninitialized); + return; + } + if (!m_fontOpen) + { + set_error_state(tErrors::NoFont); + return; + } + if (m_font == nullptr) + { + set_error_state(tErrors::NullFont); + return; + } + setFontSize(fontSize); + SDL_Surface* surf = TTF_RenderText_Blended(m_font, message.c_str(), message.len(), { color.r, color.g, color.b, color.a }); + if (surf == nullptr) + { + set_error_state(tErrors::TTFRenderTextBlendedFail); + print_ttf_error("TTF_RenderText_Blended"); + return; + } + auto renderer = m_window->getSDLRenderer(); + SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surf); + if (texture == nullptr) + { + set_error_state(tErrors::TTFCreateTextureFromSurfaceFail); + print_ttf_error("SDL_CreateTextureFromSurface"); + return; + } + SDL_DestroySurface(surf); + + float w = 0, h = 0; + SDL_GetTextureSize(texture, &w, &h); + + SDL_FRect dst; + dst.x = x; + dst.y = y; + dst.w = w; + dst.h = h; + SDL_RenderTexture(renderer, texture, NULL, &dst); + SDL_DestroyTexture(texture); + } + + void BasicRenderer2D::renderCenteredText(const ostd::String& message, int32_t center_x, int32_t center_y, const ostd::Color& color, int32_t fontSize) + { + if (!m_initialized) + { + set_error_state(tErrors::Uninitialized); + return; + } + if (!m_fontOpen) + { + set_error_state(tErrors::NoFont); + return; + } + if (m_font == nullptr) + { + set_error_state(tErrors::NullFont); + return; + } + setFontSize(fontSize); + auto renderer = m_window->getSDLRenderer(); + SDL_Surface* surf = TTF_RenderText_Blended(m_font, message.c_str(), message.len(), { color.r, color.g, color.b, color.a }); + if (surf == nullptr) + { + set_error_state(tErrors::TTFRenderTextBlendedFail); + print_ttf_error("TTF_RenderText_Blended"); + return; + } + SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surf); + if (texture == nullptr) + { + set_error_state(tErrors::TTFCreateTextureFromSurfaceFail); + print_ttf_error("SDL_CreateTextureFromSurface"); + return; + } + SDL_DestroySurface(surf); + + float w = 0, h = 0; + SDL_GetTextureSize(texture, &w, &h); + + SDL_FRect dst; + dst.x = center_x - (w / 2); + dst.y = center_y - (h / 2); + dst.w = w; + dst.h = h; + SDL_RenderTexture(renderer, texture, NULL, &dst); + SDL_DestroyTexture(texture); + } + // ===================================================== PRIVATE HELPERS ===================================================== } diff --git a/src/ogfx/render/BasicRenderer.hpp b/src/ogfx/render/BasicRenderer.hpp index ceb381f..3a541bc 100644 --- a/src/ogfx/render/BasicRenderer.hpp +++ b/src/ogfx/render/BasicRenderer.hpp @@ -30,44 +30,115 @@ namespace ogfx class WindowCore; class BasicRenderer2D { + public: struct tErrors + { + inline static constexpr int32_t NoError = 0; + inline static constexpr int32_t FailedToLoad = 1; + inline static constexpr int32_t FailedToOpenFontFile = 2; + inline static constexpr int32_t Uninitialized = 3; + inline static constexpr int32_t InvalidState = 5; + inline static constexpr int32_t TTFRenderTextBlendedFail = 6; + inline static constexpr int32_t TTFCreateTextureFromSurfaceFail = 7; + inline static constexpr int32_t NullFont = 8; + inline static constexpr int32_t NoFont = 9; + inline static constexpr int32_t FailedToOpenFontByteStrean = 10; + }; + private: class SignalHandler : public ostd::BaseObject + { + public: + SignalHandler(BasicRenderer2D& parent); + void handleSignal(ostd::Signal& signal) override; + + private: + BasicRenderer2D& m_parent; + }; public: BasicRenderer2D(void) = default; - void init(WindowCore& window); - - inline TTFRenderer& getTTFRenderer(void) { return m_ttfr; } - inline ostd::IPoint getStringSize(const ostd::String str, int32_t fontSize = 0) { return m_ttfr.getStringDimensions(str, fontSize); } - inline WindowCore& getWindow(void) { return *m_window; } - inline bool isInitialized(void) { return m_initialized; } + ~BasicRenderer2D(void); + int32_t init(WindowCore& window); + void flushBatch(void); + void endFrame(void); void pushClippingRect(const ostd::Rectangle& rect, bool additive = false); void popClippingRect(void); - void setFont(const ostd::String& fontFilePath); - void setDefaultFont(void); - void setFontSize(int32_t fontSize); + int32_t loadDefaultFont(int32_t fontSize = 0); + void closeFont(void); + int32_t openFont(const ostd::String& fontPath, int32_t fontSize = 0); + int32_t openFont(const ostd::UByte resource_data[], uint32_t data_size, int32_t fontSize = 0); + int32_t setFontSize(int32_t fontSize); + ostd::IPoint getStringDimensions(const ostd::String& message, int32_t fontSize = 0); - void drawImage(ogfx::Image& image, const ostd::Vec2& position, const ostd::Rectangle& rect = { 0, 0, 0, 0 }); - void drawAnimation(const Animation& anim, const ostd::Vec2& position); + inline uint32_t getDrawCallCount(void) { return m_drawCallCount; } + inline bool hasOpenFont(void) { return m_fontOpen; } + inline TTF_Font* getSDLFont(void) { return m_font; } + inline bool isValid(void) { return m_initialized && m_fontOpen && (m_font != nullptr || m_fontFromMemory); } + inline int32_t geterrorState(void) { return m_errorState; } + inline int32_t getFontSize(void) { return m_fontSize; } + inline WindowCore& getWindow(void) { return *m_window; } + inline bool isInitialized(void) { return m_initialized; } + + void drawImage(const ogfx::Image& image, const ostd::Vec2& position, const ostd::Vec2& size = { 0, 0 }, const ostd::Rectangle& srcRect = { 0, 0, 0, 0 }); + void drawAnimation(const Animation& anim, const ostd::Vec2& position, const ostd::Vec2& size = { 0, 0 }); void drawString(const ostd::String& str, const ostd::Vec2& position, const ostd::Color& color, int32_t fontSize = 0); void drawCenteredString(const ostd::String& str, const ostd::Vec2& center, const ostd::Color& color, int32_t fontSize = 0); - void drawLine(const ostd::FLine& line, const ostd::Color& color, int32_t thickness = 1); + void drawLine(const ostd::FLine& line, const ostd::Color& color, int32_t thickness = 1, bool rounded = true); void drawRect(const ostd::Rectangle& rect, const ostd::Color& color, int32_t thickness = 1); - void drawRoundRect(const ostd::Rectangle& rect, const ostd::Color& color, int32_t radius, int32_t thickness = 1); - void drawCircle(const ostd::Vec2& center, int32_t radius, const ostd::Color& color, int32_t thickness = 1); + void drawRoundRect(const ostd::Rectangle& rect, const ostd::Color& color, float radius, int32_t thickness = 1); + void drawCircle(const ostd::Vec2& center, float radius, const ostd::Color& color, int32_t thickness = 1); + void drawCircle(const ostd::Rectangle& rect, const ostd::Color& color, int32_t thickness = 1); + void drawEllipse(const ostd::Rectangle& rect, const ostd::Color& color, int32_t thickness = 1); void fillRect(const ostd::Rectangle& rect, const ostd::Color& color); - void fillRoundRect(const ostd::Rectangle& rect, const ostd::Color& color, int32_t radius); - void fillCircle(const ostd::Vec2& center, int32_t radius, const ostd::Color& color); + void fillRoundRect(const ostd::Rectangle& rect, const ostd::Color& color, float radius); + void fillCircle(const ostd::Vec2& center, float radius, const ostd::Color& color); + void fillCircle(const ostd::Rectangle& rect, const ostd::Color& color); + void fillEllipse(const ostd::Rectangle& rect, const ostd::Color& color); - void outlinedRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness = 1, bool outlineInward = true); - void outlinedRoundRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t radius, int32_t outlineThickness = 1, bool outlineInward = true); - void outlinedCircle(const ostd::Vec2& center, int32_t radius, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness = 1, bool outlineInward = true); + void outlinedRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness = 1); + void outlinedRoundRect(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, float radius, int32_t outlineThickness = 1); + void outlinedCircle(const ostd::Vec2& center, float radius, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness = 1); + void outlinedCircle(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness = 1); + void outlinedEllipse(const ostd::Rectangle& rect, const ostd::Color& fillColor, const ostd::Color& outlineColor, int32_t outlineThickness = 1); private: - TTFRenderer m_ttfr; + void init_arrays(void); + void generate_half_circle(const ostd::Vec2& center, const ostd::Vec2& dir, float radius, int segments, const ostd::Color& color); + void generate_quarter_circle(const ostd::Vec2& center, float radius, float thickness, float startAngle, const ostd::Color& color, int segments); + void generate_circle_stroke(const ostd::Vec2& center, float radius, float thickness, const ostd::Color& color, int segments); + void generate_ellipse_stroke(const ostd::Vec2& center, float radiusX, float radiusY, float thickness, float startAngle, float endAngle, const ostd::Color& color, int segments); + void generate_filled_ellipse_stroke(const ostd::Vec2& center, float radiusX, float radiusY, float startAngle, const ostd::Color& color, int segments); + void generate_filled_ellipse(const ostd::Vec2& center, float radiusX, float radiusY, const ostd::Color& color, int segments); + void push_polygon(const ostd::Vec2* verts, const ostd::Vec2* texCoords, uint32_t vertCount, const uint32_t* inds, uint32_t indexCount, const ostd::Color& color, SDL_Texture* texture); + void print_ttf_error(const ostd::String& funcName); + inline int32_t set_error_state(int32_t err) { m_errorState = err; return m_errorState; } + void renderText(const ostd::String& message, int32_t x, int32_t y, const ostd::Color& color, int32_t fontSize = 0); + void renderCenteredText(const ostd::String& message, int32_t center_x, int32_t center_y, const ostd::Color& color, int32_t fontSize = 0); + + public: + inline static constexpr int32_t MaxVertices { 8192 }; + inline static constexpr int32_t MaxIndices { (int32_t)(MaxVertices * 1.5f) }; + private: WindowCore* m_window { nullptr }; + ostd::ConsoleOutputHandler m_out; bool m_initialized { false }; std::vector m_clipStack; + + std::array m_vertices; + std::array m_indices; + int32_t m_vertexCount { 0 }; + int32_t m_indexCount { 0 }; + SDL_Texture* m_texture { nullptr }; + + uint32_t m_drawCallCount { 0 }; + bool m_fontOpen { false }; + + TTF_Font* m_font { nullptr }; + int32_t m_errorState { tErrors::NoError }; + int32_t m_fontSize { DefaultFontSize }; + bool m_fontFromMemory { false }; + + inline static constexpr int32_t DefaultFontSize { 16 }; }; } diff --git a/src/ogfx/render/FontUtils.cpp b/src/ogfx/render/FontUtils.cpp deleted file mode 100644 index db6c1d4..0000000 --- a/src/ogfx/render/FontUtils.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* - OmniaFramework - A collection of useful functionality - Copyright (C) 2025 OmniaX-Dev - - This file is part of OmniaFramework. - - OmniaFramework is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OmniaFramework is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OmniaFramework. If not, see . -*/ - -#include "FontUtils.hpp" -#include "../resources/UbuntuMonoRegularTTF.hpp" - -namespace ogfx -{ - TTFRenderer::SignalHandler::SignalHandler(TTFRenderer& parent) : m_parent(parent) - { - enableSignals(); - connectSignal(ostd::BuiltinSignals::BeforeSDLShutdown); - setTypeName("ostd::GraphicsWindowOutputHandler::SignalHandler"); - validate(); - } - - void TTFRenderer::SignalHandler::handleSignal(ostd::Signal& signal) - { - if (signal.ID == ostd::BuiltinSignals::BeforeSDLShutdown) - { - m_parent.closeFont(); - } - } - - - - TTFRenderer::~TTFRenderer(void) - { - closeFont(); - } - - void TTFRenderer::renderText(const ostd::String& message, int32_t x, int32_t y, const ostd::Color& color, int32_t fontSize) - { - if (!TTFRenderer::m_initialized) - { - set_error_state(tErrors::Uninitialized); - return; - } - if (!m_fontOpen) - { - set_error_state(tErrors::NoFont); - return; - } - if (m_renderer == nullptr) - { - set_error_state(tErrors::NullRenderer); - return; - } - if (m_font == nullptr) - { - set_error_state(tErrors::NullFont); - return; - } - setFontSize(fontSize); - SDL_Surface* surf = TTF_RenderText_Blended(m_font, message.c_str(), message.len(), { color.r, color.g, color.b, color.a }); - if (surf == nullptr) - { - set_error_state(tErrors::TTFRenderTextBlendedFail); - print_ttf_error("TTF_RenderText_Blended"); - return; - } - SDL_Texture* texture = SDL_CreateTextureFromSurface(m_renderer, surf); - if (texture == nullptr) - { - set_error_state(tErrors::TTFCreateTextureFromSurfaceFail); - print_ttf_error("SDL_CreateTextureFromSurface"); - return; - } - SDL_DestroySurface(surf); - - float w = 0, h = 0; - SDL_GetTextureSize(texture, &w, &h); - - SDL_FRect dst; - dst.x = x; - dst.y = y; - dst.w = w; - dst.h = h; - SDL_RenderTexture(m_renderer, texture, NULL, &dst); - SDL_DestroyTexture(texture); - } - - void TTFRenderer::renderCenteredText(const ostd::String& message, int32_t center_x, int32_t center_y, const ostd::Color& color, int32_t fontSize) - { - if (!TTFRenderer::m_initialized) - { - set_error_state(tErrors::Uninitialized); - return; - } - if (!m_fontOpen) - { - set_error_state(tErrors::NoFont); - return; - } - if (m_renderer == nullptr) - { - set_error_state(tErrors::NullRenderer); - return; - } - if (m_font == nullptr) - { - set_error_state(tErrors::NullFont); - return; - } - setFontSize(fontSize); - SDL_Surface* surf = TTF_RenderText_Blended(m_font, message.c_str(), message.len(), { color.r, color.g, color.b, color.a }); - if (surf == nullptr) - { - set_error_state(tErrors::TTFRenderTextBlendedFail); - print_ttf_error("TTF_RenderText_Blended"); - return; - } - SDL_Texture* texture = SDL_CreateTextureFromSurface(m_renderer, surf); - if (texture == nullptr) - { - set_error_state(tErrors::TTFCreateTextureFromSurfaceFail); - print_ttf_error("SDL_CreateTextureFromSurface"); - return; - } - SDL_DestroySurface(surf); - - float w = 0, h = 0; - SDL_GetTextureSize(texture, &w, &h); - - SDL_FRect dst; - dst.x = center_x - (w / 2); - dst.y = center_y - (h / 2); - dst.w = w; - dst.h = h; - SDL_RenderTexture(m_renderer, texture, NULL, &dst); - SDL_DestroyTexture(texture); - } - - ostd::IPoint TTFRenderer::getStringDimensions(const ostd::String& message, int32_t fontSize) - { - if (!TTFRenderer::m_initialized) - { - set_error_state(tErrors::Uninitialized); - return { 0, 0 }; - } - if (!m_fontOpen) - { - set_error_state(tErrors::NoFont); - return { 0, 0 }; - } - if (m_renderer == nullptr) - { - set_error_state(tErrors::NullRenderer); - return { 0, 0 }; - } - if (m_font == nullptr) - { - set_error_state(tErrors::NullFont); - return { 0, 0 }; - } - setFontSize(fontSize); - SDL_Surface* surf = TTF_RenderText_Blended(m_font, message.c_str(), message.len(), { 0, 0, 0, 255 }); - if (surf == nullptr) - { - set_error_state(tErrors::TTFRenderTextBlendedFail); - print_ttf_error("TTF_RenderText_Blended"); - return { 0, 0 }; - } - SDL_Texture* texture = SDL_CreateTextureFromSurface(m_renderer, surf); - if (texture == nullptr) - { - set_error_state(tErrors::TTFCreateTextureFromSurfaceFail); - print_ttf_error("SDL_CreateTextureFromSurface"); - return { 0, 0 }; - } - SDL_DestroySurface(surf); - - float w = 0, h = 0; - SDL_GetTextureSize(texture, &w, &h); - SDL_DestroyTexture(texture); - return { static_cast(w), static_cast(h) }; - } - - int32_t TTFRenderer::init(SDL_Renderer* renderer) - { - if (TTFRenderer::m_initialized) return set_error_state(tErrors::NoError); - if (renderer == nullptr) return set_error_state(tErrors::NullRenderer); - m_renderer = renderer; - TTFRenderer::m_initialized = true; - return set_error_state(tErrors::NoError); - } - - int32_t TTFRenderer::loadDefaultFont(int32_t fontSize) - { - return openFont(ubuntu_mono_regular_ttf_data, ubuntu_mono_regular_ttf_size, fontSize); - } - - void TTFRenderer::closeFont(void) - { - if (!TTFRenderer::m_initialized || !m_fontOpen) return; - if (m_font != nullptr) - TTF_CloseFont(m_font); - m_font = nullptr; - m_fontOpen = false; - m_fontSize = DefaultFontSize; - m_fontFromMemory = false; - set_error_state(tErrors::NoError); - } - - int32_t TTFRenderer::openFont(const ostd::String& fontPath, int32_t fontSize) - { - if (!TTFRenderer::m_initialized) return set_error_state(tErrors::Uninitialized); - if (m_fontOpen) closeFont(); - if (fontSize <= 0) - fontSize = m_fontSize; - else - m_fontSize = fontSize; - m_font = TTF_OpenFont(fontPath.c_str(), fontSize); - if (m_font == nullptr) - { - print_ttf_error("TTF_OpenFont"); - return set_error_state(tErrors::FailedToOpenFontFile); - } - m_fontOpen = true; - m_fontFromMemory = false; - return set_error_state(tErrors::NoError); - } - - int32_t TTFRenderer::openFont(const ostd::UByte resource_data[], uint32_t data_size, int32_t fontSize) - { - if (!TTFRenderer::m_initialized) return set_error_state(tErrors::Uninitialized); - if (data_size < 100) // Arbitrary 100 bytes - return set_error_state(tErrors::FailedToOpenFontFile); - if (m_fontOpen) closeFont(); - if (fontSize <= 0) - fontSize = m_fontSize; - else - m_fontSize = fontSize; - SDL_IOStream* rw = SDL_IOFromConstMem(resource_data, data_size); - m_font = TTF_OpenFontIO(rw, true, fontSize); - if (m_font == nullptr) - { - print_ttf_error("TTF_OpenFont"); - return set_error_state(tErrors::FailedToOpenFontFile); - } - m_fontOpen = true; - m_fontFromMemory = true; - return set_error_state(tErrors::NoError); - } - - int32_t TTFRenderer::setFontSize(int32_t fontSize) - { - if (!TTFRenderer::m_initialized) - return set_error_state(tErrors::Uninitialized); - if (!m_fontOpen) - return set_error_state(tErrors::NoFont); - if (m_font == nullptr) - return set_error_state(tErrors::NullFont); - if (fontSize == m_fontSize || fontSize <= 0) return set_error_state(tErrors::NoError); - TTF_SetFontSize(m_font, fontSize); - return set_error_state(tErrors::NoError); - } - - void TTFRenderer::print_ttf_error(const ostd::String& funcName) - { - m_out.fg(ostd::ConsoleColors::Red).p(funcName).p("(...) failed: ").p(ostd::String(SDL_GetError())).reset().nl(); - } -} diff --git a/src/ogfx/render/FontUtils.hpp b/src/ogfx/render/FontUtils.hpp deleted file mode 100644 index 48b3e9f..0000000 --- a/src/ogfx/render/FontUtils.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - OmniaFramework - A collection of useful functionality - Copyright (C) 2025 OmniaX-Dev - - This file is part of OmniaFramework. - - OmniaFramework is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OmniaFramework is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OmniaFramework. If not, see . -*/ - -#pragma once - -#include -#include -#include - -namespace ogfx -{ - class TTFRenderer - { - private: class SignalHandler : public ostd::BaseObject - { - public: - SignalHandler(TTFRenderer& parent); - void handleSignal(ostd::Signal& signal) override; - - private: - TTFRenderer& m_parent; - }; - public: struct tErrors - { - inline static constexpr int32_t NoError = 0; - inline static constexpr int32_t FailedToLoad = 1; - inline static constexpr int32_t FailedToOpenFontFile = 2; - inline static constexpr int32_t Uninitialized = 3; - inline static constexpr int32_t NullRenderer = 4; - inline static constexpr int32_t InvalidState = 5; - inline static constexpr int32_t TTFRenderTextBlendedFail = 6; - inline static constexpr int32_t TTFCreateTextureFromSurfaceFail = 7; - inline static constexpr int32_t NullFont = 8; - inline static constexpr int32_t NoFont = 9; - inline static constexpr int32_t FailedToOpenFontByteStrean = 10; - }; - public: - TTFRenderer(void) = default; - ~TTFRenderer(void); - inline TTFRenderer(SDL_Renderer* renderer) { init(renderer); } - int32_t init(SDL_Renderer* renderer); - int32_t loadDefaultFont(int32_t fontSize = 0); - void closeFont(void); - int32_t openFont(const ostd::String& fontPath, int32_t fontSize = 0); - int32_t openFont(const ostd::UByte resource_data[], uint32_t data_size, int32_t fontSize = 0); - int32_t setFontSize(int32_t fontSize); - void renderText(const ostd::String& message, int32_t x, int32_t y, const ostd::Color& color, int32_t fontSize = 0); - void renderCenteredText(const ostd::String& message, int32_t center_x, int32_t center_y, const ostd::Color& color, int32_t fontSize = 0); - ostd::IPoint getStringDimensions(const ostd::String& message, int32_t fontSize = 0); - inline bool isInitialized(void) { return TTFRenderer::m_initialized; } - inline bool hasOpenFont(void) { return m_fontOpen; } - inline TTF_Font* getSDLFont(void) { return m_font; } - inline bool isValid(void) { return TTFRenderer::m_initialized && m_fontOpen && (m_font != nullptr || m_fontFromMemory) && m_renderer != nullptr; } - inline int32_t geterrorState(void) { return m_errorState; } - inline int32_t getFontSize(void) { return m_fontSize; } - - private: - void print_ttf_error(const ostd::String& funcName); - inline int32_t set_error_state(int32_t err) { m_errorState = err; return m_errorState; } - - private: - ostd::ConsoleOutputHandler m_out; - SignalHandler m_sigHndl { *this }; - bool m_initialized { false }; - bool m_fontOpen { false }; - TTF_Font* m_font { nullptr }; - SDL_Renderer* m_renderer { nullptr }; - int32_t m_errorState { tErrors::NoError }; - int32_t m_fontSize { DefaultFontSize }; - bool m_fontFromMemory { false }; - - inline static constexpr int32_t DefaultFontSize { 16 }; - }; -} diff --git a/src/ogfx/resources/Image.hpp b/src/ogfx/resources/Image.hpp index bc55a0b..7156e46 100644 --- a/src/ogfx/resources/Image.hpp +++ b/src/ogfx/resources/Image.hpp @@ -37,7 +37,7 @@ namespace ogfx Image& loadFromFile(const ostd::String& filePath, BasicRenderer2D& gfx); inline ostd::Vec2 getSize(void) const { return { m_width, m_height }; } inline bool isLoaded(void) const { return m_loaded; } - inline SDL_Texture* getSDLTexture(void) { return m_sdl_texture; } + inline SDL_Texture* getSDLTexture(void) const { return m_sdl_texture; } private: SDL_Texture* m_sdl_texture { nullptr }; diff --git a/src/ogfx/utils/SDLInclude.hpp b/src/ogfx/utils/SDLInclude.hpp index 766b170..4a959b8 100644 --- a/src/ogfx/utils/SDLInclude.hpp +++ b/src/ogfx/utils/SDLInclude.hpp @@ -25,7 +25,6 @@ #include #include -#include #include #include #include diff --git a/src/ogfx/vendor/sdl3_gfx/SDL3_framerate.c b/src/ogfx/vendor/sdl3_gfx/SDL3_framerate.c deleted file mode 100644 index 5bff7e2..0000000 --- a/src/ogfx/vendor/sdl3_gfx/SDL3_framerate.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - -SDL3_framerate.c: framerate manager - -Copyright (C) 2012-2014 Andreas Schiffler - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. - -Andreas Schiffler -- aschiffler at ferzkopp dot net - -*/ - -#include "SDL3_framerate.h" - -/*! -\brief Internal wrapper to SDL_GetTicks that ensures a non-zero return value. - -\return The tick count. -*/ -Uint64 _getTicks() -{ - Uint64 ticks = SDL_GetTicks(); - - /* - * Since baseticks!=0 is used to track initialization - * we need to ensure that the tick count is always >0 - * since SDL_GetTicks may not have incremented yet and - * return 0 depending on the timing of the calls. - */ - if (ticks == 0) { - return 1; - } else { - return ticks; - } -} - -/*! -\brief Initialize the framerate manager. - -Initialize the framerate manager, set default framerate of 30Hz and -reset delay interpolation. - -\param manager Pointer to the framerate manager. -*/ -void SDL_initFramerate(FPSmanager * manager) -{ - /* - * Store some sane values - */ - manager->framecount = 0; - manager->rate = FPS_DEFAULT; - manager->rateticks = (1000.0f / (float) FPS_DEFAULT); - manager->baseticks = _getTicks(); - manager->lastticks = manager->baseticks; - -} - -/*! -\brief Set the framerate in Hz - -Sets a new framerate for the manager and reset delay interpolation. -Rate values must be between FPS_LOWER_LIMIT and FPS_UPPER_LIMIT inclusive to be accepted. - -\param manager Pointer to the framerate manager. -\param rate The new framerate in Hz (frames per second). - -\return 0 for sucess and -1 for error. -*/ -int SDL_setFramerate(FPSmanager * manager, Uint32 rate) -{ - if ((rate >= FPS_LOWER_LIMIT) && (rate <= FPS_UPPER_LIMIT)) { - manager->framecount = 0; - manager->rate = rate; - manager->rateticks = (1000.0f / (float) rate); - return (0); - } else { - return (-1); - } -} - -/*! -\brief Return the current target framerate in Hz - -Get the currently set framerate of the manager. - -\param manager Pointer to the framerate manager. - -\return Current framerate in Hz or -1 for error. -*/ -int SDL_getFramerate(FPSmanager * manager) -{ - if (manager == NULL) { - return (-1); - } else { - return ((int)manager->rate); - } -} - -/*! -\brief Return the current framecount. - -Get the current framecount from the framerate manager. -A frame is counted each time SDL_framerateDelay is called. - -\param manager Pointer to the framerate manager. - -\return Current frame count or -1 for error. -*/ -int SDL_getFramecount(FPSmanager * manager) -{ - if (manager == NULL) { - return (-1); - } else { - return ((int)manager->framecount); - } -} - -/*! -\brief Delay execution to maintain a constant framerate and calculate fps. - -Generate a delay to accomodate currently set framerate. Call once in the -graphics/rendering loop. If the computer cannot keep up with the rate (i.e. -drawing too slow), the delay is zero and the delay interpolation is reset. - -\param manager Pointer to the framerate manager. - -\return The time that passed since the last call to the function in ms. May return 0. -*/ -Uint64 SDL_framerateDelay(FPSmanager * manager) -{ - Uint64 current_ticks; - Uint64 target_ticks; - Uint64 the_delay; - Uint64 time_passed = 0; - - /* - * No manager, no delay - */ - if (manager == NULL) { - return 0; - } - - /* - * Initialize uninitialized manager - */ - if (manager->baseticks == 0) { - SDL_initFramerate(manager); - } - - /* - * Next frame - */ - manager->framecount++; - - /* - * Get/calc ticks - */ - current_ticks = _getTicks(); - time_passed = current_ticks - manager->lastticks; - manager->lastticks = current_ticks; - target_ticks = manager->baseticks + (Uint64) ((float) manager->framecount * manager->rateticks); - - if (current_ticks <= target_ticks) { - the_delay = target_ticks - current_ticks; - SDL_Delay(the_delay); - } else { - manager->framecount = 0; - manager->baseticks = _getTicks(); - } - - return time_passed; -} diff --git a/src/ogfx/vendor/sdl3_gfx/SDL3_framerate.h b/src/ogfx/vendor/sdl3_gfx/SDL3_framerate.h deleted file mode 100644 index 43bf8fc..0000000 --- a/src/ogfx/vendor/sdl3_gfx/SDL3_framerate.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - -SDL3_framerate.h: framerate manager - -Copyright (C) 2012-2014 Andreas Schiffler - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. - -Andreas Schiffler -- aschiffler at ferzkopp dot net - -*/ - -#ifndef _SDL3_framerate_h -#define _SDL3_framerate_h - -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - - /* --- */ - -#include - - /* --------- Definitions */ - - /*! - \brief Highest possible rate supported by framerate controller in Hz (1/s). - */ -#define FPS_UPPER_LIMIT 200 - - /*! - \brief Lowest possible rate supported by framerate controller in Hz (1/s). - */ -#define FPS_LOWER_LIMIT 1 - - /*! - \brief Default rate of framerate controller in Hz (1/s). - */ -#define FPS_DEFAULT 30 - - /*! - \brief Structure holding the state and timing information of the framerate controller. - */ - typedef struct { - Uint32 framecount; - float rateticks; - Uint64 baseticks; - Uint64 lastticks; - Uint32 rate; - } FPSmanager; - - /* ---- Function Prototypes */ - -#ifdef _MSC_VER -# if defined(DLL_EXPORT) && !defined(LIBSDL3_GFX_DLL_IMPORT) -# define SDL3_FRAMERATE_SCOPE __declspec(dllexport) -# else -# ifdef LIBSDL3_GFX_DLL_IMPORT -# define SDL3_FRAMERATE_SCOPE __declspec(dllimport) -# endif -# endif -#endif -#ifndef SDL3_FRAMERATE_SCOPE -# define SDL3_FRAMERATE_SCOPE extern -#endif - - /* Functions return 0 or value for sucess and -1 for error */ - - SDL3_FRAMERATE_SCOPE void SDL_initFramerate(FPSmanager * manager); - SDL3_FRAMERATE_SCOPE int SDL_setFramerate(FPSmanager * manager, Uint32 rate); - SDL3_FRAMERATE_SCOPE int SDL_getFramerate(FPSmanager * manager); - SDL3_FRAMERATE_SCOPE int SDL_getFramecount(FPSmanager * manager); - SDL3_FRAMERATE_SCOPE Uint64 SDL_framerateDelay(FPSmanager * manager); - - /* --- */ - - /* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif - -#endif /* _SDL3_framerate_h */ diff --git a/src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives.c b/src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives.c deleted file mode 100644 index 1726d24..0000000 --- a/src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives.c +++ /dev/null @@ -1,3794 +0,0 @@ -/* - -SDL3_gfxPrimitives.c: graphics primitives for SDL3 renderers - -Copyright (C) 2012-2014 Andreas Schiffler - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. - -Andreas Schiffler -- aschiffler at ferzkopp dot net - -*/ - -#include -#include -#include -#include - -#include "SDL3_gfxPrimitives.h" -#include "SDL3_rotozoom.h" -#include "SDL3_gfxPrimitives_font.h" - -/* ---- Pixel */ - -/*! -\brief Draw pixel in currently set color. - -\param renderer The renderer to draw on. -\param x X (horizontal) coordinate of the pixel. -\param y Y (vertical) coordinate of the pixel. - -\returns Returns true on success, false on failure. -*/ -bool pixel(SDL_Renderer *renderer, float x, float y) -{ - return SDL_RenderPoint(renderer, x, y); -} - -/*! -\brief Draw pixel with blending enabled if a<255. - -\param renderer The renderer to draw on. -\param x X (horizontal) coordinate of the pixel. -\param y Y (vertical) coordinate of the pixel. -\param color The color value of the pixel to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool pixelColor(SDL_Renderer * renderer, float x, float y, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return pixelRGBA(renderer, x, y, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw pixel with blending enabled if a<255. - -\param renderer The renderer to draw on. -\param x X (horizontal) coordinate of the pixel. -\param y Y (vertical) coordinate of the pixel. -\param r The red color value of the pixel to draw. -\param g The green color value of the pixel to draw. -\param b The blue color value of the pixel to draw. -\param a The alpha value of the pixel to draw. - -\returns Returns true on success, false on failure. -*/ -bool pixelRGBA(SDL_Renderer * renderer, float x, float y, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - bool result = true; - result &= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND); - result &= SDL_SetRenderDrawColor(renderer, r, g, b, a); - result &= SDL_RenderPoint(renderer, x, y); - return result; -} - -/*! -\brief Draw pixel with blending enabled and using alpha weight on color. - -\param renderer The renderer to draw on. -\param x The horizontal coordinate of the pixel. -\param y The vertical position of the pixel. -\param r The red color value of the pixel to draw. -\param g The green color value of the pixel to draw. -\param b The blue color value of the pixel to draw. -\param a The alpha value of the pixel to draw. -\param weight The weight multiplied into the alpha value of the pixel. - -\returns Returns true on success, false on failure. -*/ -bool pixelRGBAWeight(SDL_Renderer * renderer, float x, float y, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Uint32 weight) -{ - /* - * Modify Alpha by weight - */ - Uint32 ax = a; - ax = ((ax * weight) >> 8); - if (ax > 255) { - a = 255; - } else { - a = (Uint8)(ax & 0x000000ff); - } - - return pixelRGBA(renderer, x, y, r, g, b, a); -} - -/* ---- Hline */ - -/*! -\brief Draw horizontal line in currently set color - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point (i.e. left) of the line. -\param x2 X coordinate of the second point (i.e. right) of the line. -\param y Y coordinate of the points of the line. - -\returns Returns true on success, false on failure. -*/ -bool hline(SDL_Renderer * renderer, float x1, float x2, float y) -{ - return SDL_RenderLine(renderer, x1, y, x2, y);; -} - - -/*! -\brief Draw horizontal line with blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point (i.e. left) of the line. -\param x2 X coordinate of the second point (i.e. right) of the line. -\param y Y coordinate of the points of the line. -\param color The color value of the line to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool hlineColor(SDL_Renderer * renderer, float x1, float x2, float y, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return hlineRGBA(renderer, x1, x2, y, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw horizontal line with blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point (i.e. left) of the line. -\param x2 X coordinate of the second point (i.e. right) of the line. -\param y Y coordinate of the points of the line. -\param r The red value of the line to draw. -\param g The green value of the line to draw. -\param b The blue value of the line to draw. -\param a The alpha value of the line to draw. - -\returns Returns true on success, false on failure. -*/ -bool hlineRGBA(SDL_Renderer * renderer, float x1, float x2, float y, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - bool result = true; - result &= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND); - result &= SDL_SetRenderDrawColor(renderer, r, g, b, a); - result &= SDL_RenderLine(renderer, x1, y, x2, y); - return result; -} - -/* ---- Vline */ - -/*! -\brief Draw vertical line in currently set color - -\param renderer The renderer to draw on. -\param x X coordinate of points of the line. -\param y1 Y coordinate of the first point (i.e. top) of the line. -\param y2 Y coordinate of the second point (i.e. bottom) of the line. - -\returns Returns true on success, false on failure. -*/ -bool vline(SDL_Renderer * renderer, float x, float y1, float y2) -{ - return SDL_RenderLine(renderer, x, y1, x, y2);; -} - -/*! -\brief Draw vertical line with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the points of the line. -\param y1 Y coordinate of the first point (i.e. top) of the line. -\param y2 Y coordinate of the second point (i.e. bottom) of the line. -\param color The color value of the line to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool vlineColor(SDL_Renderer * renderer, float x, float y1, float y2, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return vlineRGBA(renderer, x, y1, y2, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw vertical line with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the points of the line. -\param y1 Y coordinate of the first point (i.e. top) of the line. -\param y2 Y coordinate of the second point (i.e. bottom) of the line. -\param r The red value of the line to draw. -\param g The green value of the line to draw. -\param b The blue value of the line to draw. -\param a The alpha value of the line to draw. - -\returns Returns true on success, false on failure. -*/ -bool vlineRGBA(SDL_Renderer * renderer, float x, float y1, float y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - bool result = true; - result &= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND); - result &= SDL_SetRenderDrawColor(renderer, r, g, b, a); - result &= SDL_RenderLine(renderer, x, y1, x, y2); - return result; -} - -/* ---- Rectangle */ - -/*! -\brief Draw rectangle with blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point (i.e. top right) of the rectangle. -\param y1 Y coordinate of the first point (i.e. top right) of the rectangle. -\param x2 X coordinate of the second point (i.e. bottom left) of the rectangle. -\param y2 Y coordinate of the second point (i.e. bottom left) of the rectangle. -\param color The color value of the rectangle to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool rectangleColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return rectangleRGBA(renderer, x1, y1, x2, y2, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw rectangle with blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point (i.e. top right) of the rectangle. -\param y1 Y coordinate of the first point (i.e. top right) of the rectangle. -\param x2 X coordinate of the second point (i.e. bottom left) of the rectangle. -\param y2 Y coordinate of the second point (i.e. bottom left) of the rectangle. -\param r The red value of the rectangle to draw. -\param g The green value of the rectangle to draw. -\param b The blue value of the rectangle to draw. -\param a The alpha value of the rectangle to draw. - -\returns Returns true on success, false on failure. -*/ -bool rectangleRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - bool result; - float tmp; - SDL_FRect rect; - - /* - * Test for special cases of straight lines or single point - */ - if (x1 == x2) { - if (y1 == y2) { - return (pixelRGBA(renderer, x1, y1, r, g, b, a)); - } else { - return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a)); - } - } else { - if (y1 == y2) { - return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a)); - } - } - - /* - * Swap x1, x2 if required - */ - if (x1 > x2) { - tmp = x1; - x1 = x2; - x2 = tmp; - } - - /* - * Swap y1, y2 if required - */ - if (y1 > y2) { - tmp = y1; - y1 = y2; - y2 = tmp; - } - - /* - * Create destination rect - */ - rect.x = x1; - rect.y = y1; - rect.w = x2 - x1; - rect.h = y2 - y1; - - /* - * Draw - */ - result = true; - result &= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND); - result &= SDL_SetRenderDrawColor(renderer, r, g, b, a); - result &= SDL_RenderRect(renderer, &rect); - return result; -} - -/* ---- Rounded Rectangle */ - -/*! -\brief Draw rounded-corner rectangle with blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point (i.e. top right) of the rectangle. -\param y1 Y coordinate of the first point (i.e. top right) of the rectangle. -\param x2 X coordinate of the second point (i.e. bottom left) of the rectangle. -\param y2 Y coordinate of the second point (i.e. bottom left) of the rectangle. -\param rad The radius of the corner arc. -\param color The color value of the rectangle to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool roundedRectangleColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float rad, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return roundedRectangleRGBA(renderer, x1, y1, x2, y2, rad, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw rounded-corner rectangle with blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point (i.e. top right) of the rectangle. -\param y1 Y coordinate of the first point (i.e. top right) of the rectangle. -\param x2 X coordinate of the second point (i.e. bottom left) of the rectangle. -\param y2 Y coordinate of the second point (i.e. bottom left) of the rectangle. -\param rad The radius of the corner arc. -\param r The red value of the rectangle to draw. -\param g The green value of the rectangle to draw. -\param b The blue value of the rectangle to draw. -\param a The alpha value of the rectangle to draw. - -\returns Returns true on success, false on failure. -*/ -bool roundedRectangleRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - Sint32 result = 0; - float tmp; - float w, h; - float xx1, xx2; - float yy1, yy2; - - /* - * Check renderer - */ - if (renderer == NULL) - { - return false; - } - - /* - * Check radius vor valid range - */ - if (rad < 0) { - return false; - } - - /* - * Special case - no rounding - */ - if (rad <= 1) { - return rectangleRGBA(renderer, x1, y1, x2, y2, r, g, b, a); - } - - /* - * Test for special cases of straight lines or single point - */ - if (x1 == x2) { - if (y1 == y2) { - return (pixelRGBA(renderer, x1, y1, r, g, b, a)); - } else { - return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a)); - } - } else { - if (y1 == y2) { - return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a)); - } - } - - /* - * Swap x1, x2 if required - */ - if (x1 > x2) { - tmp = x1; - x1 = x2; - x2 = tmp; - } - - /* - * Swap y1, y2 if required - */ - if (y1 > y2) { - tmp = y1; - y1 = y2; - y2 = tmp; - } - - /* - * Calculate width&height - */ - w = x2 - x1; - h = y2 - y1; - - /* - * Maybe adjust radius - */ - if ((rad * 2) > w) - { - rad = (Sint32) w / 2; - } - if ((rad * 2) > h) - { - rad = (Sint32) h / 2; - } - - /* - * Draw corners - */ - xx1 = x1 + rad; - xx2 = x2 - rad; - yy1 = y1 + rad; - yy2 = y2 - rad; - result &= arcRGBA(renderer, xx1, yy1, rad, 180, 270, r, g, b, a); - result &= arcRGBA(renderer, xx2, yy1, rad, 270, 360, r, g, b, a); - result &= arcRGBA(renderer, xx1, yy2, rad, 90, 180, r, g, b, a); - result &= arcRGBA(renderer, xx2, yy2, rad, 0, 90, r, g, b, a); - - /* - * Draw lines - */ - if (xx1 <= xx2) { - result &= hlineRGBA(renderer, xx1, xx2, y1, r, g, b, a); - result &= hlineRGBA(renderer, xx1, xx2, y2, r, g, b, a); - } - if (yy1 <= yy2) { - result &= vlineRGBA(renderer, x1, yy1, yy2, r, g, b, a); - result &= vlineRGBA(renderer, x2, yy1, yy2, r, g, b, a); - } - - return result; -} - -/* ---- Rounded Box */ - -/*! -\brief Draw rounded-corner box (filled rectangle) with blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point (i.e. top right) of the box. -\param y1 Y coordinate of the first point (i.e. top right) of the box. -\param x2 X coordinate of the second point (i.e. bottom left) of the box. -\param y2 Y coordinate of the second point (i.e. bottom left) of the box. -\param rad The radius of the corner arcs of the box. -\param color The color value of the box to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool roundedBoxColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float rad, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return roundedBoxRGBA(renderer, x1, y1, x2, y2, rad, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw rounded-corner box (filled rectangle) with blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point (i.e. top right) of the box. -\param y1 Y coordinate of the first point (i.e. top right) of the box. -\param x2 X coordinate of the second point (i.e. bottom left) of the box. -\param y2 Y coordinate of the second point (i.e. bottom left) of the box. -\param rad The radius of the corner arcs of the box. -\param r The red value of the box to draw. -\param g The green value of the box to draw. -\param b The blue value of the box to draw. -\param a The alpha value of the box to draw. - -\returns Returns true on success, false on failure. -*/ -bool roundedBoxRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, - float y2, float rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - bool result; - float w, h, r2, tmp; - float cx = 0; - float cy = rad; - float ocx = (float) 0xffff; - float ocy = (float) 0xffff; - float df = 1 - rad; - float d_e = 3; - float d_se = -2 * rad + 5; - float xpcx, xmcx, xpcy, xmcy; - float ypcy, ymcy, ypcx, ymcx; - float x, y, dx, dy; - - /* - * Check destination renderer - */ - if (renderer == NULL) - { - return false; - } - - /* - * Check radius vor valid range - */ - if (rad < 0) { - return false; - } - - /* - * Special case - no rounding - */ - if (rad <= 1) { - return boxRGBA(renderer, x1, y1, x2, y2, r, g, b, a); - } - - /* - * Test for special cases of straight lines or single point - */ - if (x1 == x2) { - if (y1 == y2) { - return (pixelRGBA(renderer, x1, y1, r, g, b, a)); - } else { - return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a)); - } - } else { - if (y1 == y2) { - return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a)); - } - } - - /* - * Swap x1, x2 if required - */ - if (x1 > x2) { - tmp = x1; - x1 = x2; - x2 = tmp; - } - - /* - * Swap y1, y2 if required - */ - if (y1 > y2) { - tmp = y1; - y1 = y2; - y2 = tmp; - } - - /* - * Calculate width&height - */ - w = x2 - x1 + 1; - h = y2 - y1 + 1; - - /* - * Maybe adjust radius - */ - r2 = rad + rad; - if (r2 > w) - { - rad = (Sint32) w / 2; - r2 = rad + rad; - } - if (r2 > h) - { - rad = (Sint32) h / 2; - } - - /* Setup filled circle drawing for corners */ - x = x1 + rad; - y = y1 + rad; - dx = x2 - x1 - rad - rad; - dy = y2 - y1 - rad - rad; - - /* - * Set color - */ - result = true; - result &= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND); - result &= SDL_SetRenderDrawColor(renderer, r, g, b, a); - - /* - * Draw corners - */ - do { - xpcx = x + cx; - xmcx = x - cx; - xpcy = x + cy; - xmcy = x - cy; - if (ocy != cy) { - if (cy > 0) { - ypcy = y + cy; - ymcy = y - cy; - result &= hline(renderer, xmcx, xpcx + dx, ypcy + dy); - result &= hline(renderer, xmcx, xpcx + dx, ymcy); - } else { - result &= hline(renderer, xmcx, xpcx + dx, y); - } - ocy = cy; - } - if (ocx != cx) { - if (cx != cy) { - if (cx > 0) { - ypcx = y + cx; - ymcx = y - cx; - result &= hline(renderer, xmcy, xpcy + dx, ymcx); - result &= hline(renderer, xmcy, xpcy + dx, ypcx + dy); - } else { - result &= hline(renderer, xmcy, xpcy + dx, y); - } - } - ocx = cx; - } - - /* - * Update - */ - if (df < 0) { - df += d_e; - d_e += 2; - d_se += 2; - } else { - df += d_se; - d_e += 2; - d_se += 4; - cy--; - } - cx++; - } while (cx <= cy); - - /* Inside */ - if (dx > 0 && dy > 0) { - result &= boxRGBA(renderer, x1, y1 + rad + 1, x2, y2 - rad, r, g, b, a); - } - - return (result); -} - -/* ---- Box */ - -/*! -\brief Draw box (filled rectangle) with blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point (i.e. top right) of the box. -\param y1 Y coordinate of the first point (i.e. top right) of the box. -\param x2 X coordinate of the second point (i.e. bottom left) of the box. -\param y2 Y coordinate of the second point (i.e. bottom left) of the box. -\param color The color value of the box to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool boxColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return boxRGBA(renderer, x1, y1, x2, y2, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw box (filled rectangle) with blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point (i.e. top right) of the box. -\param y1 Y coordinate of the first point (i.e. top right) of the box. -\param x2 X coordinate of the second point (i.e. bottom left) of the box. -\param y2 Y coordinate of the second point (i.e. bottom left) of the box. -\param r The red value of the box to draw. -\param g The green value of the box to draw. -\param b The blue value of the box to draw. -\param a The alpha value of the box to draw. - -\returns Returns true on success, false on failure. -*/ -bool boxRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - bool result; - float tmp; - SDL_FRect rect; - - /* - * Test for special cases of straight lines or single point - */ - if (x1 == x2) { - if (y1 == y2) { - return (pixelRGBA(renderer, x1, y1, r, g, b, a)); - } else { - return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a)); - } - } else { - if (y1 == y2) { - return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a)); - } - } - - /* - * Swap x1, x2 if required - */ - if (x1 > x2) { - tmp = x1; - x1 = x2; - x2 = tmp; - } - - /* - * Swap y1, y2 if required - */ - if (y1 > y2) { - tmp = y1; - y1 = y2; - y2 = tmp; - } - - /* - * Create destination rect - */ - rect.x = x1; - rect.y = y1; - rect.w = x2 - x1 + 1; - rect.h = y2 - y1 + 1; - - /* - * Draw - */ - result = true; - result &= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND); - result &= SDL_SetRenderDrawColor(renderer, r, g, b, a); - result &= SDL_RenderFillRect(renderer, &rect); - return result; -} - -/* ----- Line */ - -/*! -\brief Draw line with alpha blending using the currently set color. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the line. -\param y1 Y coordinate of the first point of the line. -\param x2 X coordinate of the second point of the line. -\param y2 Y coordinate of the second point of the line. - -\returns Returns true on success, false on failure. -*/ -bool line(SDL_Renderer * renderer, float x1, float y1, float x2, float y2) -{ - /* - * Draw - */ - return SDL_RenderLine(renderer, x1, y1, x2, y2); -} - -/*! -\brief Draw line with alpha blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the line. -\param y1 Y coordinate of the first point of the line. -\param x2 X coordinate of the second point of the line. -\param y2 Y coordinate of the seond point of the line. -\param color The color value of the line to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool lineColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return lineRGBA(renderer, x1, y1, x2, y2, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw line with alpha blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the line. -\param y1 Y coordinate of the first point of the line. -\param x2 X coordinate of the second point of the line. -\param y2 Y coordinate of the second point of the line. -\param r The red value of the line to draw. -\param g The green value of the line to draw. -\param b The blue value of the line to draw. -\param a The alpha value of the line to draw. - -\returns Returns true on success, false on failure. -*/ -bool lineRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - /* - * Draw - */ - bool result = true; - result &= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND); - result &= SDL_SetRenderDrawColor(renderer, r, g, b, a); - result &= SDL_RenderLine(renderer, x1, y1, x2, y2); - return result; -} - -/* ---- AA Line */ - -#define AAlevels 256 -#define AAbits 8 - -/*! -\brief Internal function to draw anti-aliased line with alpha blending and endpoint control. - -This implementation of the Wu antialiasing code is based on Mike Abrash's -DDJ article which was reprinted as Chapter 42 of his Graphics Programming -Black Book, but has been optimized to work with SDL and utilizes 32-bit -fixed-point arithmetic by A. Schiffler. The endpoint control allows the -supression to draw the last pixel useful for rendering continous aa-lines -with alpha<255. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the aa-line. -\param y1 Y coordinate of the first point of the aa-line. -\param x2 X coordinate of the second point of the aa-line. -\param y2 Y coordinate of the second point of the aa-line. -\param r The red value of the aa-line to draw. -\param g The green value of the aa-line to draw. -\param b The blue value of the aa-line to draw. -\param a The alpha value of the aa-line to draw. -\param draw_endpoint Flag indicating if the endpoint should be drawn; draw if non-zero. - -\returns Returns true on success, false on failure. -*/ -bool _aalineRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a, bool draw_endpoint) -{ - float xx0, yy0, xx1, yy1; - bool result; - Uint32 intshift, erracc, erradj; - Uint32 erracctmp, wgt; - Sint32 dx, dy, tmp, xdir, y0p1, x0pxdir; - - /* - * Keep on working with 32bit numbers - */ - xx0 = x1; - yy0 = y1; - xx1 = x2; - yy1 = y2; - - /* - * Reorder points to make dy positive - */ - if (yy0 > yy1) { - tmp = yy0; - yy0 = yy1; - yy1 = tmp; - tmp = xx0; - xx0 = xx1; - xx1 = tmp; - } - - /* - * Calculate distance - */ - dx = xx1 - xx0; - dy = yy1 - yy0; - - /* - * Adjust for negative dx and set xdir - */ - if (dx >= 0) { - xdir = 1; - } else { - xdir = -1; - dx = (-dx); - } - - /* - * Check for special cases - */ - if (dx == 0) { - /* - * Vertical line - */ - if (draw_endpoint) - { - return (vlineRGBA(renderer, x1, y1, y2, r, g, b, a)); - } else { - if (dy > 0) { - return (vlineRGBA(renderer, x1, yy0, yy0+dy, r, g, b, a)); - } else { - return (pixelRGBA(renderer, x1, y1, r, g, b, a)); - } - } - } else if (dy == 0) { - /* - * Horizontal line - */ - if (draw_endpoint) - { - return (hlineRGBA(renderer, x1, x2, y1, r, g, b, a)); - } else { - if (dx > 0) { - return (hlineRGBA(renderer, xx0, xx0+(xdir*dx), y1, r, g, b, a)); - } else { - return (pixelRGBA(renderer, x1, y1, r, g, b, a)); - } - } - } else if ((dx == dy) && (draw_endpoint)) { - /* - * Diagonal line (with endpoint) - */ - return (lineRGBA(renderer, x1, y1, x2, y2, r, g, b, a)); - } - - - /* - * Line is not horizontal, vertical or diagonal (with endpoint) - */ - result = true; - - /* - * Zero accumulator - */ - erracc = 0; - - /* - * # of bits by which to shift erracc to get intensity level - */ - intshift = 32 - AAbits; - - /* - * Draw the initial pixel in the foreground color - */ - result &= pixelRGBA(renderer, x1, y1, r, g, b, a); - - /* - * x-major or y-major? - */ - if (dy > dx) { - - /* - * y-major. Calculate 16-bit fixed point fractional part of a pixel that - * X advances every time Y advances 1 pixel, truncating the result so that - * we won't overrun the endpoint along the X axis - */ - /* - * Not-so-portable version: erradj = ((Uint64)dx << 32) / (Uint64)dy; - */ - erradj = ((dx << 16) / dy) << 16; - - /* - * draw all pixels other than the first and last - */ - x0pxdir = xx0 + xdir; - while (--dy) { - erracctmp = erracc; - erracc += erradj; - if (erracc <= erracctmp) { - /* - * rollover in error accumulator, x coord advances - */ - xx0 = x0pxdir; - x0pxdir += xdir; - } - yy0++; /* y-major so always advance Y */ - - /* - * the AAbits most significant bits of erracc give us the intensity - * weighting for this pixel, and the complement of the weighting for - * the paired pixel. - */ - wgt = (erracc >> intshift) & 255; - result &= pixelRGBAWeight (renderer, xx0, yy0, r, g, b, a, 255 - wgt); - result &= pixelRGBAWeight (renderer, x0pxdir, yy0, r, g, b, a, wgt); - } - - } else { - - /* - * x-major line. Calculate 16-bit fixed-point fractional part of a pixel - * that Y advances each time X advances 1 pixel, truncating the result so - * that we won't overrun the endpoint along the X axis. - */ - /* - * Not-so-portable version: erradj = ((Uint64)dy << 32) / (Uint64)dx; - */ - erradj = ((dy << 16) / dx) << 16; - - /* - * draw all pixels other than the first and last - */ - y0p1 = yy0 + 1; - while (--dx) { - - erracctmp = erracc; - erracc += erradj; - if (erracc <= erracctmp) { - /* - * Accumulator turned over, advance y - */ - yy0 = y0p1; - y0p1++; - } - xx0 += xdir; /* x-major so always advance X */ - /* - * the AAbits most significant bits of erracc give us the intensity - * weighting for this pixel, and the complement of the weighting for - * the paired pixel. - */ - wgt = (erracc >> intshift) & 255; - result &= pixelRGBAWeight (renderer, xx0, yy0, r, g, b, a, 255 - wgt); - result &= pixelRGBAWeight (renderer, xx0, y0p1, r, g, b, a, wgt); - } - } - - /* - * Do we have to draw the endpoint - */ - if (draw_endpoint) { - /* - * Draw final pixel, always exactly intersected by the line and doesn't - * need to be weighted. - */ - result &= pixelRGBA (renderer, x2, y2, r, g, b, a); - } - - return (result); -} - -/*! -\brief Draw anti-aliased line with alpha blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the aa-line. -\param y1 Y coordinate of the first point of the aa-line. -\param x2 X coordinate of the second point of the aa-line. -\param y2 Y coordinate of the second point of the aa-line. -\param color The color value of the aa-line to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool aalineColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return _aalineRGBA(renderer, x1, y1, x2, y2, c[0], c[1], c[2], c[3], true); -} - -/*! -\brief Draw anti-aliased line with alpha blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the aa-line. -\param y1 Y coordinate of the first point of the aa-line. -\param x2 X coordinate of the second point of the aa-line. -\param y2 Y coordinate of the second point of the aa-line. -\param r The red value of the aa-line to draw. -\param g The green value of the aa-line to draw. -\param b The blue value of the aa-line to draw. -\param a The alpha value of the aa-line to draw. - -\returns Returns true on success, false on failure. -*/ -bool aalineRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - return _aalineRGBA(renderer, x1, y1, x2, y2, r, g, b, a, true); -} - -/* ----- Circle */ - -/*! -\brief Draw circle with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the circle. -\param y Y coordinate of the center of the circle. -\param rad Radius in pixels of the circle. -\param color The color value of the circle to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool circleColor(SDL_Renderer * renderer, float x, float y, float rad, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return ellipseRGBA(renderer, x, y, rad, rad, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw circle with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the circle. -\param y Y coordinate of the center of the circle. -\param rad Radius in pixels of the circle. -\param r The red value of the circle to draw. -\param g The green value of the circle to draw. -\param b The blue value of the circle to draw. -\param a The alpha value of the circle to draw. - -\returns Returns true on success, false on failure. -*/ -bool circleRGBA(SDL_Renderer * renderer, float x, float y, float rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - return ellipseRGBA(renderer, x, y, rad, rad, r, g, b, a); -} - -/* ----- Arc */ - -/*! -\brief Arc with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the arc. -\param y Y coordinate of the center of the arc. -\param rad Radius in pixels of the arc. -\param start Starting radius in degrees of the arc. 0 degrees is down, increasing counterclockwise. -\param end Ending radius in degrees of the arc. 0 degrees is down, increasing counterclockwise. -\param color The color value of the arc to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool arcColor(SDL_Renderer * renderer, float x, float y, float rad, Sint32 start, Sint32 end, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return arcRGBA(renderer, x, y, rad, start, end, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Arc with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the arc. -\param y Y coordinate of the center of the arc. -\param rad Radius in pixels of the arc. -\param start Starting radius in degrees of the arc. 0 degrees is down, increasing counterclockwise. -\param end Ending radius in degrees of the arc. 0 degrees is down, increasing counterclockwise. -\param r The red value of the arc to draw. -\param g The green value of the arc to draw. -\param b The blue value of the arc to draw. -\param a The alpha value of the arc to draw. - -\returns Returns true on success, false on failure. -*/ -/* TODO: rewrite algorithm; arc endpoints are not always drawn */ -bool arcRGBA(SDL_Renderer * renderer, float x, float y, float rad, Sint32 start, Sint32 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - bool result; - float cx = 0; - float cy = rad; - float df = 1 - rad; - float d_e = 3; - float d_se = -2 * rad + 5; - float xpcx, xmcx, xpcy, xmcy; - float ypcy, ymcy, ypcx, ymcx; - Uint8 drawoct; - Sint32 startoct, endoct, oct, stopval_start = 0, stopval_end = 0; - double dstart, dend, temp = 0.; - - /* - * Sanity check radius - */ - if (rad < 0) { - return (false); - } - - /* - * Special case for rad=0 - draw a point - */ - if (rad == 0) { - return (pixelRGBA(renderer, x, y, r, g, b, a)); - } - - /* - Octant labeling - - \ 5 | 6 / - \ | / - 4 \ | / 7 - \|/ - ------+------ +x - /|\ - 3 / | \ 0 - / | \ - / 2 | 1 \ - +y - - Initially reset bitmask to 0x00000000 - the set whether or not to keep drawing a given octant. - For example: 0x00111100 means we're drawing in octants 2-5 - */ - drawoct = 0; - - /* - * Fixup angles - */ - start %= 360; - end %= 360; - /* 0 <= start & end < 360; note that sometimes start > end - if so, arc goes back through 0. */ - while (start < 0) start += 360; - while (end < 0) end += 360; - start %= 360; - end %= 360; - - /* now, we find which octants we're drawing in. */ - startoct = start / 45; - endoct = end / 45; - oct = startoct - 1; - - /* stopval_start, stopval_end; what values of cx to stop at. */ - do { - oct = (oct + 1) % 8; - - if (oct == startoct) { - /* need to compute stopval_start for this octant. Look at picture above if this is unclear */ - dstart = (double)start; - switch (oct) - { - case 0: - case 3: - temp = sin(dstart * M_PI / 180.); - break; - case 1: - case 6: - temp = cos(dstart * M_PI / 180.); - break; - case 2: - case 5: - temp = -cos(dstart * M_PI / 180.); - break; - case 4: - case 7: - temp = -sin(dstart * M_PI / 180.); - break; - default: - break; - } - temp *= rad; - stopval_start = (int)temp; - - /* - This isn't arbitrary, but requires graph paper to explain well. - The basic idea is that we're always changing drawoct after we draw, so we - stop immediately after we render the last sensible pixel at x = ((int)temp). - and whether to draw in this octant initially - */ - if (oct % 2) drawoct |= (1 << oct); /* this is basically like saying drawoct[oct] = true, if drawoct were a bool array */ - else drawoct &= 255 - (1 << oct); /* this is basically like saying drawoct[oct] = false */ - } - if (oct == endoct) { - /* need to compute stopval_end for this octant */ - dend = (double)end; - switch (oct) - { - case 0: - case 3: - temp = sin(dend * M_PI / 180); - break; - case 1: - case 6: - temp = cos(dend * M_PI / 180); - break; - case 2: - case 5: - temp = -cos(dend * M_PI / 180); - break; - case 4: - case 7: - temp = -sin(dend * M_PI / 180); - break; - default: - break; - } - temp *= rad; - stopval_end = (int)temp; - - /* and whether to draw in this octant initially */ - if (startoct == endoct) { - /* note: we start drawing, stop, then start again in this case */ - /* otherwise: we only draw in this octant, so initialize it to false, it will get set back to true */ - if (start > end) { - /* unfortunately, if we're in the same octant and need to draw over the whole circle, */ - /* we need to set the rest to true, because the while loop will end at the bottom. */ - drawoct = 255; - } else { - drawoct &= 255 - (1 << oct); - } - } - else if (oct % 2) drawoct &= 255 - (1 << oct); - else drawoct |= (1 << oct); - } else if (oct != startoct) { /* already verified that it's != endoct */ - drawoct |= (1 << oct); /* draw this entire segment */ - } - } while (oct != endoct); - - /* so now we have what octants to draw and when to draw them. all that's left is the actual raster code. */ - - /* - * Set color - */ - result = true; - result &= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND); - result &= SDL_SetRenderDrawColor(renderer, r, g, b, a); - - /* - * Draw arc - */ - do { - ypcy = y + cy; - ymcy = y - cy; - if (cx > 0) { - xpcx = x + cx; - xmcx = x - cx; - - /* always check if we're drawing a certain octant before adding a pixel to that octant. */ - if (drawoct & 4) result &= pixel(renderer, xmcx, ypcy); - if (drawoct & 2) result &= pixel(renderer, xpcx, ypcy); - if (drawoct & 32) result &= pixel(renderer, xmcx, ymcy); - if (drawoct & 64) result &= pixel(renderer, xpcx, ymcy); - } else { - if (drawoct & 96) result &= pixel(renderer, x, ymcy); - if (drawoct & 6) result &= pixel(renderer, x, ypcy); - } - - xpcy = x + cy; - xmcy = x - cy; - if (cx > 0 && cx != cy) { - ypcx = y + cx; - ymcx = y - cx; - if (drawoct & 8) result &= pixel(renderer, xmcy, ypcx); - if (drawoct & 1) result &= pixel(renderer, xpcy, ypcx); - if (drawoct & 16) result &= pixel(renderer, xmcy, ymcx); - if (drawoct & 128) result &= pixel(renderer, xpcy, ymcx); - } else if (cx == 0) { - if (drawoct & 24) result &= pixel(renderer, xmcy, y); - if (drawoct & 129) result &= pixel(renderer, xpcy, y); - } - - /* - * Update whether we're drawing an octant - */ - if (stopval_start == cx) { - /* works like an on-off switch. */ - /* This is just in case start & end are in the same octant. */ - if (drawoct & (1 << startoct)) drawoct &= 255 - (1 << startoct); - else drawoct |= (1 << startoct); - } - if (stopval_end == cx) { - if (drawoct & (1 << endoct)) drawoct &= 255 - (1 << endoct); - else drawoct |= (1 << endoct); - } - - /* - * Update pixels - */ - if (df < 0) { - df += d_e; - d_e += 2; - d_se += 2; - } else { - df += d_se; - d_e += 2; - d_se += 4; - cy--; - } - cx++; - } while (cx <= cy); - - return (result); -} - -/* ----- AA Circle */ - -/*! -\brief Draw anti-aliased circle with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the aa-circle. -\param y Y coordinate of the center of the aa-circle. -\param rad Radius in pixels of the aa-circle. -\param color The color value of the aa-circle to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool aacircleColor(SDL_Renderer * renderer, float x, float y, float rad, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return aaellipseRGBA(renderer, x, y, rad, rad, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw anti-aliased circle with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the aa-circle. -\param y Y coordinate of the center of the aa-circle. -\param rad Radius in pixels of the aa-circle. -\param r The red value of the aa-circle to draw. -\param g The green value of the aa-circle to draw. -\param b The blue value of the aa-circle to draw. -\param a The alpha value of the aa-circle to draw. - -\returns Returns true on success, false on failure. -*/ -bool aacircleRGBA(SDL_Renderer * renderer, float x, float y, float rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - /* - * Draw - */ - return aaellipseRGBA(renderer, x, y, rad, rad, r, g, b, a); -} - -/* ----- Ellipse */ - -/*! -\brief Internal function to draw pixels or lines in 4 quadrants. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the quadrant. -\param y Y coordinate of the center of the quadrant. -\param dx X offset in pixels of the corners of the quadrant. -\param dy Y offset in pixels of the corners of the quadrant. -\param f Flag indicating if the quadrant should be filled (1) or not (0). - -\returns Returns true on success, false on failure. -*/ -bool _drawQuadrants(SDL_Renderer * renderer, float x, float y, float dx, float dy, bool f) -{ - bool result = true; - float xpdx, xmdx; - float ypdy, ymdy; - - if (dx == 0) { - if (dy == 0) { - result &= pixel(renderer, x, y); - } else { - ypdy = y + dy; - ymdy = y - dy; - if (f) { - result &= vline(renderer, x, ymdy, ypdy); - } else { - result &= pixel(renderer, x, ypdy); - result &= pixel(renderer, x, ymdy); - } - } - } else { - xpdx = x + dx; - xmdx = x - dx; - ypdy = y + dy; - ymdy = y - dy; - if (f) { - result &= vline(renderer, xpdx, ymdy, ypdy); - result &= vline(renderer, xmdx, ymdy, ypdy); - } else { - result &= pixel(renderer, xpdx, ypdy); - result &= pixel(renderer, xmdx, ypdy); - result &= pixel(renderer, xpdx, ymdy); - result &= pixel(renderer, xmdx, ymdy); - } - } - - return result; -} - -/*! -\brief Internal function to draw ellipse or filled ellipse with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the ellipse. -\param y Y coordinate of the center of the ellipse. -\param rx Horizontal radius in pixels of the ellipse. -\param ry Vertical radius in pixels of the ellipse. -\param r The red value of the ellipse to draw. -\param g The green value of the ellipse to draw. -\param b The blue value of the ellipse to draw. -\param a The alpha value of the ellipse to draw. -\param f Flag indicating if the ellipse should be filled (1) or not (0). - -\returns Returns true on success, false on failure. -*/ -#define DEFAULT_ELLIPSE_OVERSCAN 4 -bool _ellipseRGBA(SDL_Renderer * renderer, float x, float y, float rx, float ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a, bool f) -{ - bool result; - Sint32 rxi, ryi; - Sint32 rx2, ry2, rx22, ry22; - Sint32 error; - Sint32 curX, curY, curXp1, curYm1; - Sint32 scrX, scrY, oldX, oldY; - Sint32 deltaX, deltaY; - Sint32 ellipseOverscan; - - /* - * Sanity check radii - */ - if ((rx < 0) || (ry < 0)) { - return (false); - } - - /* - * Set color - */ - result = true; - result &= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND); - result &= SDL_SetRenderDrawColor(renderer, r, g, b, a); - - /* - * Special cases for rx=0 and/or ry=0: draw a hline/vline/pixel - */ - if (rx == 0) { - if (ry == 0) { - return (pixel(renderer, x, y)); - } else { - return (vline(renderer, x, y - ry, y + ry)); - } - } else { - if (ry == 0) { - return (hline(renderer, x - rx, x + rx, y)); - } - } - - /* - * Special case for radii > 0 and < 1 - */ - if (rx > 0 && rx < 1) { - rx = 1.0f; - } - - if (ry > 0 && ry < 1) { - ry = 1.0f; - } - - /* - * Adjust overscan - */ - rxi = rx; - ryi = ry; - if (rxi >= 512 || ryi >= 512) - { - ellipseOverscan = DEFAULT_ELLIPSE_OVERSCAN / 4; - } - else if (rxi >= 256 || ryi >= 256) - { - ellipseOverscan = DEFAULT_ELLIPSE_OVERSCAN / 2; - } - else - { - ellipseOverscan = DEFAULT_ELLIPSE_OVERSCAN / 1; - } - - /* - * Top/bottom center points. - */ - oldX = scrX = 0; - oldY = scrY = ryi; - result &= _drawQuadrants(renderer, x, y, 0, ry, f); - - /* Midpoint ellipse algorithm with overdraw */ - rxi *= ellipseOverscan; - ryi *= ellipseOverscan; - rx2 = rxi * rxi; - rx22 = rx2 + rx2; - ry2 = ryi * ryi; - ry22 = ry2 + ry2; - curX = 0; - curY = ryi; - deltaX = 0; - deltaY = rx22 * curY; - - /* Points in segment 1 */ - error = ry2 - rx2 * ryi + rx2 / 4; - while (deltaX <= deltaY) - { - curX++; - deltaX += ry22; - - error += deltaX + ry2; - if (error >= 0) - { - curY--; - deltaY -= rx22; - error -= deltaY; - } - - scrX = curX / ellipseOverscan; - scrY = curY / ellipseOverscan; - if ((scrX != oldX && scrY == oldY) || (scrX != oldX && scrY != oldY)) { - result &= _drawQuadrants(renderer, x, y, scrX, scrY, f); - oldX = scrX; - oldY = scrY; - } - } - - /* Points in segment 2 */ - if (curY > 0) - { - curXp1 = curX + 1; - curYm1 = curY - 1; - error = ry2 * curX * curXp1 + ((ry2 + 3) / 4) + rx2 * curYm1 * curYm1 - rx2 * ry2; - while (curY > 0) - { - curY--; - deltaY -= rx22; - - error += rx2; - error -= deltaY; - - if (error <= 0) - { - curX++; - deltaX += ry22; - error += deltaX; - } - - scrX = curX / ellipseOverscan; - scrY = curY / ellipseOverscan; - if ((scrX != oldX && scrY == oldY) || (scrX != oldX && scrY != oldY)) { - oldY--; - for (;oldY >= scrY; oldY--) { - result &= _drawQuadrants(renderer, x, y, scrX, oldY, f); - /* prevent overdraw */ - if (f) { - oldY = scrY - 1; - } - } - oldX = scrX; - oldY = scrY; - } - } - - /* Remaining points in vertical */ - if (!f) { - oldY--; - for (;oldY >= 0; oldY--) { - result &= _drawQuadrants(renderer, x, y, scrX, oldY, f); - } - } - } - - return (result); -} - -/*! -\brief Draw ellipse with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the ellipse. -\param y Y coordinate of the center of the ellipse. -\param rx Horizontal radius in pixels of the ellipse. -\param ry Vertical radius in pixels of the ellipse. -\param color The color value of the ellipse to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool ellipseColor(SDL_Renderer * renderer, float x, float y, float rx, float ry, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return _ellipseRGBA(renderer, x, y, rx, ry, c[0], c[1], c[2], c[3], false); -} - -/*! -\brief Draw ellipse with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the ellipse. -\param y Y coordinate of the center of the ellipse. -\param rx Horizontal radius in pixels of the ellipse. -\param ry Vertical radius in pixels of the ellipse. -\param r The red value of the ellipse to draw. -\param g The green value of the ellipse to draw. -\param b The blue value of the ellipse to draw. -\param a The alpha value of the ellipse to draw. - -\returns Returns true on success, false on failure. -*/ -bool ellipseRGBA(SDL_Renderer * renderer, float x, float y, float rx, float ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - return _ellipseRGBA(renderer, x, y, rx, ry, r, g, b, a, false); -} - -/* ----- Filled Circle */ - -/*! -\brief Draw filled circle with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the filled circle. -\param y Y coordinate of the center of the filled circle. -\param rad Radius in pixels of the filled circle. -\param color The color value of the filled circle to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool filledCircleColor(SDL_Renderer * renderer, float x, float y, float rad, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return filledEllipseRGBA(renderer, x, y, rad, rad, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw filled circle with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the filled circle. -\param y Y coordinate of the center of the filled circle. -\param rad Radius in pixels of the filled circle. -\param r The red value of the filled circle to draw. -\param g The green value of the filled circle to draw. -\param b The blue value of the filled circle to draw. -\param a The alpha value of the filled circle to draw. - -\returns Returns true on success, false on failure. -*/ -bool filledCircleRGBA(SDL_Renderer * renderer, float x, float y, float rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - return _ellipseRGBA(renderer, x, y, rad, rad, r, g ,b, a, true); -} - - -/* ----- AA Ellipse */ - -/* Windows targets do not have lrint, so provide a local inline version */ -#if defined(_MSC_VER) && _MSC_VER < 1920 -/* Detect 64bit and use intrinsic version */ -#ifdef _M_X64 -#include -static __inline long - lrint(float f) -{ - return _mm_cvtss_si32(_mm_load_ss(&f)); -} -#elif defined(_M_IX86) -__inline long int - lrint (double flt) -{ - int intgr; - _asm - { - fld flt - fistp intgr - }; - return intgr; -} -#elif defined(_M_ARM) -#include -#pragma warning(push) -#pragma warning(disable: 4716) -__declspec(naked) long int - lrint (double flt) -{ - __emit(0xEC410B10); // fmdrr d0, r0, r1 - __emit(0xEEBD0B40); // ftosid s0, d0 - __emit(0xEE100A10); // fmrs r0, s0 - __emit(0xE12FFF1E); // bx lr -} -#pragma warning(pop) -#else -#error lrint needed for MSVC on non X86/AMD64/ARM targets. -#endif -#endif - -/*! -\brief Draw anti-aliased ellipse with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the aa-ellipse. -\param y Y coordinate of the center of the aa-ellipse. -\param rx Horizontal radius in pixels of the aa-ellipse. -\param ry Vertical radius in pixels of the aa-ellipse. -\param color The color value of the aa-ellipse to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool aaellipseColor(SDL_Renderer * renderer, float x, float y, float rx, float ry, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return aaellipseRGBA(renderer, x, y, rx, ry, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw anti-aliased ellipse with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the aa-ellipse. -\param y Y coordinate of the center of the aa-ellipse. -\param rx Horizontal radius in pixels of the aa-ellipse. -\param ry Vertical radius in pixels of the aa-ellipse. -\param r The red value of the aa-ellipse to draw. -\param g The green value of the aa-ellipse to draw. -\param b The blue value of the aa-ellipse to draw. -\param a The alpha value of the aa-ellipse to draw. - -\returns Returns true on success, false on failure. -*/ -bool aaellipseRGBA(SDL_Renderer * renderer, float x, float y, float rx, float ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - bool result; - Sint32 i; - Sint32 a2, b2, ds, dt, dxt, t, s, d; - float xp, yp, xs, ys, dyt, od, xx, yy, xc2, yc2; - float cp; - double sab; - Uint8 weight, iweight; - - /* - * Sanity check radii - */ - if ((rx < 0) || (ry < 0)) { - return (false); - } - - /* - * Special cases for rx=0 and/or ry=0: draw a hline/vline/pixel - */ - if (rx == 0) { - if (ry == 0) { - return (pixelRGBA(renderer, x, y, r, g, b, a)); - } else { - return (vlineRGBA(renderer, x, y - ry, y + ry, r, g, b, a)); - } - } else { - if (ry == 0) { - return (hlineRGBA(renderer, x - rx, x + rx, y, r, g, b, a)); - } - } - - /* Variable setup */ - a2 = rx * rx; - b2 = ry * ry; - - ds = 2 * a2; - dt = 2 * b2; - - xc2 = 2 * x; - yc2 = 2 * y; - - sab = sqrt((double)(a2 + b2)); - od = (float)lrint(sab*0.01) + 1; /* introduce some overdraw */ - dxt = (float)lrint((double)a2 / sab) + od; - - t = 0; - s = -2 * a2 * ry; - d = 0; - - xp = x; - yp = y - ry; - - /* Draw */ - result = true; - result &= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND); - - /* "End points" */ - result &= pixelRGBA(renderer, xp, yp, r, g, b, a); - result &= pixelRGBA(renderer, xc2 - xp, yp, r, g, b, a); - result &= pixelRGBA(renderer, xp, yc2 - yp, r, g, b, a); - result &= pixelRGBA(renderer, xc2 - xp, yc2 - yp, r, g, b, a); - - for (i = 1; i <= dxt; i++) { - xp--; - d += t - b2; - - if (d >= 0) - ys = yp - 1; - else if ((d - s - a2) > 0) { - if ((2 * d - s - a2) >= 0) - ys = yp + 1; - else { - ys = yp; - yp++; - d -= s + a2; - s += ds; - } - } else { - yp++; - ys = yp + 1; - d -= s + a2; - s += ds; - } - - t -= dt; - - /* Calculate alpha */ - if (s != 0) { - cp = (float) abs(d) / (float) abs(s); - if (cp > 1.0) { - cp = 1.0; - } - } else { - cp = 1.0; - } - - /* Calculate weights */ - weight = (Uint8) (cp * 255); - iweight = 255 - weight; - - /* Upper half */ - xx = xc2 - xp; - result &= pixelRGBAWeight(renderer, xp, yp, r, g, b, a, iweight); - result &= pixelRGBAWeight(renderer, xx, yp, r, g, b, a, iweight); - - result &= pixelRGBAWeight(renderer, xp, ys, r, g, b, a, weight); - result &= pixelRGBAWeight(renderer, xx, ys, r, g, b, a, weight); - - /* Lower half */ - yy = yc2 - yp; - result &= pixelRGBAWeight(renderer, xp, yy, r, g, b, a, iweight); - result &= pixelRGBAWeight(renderer, xx, yy, r, g, b, a, iweight); - - yy = yc2 - ys; - result &= pixelRGBAWeight(renderer, xp, yy, r, g, b, a, weight); - result &= pixelRGBAWeight(renderer, xx, yy, r, g, b, a, weight); - } - - /* Replaces original approximation code dyt = abs(yp - yc); */ - dyt = (float)lrint((double)b2 / sab ) + od; - - for (i = 1; i <= dyt; i++) { - yp++; - d -= s + a2; - - if (d <= 0) - xs = xp + 1; - else if ((d + t - b2) < 0) { - if ((2 * d + t - b2) <= 0) - xs = xp - 1; - else { - xs = xp; - xp--; - d += t - b2; - t -= dt; - } - } else { - xp--; - xs = xp - 1; - d += t - b2; - t -= dt; - } - - s += ds; - - /* Calculate alpha */ - if (t != 0) { - cp = (float) abs(d) / (float) abs(t); - if (cp > 1.0) { - cp = 1.0; - } - } else { - cp = 1.0; - } - - /* Calculate weight */ - weight = (Uint8) (cp * 255); - iweight = 255 - weight; - - /* Left half */ - xx = xc2 - xp; - yy = yc2 - yp; - result &= pixelRGBAWeight(renderer, xp, yp, r, g, b, a, iweight); - result &= pixelRGBAWeight(renderer, xx, yp, r, g, b, a, iweight); - - result &= pixelRGBAWeight(renderer, xp, yy, r, g, b, a, iweight); - result &= pixelRGBAWeight(renderer, xx, yy, r, g, b, a, iweight); - - /* Right half */ - xx = xc2 - xs; - result &= pixelRGBAWeight(renderer, xs, yp, r, g, b, a, weight); - result &= pixelRGBAWeight(renderer, xx, yp, r, g, b, a, weight); - - result &= pixelRGBAWeight(renderer, xs, yy, r, g, b, a, weight); - result &= pixelRGBAWeight(renderer, xx, yy, r, g, b, a, weight); - } - - return (result); -} - -/* ---- Filled Ellipse */ - -/*! -\brief Draw filled ellipse with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the filled ellipse. -\param y Y coordinate of the center of the filled ellipse. -\param rx Horizontal radius in pixels of the filled ellipse. -\param ry Vertical radius in pixels of the filled ellipse. -\param color The color value of the filled ellipse to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool filledEllipseColor(SDL_Renderer * renderer, float x, float y, float rx, float ry, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return _ellipseRGBA(renderer, x, y, rx, ry, c[0], c[1], c[2], c[3], true); -} - -/*! -\brief Draw filled ellipse with blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the filled ellipse. -\param y Y coordinate of the center of the filled ellipse. -\param rx Horizontal radius in pixels of the filled ellipse. -\param ry Vertical radius in pixels of the filled ellipse. -\param r The red value of the filled ellipse to draw. -\param g The green value of the filled ellipse to draw. -\param b The blue value of the filled ellipse to draw. -\param a The alpha value of the filled ellipse to draw. - -\returns Returns true on success, false on failure. -*/ -bool filledEllipseRGBA(SDL_Renderer * renderer, float x, float y, float rx, float ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - return _ellipseRGBA(renderer, x, y, rx, ry, r, g, b, a, true); -} - -/* ----- Pie */ - -/*! -\brief Internal float (low-speed) pie-calc implementation by drawing polygons. - -Note: Determines vertex array and uses polygon or filledPolygon drawing routines to render. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the pie. -\param y Y coordinate of the center of the pie. -\param rad Radius in pixels of the pie. -\param start Starting radius in degrees of the pie. -\param end Ending radius in degrees of the pie. -\param r The red value of the pie to draw. -\param g The green value of the pie to draw. -\param b The blue value of the pie to draw. -\param a The alpha value of the pie to draw. -\param filled Flag indicating if the pie should be filled (=1) or not (=0). - -\returns Returns true on success, false on failure. -*/ -/* TODO: rewrite algorithm; pie is not always accurate */ -bool _pieRGBA(SDL_Renderer * renderer, float x, float y, float rad, Sint32 start, Sint32 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a, bool filled) -{ - bool result; - double angle, start_angle, end_angle; - double deltaAngle; - double dr; - Sint32 numpoints, i; - float *vx, *vy; - - /* - * Sanity check radii - */ - if (rad < 0) { - return (false); - } - - /* - * Fixup angles - */ - start = start % 360; - end = end % 360; - - /* - * Special case for rad=0 - draw a point - */ - if (rad == 0) { - return (pixelRGBA(renderer, x, y, r, g, b, a)); - } - - /* - * Variable setup - */ - dr = (double) rad; - deltaAngle = 3.0 / dr; - start_angle = (double) start *(2.0 * M_PI / 360.0); - end_angle = (double) end *(2.0 * M_PI / 360.0); - if (start > end) { - end_angle += (2.0 * M_PI); - } - - /* We will always have at least 2 points */ - numpoints = 2; - - /* Count points (rather than calculating it) */ - angle = start_angle; - while (angle < end_angle) { - angle += deltaAngle; - numpoints++; - } - - /* Allocate combined vertex array */ - vx = vy = (float *) malloc(2 * sizeof(float) * numpoints); - if (vx == NULL) { - return (false); - } - - /* Update point to start of vy */ - vy += numpoints; - - /* Center */ - vx[0] = x; - vy[0] = y; - - /* First vertex */ - angle = start_angle; - vx[1] = x + (int) (dr * cos(angle)); - vy[1] = y + (int) (dr * sin(angle)); - - if (numpoints<3) - { - result = lineRGBA(renderer, vx[0], vy[0], vx[1], vy[1], r, g, b, a); - } - else - { - /* Calculate other vertices */ - i = 2; - angle = start_angle; - while (angle < end_angle) { - angle += deltaAngle; - if (angle>end_angle) - { - angle = end_angle; - } - vx[i] = x + (int) (dr * cos(angle)); - vy[i] = y + (int) (dr * sin(angle)); - i++; - } - - /* Draw */ - if (filled) { - result = filledPolygonRGBA(renderer, vx, vy, numpoints, r, g, b, a); - } else { - result = polygonRGBA(renderer, vx, vy, numpoints, r, g, b, a); - } - } - - /* Free combined vertex array */ - free(vx); - - return (result); -} - -/*! -\brief Draw pie (outline) with alpha blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the pie. -\param y Y coordinate of the center of the pie. -\param rad Radius in pixels of the pie. -\param start Starting radius in degrees of the pie. -\param end Ending radius in degrees of the pie. -\param color The color value of the pie to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool pieColor(SDL_Renderer * renderer, float x, float y, float rad, - Sint32 start, Sint32 end, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return _pieRGBA(renderer, x, y, rad, start, end, c[0], c[1], c[2], c[3], false); -} - -/*! -\brief Draw pie (outline) with alpha blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the pie. -\param y Y coordinate of the center of the pie. -\param rad Radius in pixels of the pie. -\param start Starting radius in degrees of the pie. -\param end Ending radius in degrees of the pie. -\param r The red value of the pie to draw. -\param g The green value of the pie to draw. -\param b The blue value of the pie to draw. -\param a The alpha value of the pie to draw. - -\returns Returns true on success, false on failure. -*/ -bool pieRGBA(SDL_Renderer * renderer, float x, float y, float rad, - Sint32 start, Sint32 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - return _pieRGBA(renderer, x, y, rad, start, end, r, g, b, a, false); -} - -/*! -\brief Draw filled pie with alpha blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the filled pie. -\param y Y coordinate of the center of the filled pie. -\param rad Radius in pixels of the filled pie. -\param start Starting radius in degrees of the filled pie. -\param end Ending radius in degrees of the filled pie. -\param color The color value of the filled pie to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool filledPieColor(SDL_Renderer * renderer, float x, float y, float rad, Sint32 start, Sint32 end, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return _pieRGBA(renderer, x, y, rad, start, end, c[0], c[1], c[2], c[3], true); -} - -/*! -\brief Draw filled pie with alpha blending. - -\param renderer The renderer to draw on. -\param x X coordinate of the center of the filled pie. -\param y Y coordinate of the center of the filled pie. -\param rad Radius in pixels of the filled pie. -\param start Starting radius in degrees of the filled pie. -\param end Ending radius in degrees of the filled pie. -\param r The red value of the filled pie to draw. -\param g The green value of the filled pie to draw. -\param b The blue value of the filled pie to draw. -\param a The alpha value of the filled pie to draw. - -\returns Returns true on success, false on failure. -*/ -bool filledPieRGBA(SDL_Renderer * renderer, float x, float y, float rad, - Sint32 start, Sint32 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - return _pieRGBA(renderer, x, y, rad, start, end, r, g, b, a, true); -} - -/* ------ Trigon */ - -/*! -\brief Draw trigon (triangle outline) with alpha blending. - -Note: Creates vertex array and uses polygon routine to render. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the trigon. -\param y1 Y coordinate of the first point of the trigon. -\param x2 X coordinate of the second point of the trigon. -\param y2 Y coordinate of the second point of the trigon. -\param x3 X coordinate of the third point of the trigon. -\param y3 Y coordinate of the third point of the trigon. -\param color The color value of the trigon to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool trigonColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float x3, float y3, Uint32 color) -{ - float vx[3]; - float vy[3]; - - vx[0]=x1; - vx[1]=x2; - vx[2]=x3; - vy[0]=y1; - vy[1]=y2; - vy[2]=y3; - - return(polygonColor(renderer,vx,vy,3,color)); -} - -/*! -\brief Draw trigon (triangle outline) with alpha blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the trigon. -\param y1 Y coordinate of the first point of the trigon. -\param x2 X coordinate of the second point of the trigon. -\param y2 Y coordinate of the second point of the trigon. -\param x3 X coordinate of the third point of the trigon. -\param y3 Y coordinate of the third point of the trigon. -\param r The red value of the trigon to draw. -\param g The green value of the trigon to draw. -\param b The blue value of the trigon to draw. -\param a The alpha value of the trigon to draw. - -\returns Returns true on success, false on failure. -*/ -bool trigonRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float x3, float y3, - Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - float vx[3]; - float vy[3]; - - vx[0]=x1; - vx[1]=x2; - vx[2]=x3; - vy[0]=y1; - vy[1]=y2; - vy[2]=y3; - - return(polygonRGBA(renderer,vx,vy,3,r,g,b,a)); -} - -/* ------ AA-Trigon */ - -/*! -\brief Draw anti-aliased trigon (triangle outline) with alpha blending. - -Note: Creates vertex array and uses aapolygon routine to render. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the aa-trigon. -\param y1 Y coordinate of the first point of the aa-trigon. -\param x2 X coordinate of the second point of the aa-trigon. -\param y2 Y coordinate of the second point of the aa-trigon. -\param x3 X coordinate of the third point of the aa-trigon. -\param y3 Y coordinate of the third point of the aa-trigon. -\param color The color value of the aa-trigon to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool aatrigonColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float x3, float y3, Uint32 color) -{ - float vx[3]; - float vy[3]; - - vx[0]=x1; - vx[1]=x2; - vx[2]=x3; - vy[0]=y1; - vy[1]=y2; - vy[2]=y3; - - return(aapolygonColor(renderer,vx,vy,3,color)); -} - -/*! -\brief Draw anti-aliased trigon (triangle outline) with alpha blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the aa-trigon. -\param y1 Y coordinate of the first point of the aa-trigon. -\param x2 X coordinate of the second point of the aa-trigon. -\param y2 Y coordinate of the second point of the aa-trigon. -\param x3 X coordinate of the third point of the aa-trigon. -\param y3 Y coordinate of the third point of the aa-trigon. -\param r The red value of the aa-trigon to draw. -\param g The green value of the aa-trigon to draw. -\param b The blue value of the aa-trigon to draw. -\param a The alpha value of the aa-trigon to draw. - -\returns Returns true on success, false on failure. -*/ -bool aatrigonRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float x3, float y3, - Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - float vx[3]; - float vy[3]; - - vx[0]=x1; - vx[1]=x2; - vx[2]=x3; - vy[0]=y1; - vy[1]=y2; - vy[2]=y3; - - return(aapolygonRGBA(renderer,vx,vy,3,r,g,b,a)); -} - -/* ------ Filled Trigon */ - -/*! -\brief Draw filled trigon (triangle) with alpha blending. - -Note: Creates vertex array and uses aapolygon routine to render. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the filled trigon. -\param y1 Y coordinate of the first point of the filled trigon. -\param x2 X coordinate of the second point of the filled trigon. -\param y2 Y coordinate of the second point of the filled trigon. -\param x3 X coordinate of the third point of the filled trigon. -\param y3 Y coordinate of the third point of the filled trigon. -\param color The color value of the filled trigon to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool filledTrigonColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float x3, float y3, Uint32 color) -{ - float vx[3]; - float vy[3]; - - vx[0]=x1; - vx[1]=x2; - vx[2]=x3; - vy[0]=y1; - vy[1]=y2; - vy[2]=y3; - - return(filledPolygonColor(renderer,vx,vy,3,color)); -} - -/*! -\brief Draw filled trigon (triangle) with alpha blending. - -Note: Creates vertex array and uses aapolygon routine to render. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the filled trigon. -\param y1 Y coordinate of the first point of the filled trigon. -\param x2 X coordinate of the second point of the filled trigon. -\param y2 Y coordinate of the second point of the filled trigon. -\param x3 X coordinate of the third point of the filled trigon. -\param y3 Y coordinate of the third point of the filled trigon. -\param r The red value of the filled trigon to draw. -\param g The green value of the filled trigon to draw. -\param b The blue value of the filled trigon to draw. -\param a The alpha value of the filled trigon to draw. - -\returns Returns true on success, false on failure. -*/ -bool filledTrigonRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float x3, float y3, - Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - float vx[3]; - float vy[3]; - - vx[0]=x1; - vx[1]=x2; - vx[2]=x3; - vy[0]=y1; - vy[1]=y2; - vy[2]=y3; - - return(filledPolygonRGBA(renderer,vx,vy,3,r,g,b,a)); -} - -/* ---- Polygon */ - -/*! -\brief Draw polygon with alpha blending. - -\param renderer The renderer to draw on. -\param vx Vertex array containing X coordinates of the points of the polygon. -\param vy Vertex array containing Y coordinates of the points of the polygon. -\param n Number of points in the vertex array. Minimum number is 3. -\param color The color value of the polygon to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool polygonColor(SDL_Renderer * renderer, const float * vx, const float * vy, Sint32 n, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return polygonRGBA(renderer, vx, vy, n, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw polygon with the currently set color and blend mode. - -\param renderer The renderer to draw on. -\param vx Vertex array containing X coordinates of the points of the polygon. -\param vy Vertex array containing Y coordinates of the points of the polygon. -\param n Number of points in the vertex array. Minimum number is 3. - -\returns Returns true on success, false on failure. -*/ -bool polygon(SDL_Renderer * renderer, const float * vx, const float * vy, Sint32 n) -{ - /* - * Draw - */ - bool result = true; - Sint32 i, nn; - SDL_FPoint* points; - - /* - * Vertex array NULL check - */ - if (vx == NULL) { - return (false); - } - if (vy == NULL) { - return (false); - } - - /* - * Sanity check - */ - if (n < 3) { - return (false); - } - - /* - * Create array of points - */ - nn = n + 1; - points = (SDL_FPoint*)malloc(sizeof(SDL_FPoint) * nn); - if (points == NULL) - { - return false; - } - for (i=0; ib. -*/ -Sint32 _gfxPrimitivesCompareInt(const void *a, const void *b) -{ - return (*(const Sint32 *) a) - (*(const Sint32 *) b); -} - -/*! -\brief Global vertex array to use if optional parameters are not given in filledPolygonMT calls. - -Note: Used for non-multithreaded (default) operation of filledPolygonMT. -*/ -static Sint32 *gfxPrimitivesPolyIntsGlobal = NULL; - -/*! -\brief Flag indicating if global vertex array was already allocated. - -Note: Used for non-multithreaded (default) operation of filledPolygonMT. -*/ -static bool gfxPrimitivesPolyAllocatedGlobal = false; - -/*! -\brief Draw filled polygon with alpha blending (multi-threaded capable). - -Note: The last two parameters are optional; but are required for multithreaded operation. - -\param renderer The renderer to draw on. -\param vx Vertex array containing X coordinates of the points of the filled polygon. -\param vy Vertex array containing Y coordinates of the points of the filled polygon. -\param n Number of points in the vertex array. Minimum number is 3. -\param r The red value of the filled polygon to draw. -\param g The green value of the filled polygon to draw. -\param b The blue value of the filled polygon to draw. -\param a The alpha value of the filled polygon to draw. -\param polyInts Preallocated, temporary vertex array used for sorting vertices. Required for multithreaded operation; set to NULL otherwise. -\param polyAllocated Flag indicating if temporary vertex array was allocated. Required for multithreaded operation; set to NULL otherwise. - -\returns Returns true on success, false on failure. -*/ -bool filledPolygonRGBAMT(SDL_Renderer * renderer, const float * vx, const float * vy, Sint32 n, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Sint32 **polyInts, bool *polyAllocated) -{ - bool result; - Sint32 i; - Sint32 y, xa, xb; - Sint32 miny, maxy; - Sint32 x1, y1; - Sint32 x2, y2; - Sint32 ind1, ind2; - Sint32 ints; - Sint32 *gfxPrimitivesPolyInts = NULL; - Sint32 *gfxPrimitivesPolyIntsNew = NULL; - bool gfxPrimitivesPolyAllocated = false; - - /* - * Vertex array NULL check - */ - if (vx == NULL) { - return (false); - } - if (vy == NULL) { - return (false); - } - - /* - * Sanity check number of edges - */ - if (n < 3) { - return false; - } - - /* - * Map polygon cache - */ - if ((polyInts==NULL) || (polyAllocated==NULL)) { - /* Use global cache */ - gfxPrimitivesPolyInts = gfxPrimitivesPolyIntsGlobal; - gfxPrimitivesPolyAllocated = gfxPrimitivesPolyAllocatedGlobal; - } else { - /* Use local cache */ - gfxPrimitivesPolyInts = *polyInts; - gfxPrimitivesPolyAllocated = *polyAllocated; - } - - /* - * Allocate temp array, only grow array - */ - if (!gfxPrimitivesPolyAllocated) { - gfxPrimitivesPolyInts = (Sint32 *) malloc(sizeof(int) * n); - gfxPrimitivesPolyAllocated = n; - } else { - if (gfxPrimitivesPolyAllocated < n) { - gfxPrimitivesPolyIntsNew = (Sint32 *) realloc(gfxPrimitivesPolyInts, sizeof(int) * n); - if (!gfxPrimitivesPolyIntsNew) { - if (!gfxPrimitivesPolyInts) { - free(gfxPrimitivesPolyInts); - gfxPrimitivesPolyInts = NULL; - } - gfxPrimitivesPolyAllocated = 0; - } else { - gfxPrimitivesPolyInts = gfxPrimitivesPolyIntsNew; - gfxPrimitivesPolyAllocated = n; - } - } - } - - /* - * Check temp array - */ - if (gfxPrimitivesPolyInts==NULL) { - gfxPrimitivesPolyAllocated = 0; - } - - /* - * Update cache variables - */ - if ((polyInts==NULL) || (polyAllocated==NULL)) { - gfxPrimitivesPolyIntsGlobal = gfxPrimitivesPolyInts; - gfxPrimitivesPolyAllocatedGlobal = gfxPrimitivesPolyAllocated; - } else { - *polyInts = gfxPrimitivesPolyInts; - *polyAllocated = gfxPrimitivesPolyAllocated; - } - - /* - * Check temp array again - */ - if (gfxPrimitivesPolyInts==NULL) { - return false; - } - - /* - * Determine Y maxima - */ - miny = vy[0]; - maxy = vy[0]; - for (i = 1; (i < n); i++) { - if (vy[i] < miny) { - miny = vy[i]; - } else if (vy[i] > maxy) { - maxy = vy[i]; - } - } - - /* - * Draw, scanning y - */ - for (y = miny; (y <= maxy); y++) { - ints = 0; - for (i = 0; (i < n); i++) { - if (!i) { - ind1 = n - 1; - ind2 = 0; - } else { - ind1 = i - 1; - ind2 = i; - } - y1 = vy[ind1]; - y2 = vy[ind2]; - if (y1 < y2) { - x1 = vx[ind1]; - x2 = vx[ind2]; - } else if (y1 > y2) { - y2 = vy[ind1]; - y1 = vy[ind2]; - x2 = vx[ind1]; - x1 = vx[ind2]; - } else { - continue; - } - if ( ((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2)) ) { - gfxPrimitivesPolyInts[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1); - } - } - - qsort(gfxPrimitivesPolyInts, ints, sizeof(int), _gfxPrimitivesCompareInt); - - /* - * Set color - */ - result = true; - result &= SDL_SetRenderDrawBlendMode(renderer, (a == 255) ? SDL_BLENDMODE_NONE : SDL_BLENDMODE_BLEND); - result &= SDL_SetRenderDrawColor(renderer, r, g, b, a); - - for (i = 0; (i < ints); i += 2) { - xa = gfxPrimitivesPolyInts[i] + 1; - xa = (xa >> 16) + ((xa & 32768) >> 15); - xb = gfxPrimitivesPolyInts[i+1] - 1; - xb = (xb >> 16) + ((xb & 32768) >> 15); - result &= hline(renderer, xa, xb, y); - } - } - - return result; -} - -/*! -\brief Draw filled polygon with alpha blending. - -\param renderer The renderer to draw on. -\param vx Vertex array containing X coordinates of the points of the filled polygon. -\param vy Vertex array containing Y coordinates of the points of the filled polygon. -\param n Number of points in the vertex array. Minimum number is 3. -\param color The color value of the filled polygon to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool filledPolygonColor(SDL_Renderer * renderer, const float * vx, const float * vy, Sint32 n, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return filledPolygonRGBAMT(renderer, vx, vy, n, c[0], c[1], c[2], c[3], NULL, NULL); -} - -/*! -\brief Draw filled polygon with alpha blending. - -\param renderer The renderer to draw on. -\param vx Vertex array containing X coordinates of the points of the filled polygon. -\param vy Vertex array containing Y coordinates of the points of the filled polygon. -\param n Number of points in the vertex array. Minimum number is 3. -\param r The red value of the filled polygon to draw. -\param g The green value of the filled polygon to draw. -\param b The blue value of the filed polygon to draw. -\param a The alpha value of the filled polygon to draw. - -\returns Returns true on success, false on failure. -*/ -bool filledPolygonRGBA(SDL_Renderer * renderer, const float * vx, const float * vy, Sint32 n, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - return filledPolygonRGBAMT(renderer, vx, vy, n, r, g, b, a, NULL, NULL); -} - -/* ---- Textured Polygon */ - -/*! -\brief Internal function to draw a textured horizontal line. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point (i.e. left) of the line. -\param x2 X coordinate of the second point (i.e. right) of the line. -\param y Y coordinate of the points of the line. -\param texture The texture to retrieve color information from. -\param texture_w The width of the texture. -\param texture_h The height of the texture. -\param texture_dx The X offset for the texture lookup. -\param texture_dy The Y offset for the textured lookup. - -\returns Returns true on success, false on failure. -*/ -bool _HLineTextured(SDL_Renderer *renderer, float x1, float x2, float y, SDL_Texture *texture, Sint32 texture_w, Sint32 texture_h, Sint32 texture_dx, Sint32 texture_dy) -{ - float w; - float xtmp; - bool result = true; - Sint32 texture_x_walker; - Sint32 texture_y_start; - SDL_FRect source_rect,dst_rect; - Sint32 pixels_written,write_width; - - /* - * Swap x1, x2 if required to ensure x1<=x2 - */ - if (x1 > x2) { - xtmp = x1; - x1 = x2; - x2 = xtmp; - } - - /* - * Calculate width to draw - */ - w = x2 - x1 + 1; - - /* - * Determine where in the texture we start drawing - */ - texture_x_walker = ((int)x1 - texture_dx) % texture_w; - if (texture_x_walker < 0){ - texture_x_walker = texture_w + texture_x_walker ; - } - - texture_y_start = ((int)y + texture_dy) % texture_h; - if (texture_y_start < 0){ - texture_y_start = texture_h + texture_y_start; - } - - /* setup the source rectangle; we are only drawing one horizontal line */ - source_rect.y = texture_y_start; - source_rect.x = texture_x_walker; - source_rect.h = 1; - - /* we will draw to the current y */ - dst_rect.y = y; - dst_rect.h = 1; - - /* if there are enough pixels left in the current row of the texture */ - /* draw it all at once */ - if (w <= texture_w -texture_x_walker){ - source_rect.w = w; - source_rect.x = texture_x_walker; - dst_rect.x= x1; - dst_rect.w = source_rect.w; - result = SDL_RenderTexture(renderer, texture, &source_rect, &dst_rect); - } else { - /* we need to draw multiple times */ - /* draw the first segment */ - pixels_written = texture_w - texture_x_walker; - source_rect.w = pixels_written; - source_rect.x = texture_x_walker; - dst_rect.x= x1; - dst_rect.w = source_rect.w; - result &= SDL_RenderTexture(renderer, texture, &source_rect, &dst_rect); - write_width = texture_w; - - /* now draw the rest */ - /* set the source x to 0 */ - source_rect.x = 0; - while (pixels_written < w){ - if (write_width >= w - pixels_written) { - write_width = w - pixels_written; - } - source_rect.w = write_width; - dst_rect.x = x1 + pixels_written; - dst_rect.w = source_rect.w; - result &= SDL_RenderTexture(renderer, texture, &source_rect, &dst_rect); - pixels_written += write_width; - } - } - - return result; -} - -/*! -\brief Draws a polygon filled with the given texture (Multi-Threading Capable). - -\param renderer The renderer to draw on. -\param vx array of x vector components -\param vy array of x vector components -\param n the amount of vectors in the vx and vy array -\param texture the sdl surface to use to fill the polygon -\param texture_dx the offset of the texture relative to the screeen. If you move the polygon 10 pixels -to the left and want the texture to apear the same you need to increase the texture_dx value -\param texture_dy see texture_dx -\param polyInts Preallocated temp array storage for vertex sorting (used for multi-threaded operation) -\param polyAllocated Flag indicating oif the temp array was allocated (used for multi-threaded operation) - -\returns Returns true on success, false on failure. -*/ -bool texturedPolygonMT(SDL_Renderer *renderer, const float * vx, const float * vy, Sint32 n, - SDL_Surface * texture, Sint32 texture_dx, Sint32 texture_dy, Sint32 **polyInts, bool *polyAllocated) -{ - bool result; - Sint32 i; - Sint32 y, xa, xb; - Sint32 minx,maxx,miny, maxy; - Sint32 x1, y1; - Sint32 x2, y2; - Sint32 ind1, ind2; - Sint32 ints; - Sint32 *gfxPrimitivesPolyInts = NULL; - Sint32 *gfxPrimitivesPolyIntsTemp = NULL; - Sint32 gfxPrimitivesPolyAllocated = 0; - SDL_Texture *textureAsTexture = NULL; - - /* - * Sanity check number of edges - */ - if (n < 3) { - return false; - } - - /* - * Map polygon cache - */ - if ((polyInts==NULL) || (polyAllocated==NULL)) { - /* Use global cache */ - gfxPrimitivesPolyInts = gfxPrimitivesPolyIntsGlobal; - gfxPrimitivesPolyAllocated = gfxPrimitivesPolyAllocatedGlobal; - } else { - /* Use local cache */ - gfxPrimitivesPolyInts = *polyInts; - gfxPrimitivesPolyAllocated = *polyAllocated; - } - - /* - * Allocate temp array, only grow array - */ - if (!gfxPrimitivesPolyAllocated) { - gfxPrimitivesPolyInts = (Sint32 *) malloc(sizeof(int) * n); - gfxPrimitivesPolyAllocated = n; - } else { - if (gfxPrimitivesPolyAllocated < n) { - gfxPrimitivesPolyIntsTemp = (Sint32 *) realloc(gfxPrimitivesPolyInts, sizeof(int) * n); - if (gfxPrimitivesPolyIntsTemp == NULL) { - /* Realloc failed - keeps original memory block, but fails this operation */ - return(false); - } - gfxPrimitivesPolyInts = gfxPrimitivesPolyIntsTemp; - gfxPrimitivesPolyAllocated = n; - } - } - - /* - * Check temp array - */ - if (gfxPrimitivesPolyInts==NULL) { - gfxPrimitivesPolyAllocated = 0; - } - - /* - * Update cache variables - */ - if ((polyInts==NULL) || (polyAllocated==NULL)) { - gfxPrimitivesPolyIntsGlobal = gfxPrimitivesPolyInts; - gfxPrimitivesPolyAllocatedGlobal = gfxPrimitivesPolyAllocated; - } else { - *polyInts = gfxPrimitivesPolyInts; - *polyAllocated = gfxPrimitivesPolyAllocated; - } - - /* - * Check temp array again - */ - if (gfxPrimitivesPolyInts==NULL) { - return false; - } - - /* - * Determine X,Y minima,maxima - */ - miny = vy[0]; - maxy = vy[0]; - minx = vx[0]; - maxx = vx[0]; - for (i = 1; (i < n); i++) { - if (vy[i] < miny) { - miny = vy[i]; - } else if (vy[i] > maxy) { - maxy = vy[i]; - } - if (vx[i] < minx) { - minx = vx[i]; - } else if (vx[i] > maxx) { - maxx = vx[i]; - } - } - - /* Create texture for drawing */ - textureAsTexture = SDL_CreateTextureFromSurface(renderer, texture); - if (textureAsTexture == NULL) - { - return false; - } - SDL_SetTextureBlendMode(textureAsTexture, SDL_BLENDMODE_BLEND); - - /* - * Draw, scanning y - */ - result = true; - for (y = miny; (y <= maxy); y++) { - ints = 0; - for (i = 0; (i < n); i++) { - if (!i) { - ind1 = n - 1; - ind2 = 0; - } else { - ind1 = i - 1; - ind2 = i; - } - y1 = vy[ind1]; - y2 = vy[ind2]; - if (y1 < y2) { - x1 = vx[ind1]; - x2 = vx[ind2]; - } else if (y1 > y2) { - y2 = vy[ind1]; - y1 = vy[ind2]; - x2 = vx[ind1]; - x1 = vx[ind2]; - } else { - continue; - } - if ( ((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2)) ) { - gfxPrimitivesPolyInts[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1); - } - } - - qsort(gfxPrimitivesPolyInts, ints, sizeof(int), _gfxPrimitivesCompareInt); - - for (i = 0; (i < ints); i += 2) { - xa = gfxPrimitivesPolyInts[i] + 1; - xa = (xa >> 16) + ((xa & 32768) >> 15); - xb = gfxPrimitivesPolyInts[i+1] - 1; - xb = (xb >> 16) + ((xb & 32768) >> 15); - result &= _HLineTextured(renderer, xa, xb, y, textureAsTexture, texture->w, texture->h, texture_dx, texture_dy); - } - } - - SDL_DestroyTexture(textureAsTexture); - - return result; -} - -/*! -\brief Draws a polygon filled with the given texture. - -This standard version is calling multithreaded versions with NULL cache parameters. - -\param renderer The renderer to draw on. -\param vx array of x vector components -\param vy array of x vector components -\param n the amount of vectors in the vx and vy array -\param texture the sdl surface to use to fill the polygon -\param texture_dx the offset of the texture relative to the screeen. if you move the polygon 10 pixels -to the left and want the texture to apear the same you need to increase the texture_dx value -\param texture_dy see texture_dx - -\returns Returns true on success, false on failure. -*/ -bool texturedPolygon(SDL_Renderer *renderer, const float * vx, const float * vy, Sint32 n, SDL_Surface *texture, Sint32 texture_dx, Sint32 texture_dy) -{ - /* - * Draw - */ - return (texturedPolygonMT(renderer, vx, vy, n, texture, texture_dx, texture_dy, NULL, NULL)); -} - -/* ---- Character */ - -/*! -\brief Global cache for NxM pixel font textures created at runtime. -*/ -static SDL_Texture *gfxPrimitivesFont[256]; - -/*! -\brief Pointer to the current font data. Default is a 8x8 pixel internal font. -*/ -static const unsigned char *currentFontdata = gfxPrimitivesFontdata; - -/*! -\brief Width of the current font. Default is 8. -*/ -static Uint32 charWidth = 8; - -/*! -\brief Height of the current font. Default is 8. -*/ -static Uint32 charHeight = 8; - -/*! -\brief Width for rendering. Autocalculated. -*/ -static Uint32 charWidthLocal = 8; - -/*! -\brief Height for rendering. Autocalculated. -*/ -static Uint32 charHeightLocal = 8; - -/*! -\brief Pitch of the current font in bytes. Default is 1. -*/ -static Uint32 charPitch = 1; - -/*! -\brief Characters 90deg clockwise rotations. Default is 0. Max is 3. -*/ -static Uint32 charRotation = 0; - -/*! -\brief Character data size in bytes of the current font. Default is 8. -*/ -static Uint32 charSize = 8; - -/*! -\brief Sets or resets the current global font data. - -The font data array is organized in follows: -[fontdata] = [character 0][character 1]...[character 255] where -[character n] = [byte 1 row 1][byte 2 row 1]...[byte {pitch} row 1][byte 1 row 2] ...[byte {pitch} row height] where -[byte n] = [bit 0]...[bit 7] where -[bit n] = [0 for transparent pixel|1 for colored pixel] - -\param fontdata Pointer to array of font data. Set to NULL, to reset global font to the default 8x8 font. -\param cw Width of character in bytes. Ignored if fontdata==NULL. -\param ch Height of character in bytes. Ignored if fontdata==NULL. -*/ -void gfxPrimitivesSetFont(const void *fontdata, Uint32 cw, Uint32 ch) -{ - Sint32 i; - - if ((fontdata) && (cw) && (ch)) { - currentFontdata = (unsigned char *)fontdata; - charWidth = cw; - charHeight = ch; - } else { - currentFontdata = gfxPrimitivesFontdata; - charWidth = 8; - charHeight = 8; - } - - charPitch = (charWidth+7)/8; - charSize = charPitch * charHeight; - - /* Maybe flip width/height for rendering */ - if ((charRotation==1) || (charRotation==3)) - { - charWidthLocal = charHeight; - charHeightLocal = charWidth; - } - else - { - charWidthLocal = charWidth; - charHeightLocal = charHeight; - } - - /* Clear character cache */ - for (i = 0; i < 256; i++) { - if (gfxPrimitivesFont[i]) { - SDL_DestroyTexture(gfxPrimitivesFont[i]); - gfxPrimitivesFont[i] = NULL; - } - } -} - -/*! -\brief Sets current global font character rotation steps. - -Default is 0 (no rotation). 1 = 90deg clockwise. 2 = 180deg clockwise. 3 = 270deg clockwise. -Changing the rotation, will reset the character cache. - -\param rotation Number of 90deg clockwise steps to rotate -*/ -void gfxPrimitivesSetFontRotation(Uint32 rotation) -{ - Sint32 i; - - rotation = rotation & 3; - if (charRotation != rotation) - { - /* Store rotation */ - charRotation = rotation; - - /* Maybe flip width/height for rendering */ - if ((charRotation==1) || (charRotation==3)) - { - charWidthLocal = charHeight; - charHeightLocal = charWidth; - } - else - { - charWidthLocal = charWidth; - charHeightLocal = charHeight; - } - - /* Clear character cache */ - for (i = 0; i < 256; i++) { - if (gfxPrimitivesFont[i]) { - SDL_DestroyTexture(gfxPrimitivesFont[i]); - gfxPrimitivesFont[i] = NULL; - } - } - } -} - -/*! -\brief Draw a character of the currently set font. - -\param renderer The Renderer to draw on. -\param x X (horizontal) coordinate of the upper left corner of the character. -\param y Y (vertical) coordinate of the upper left corner of the character. -\param c The character to draw. -\param r The red value of the character to draw. -\param g The green value of the character to draw. -\param b The blue value of the character to draw. -\param a The alpha value of the character to draw. - -\returns Returns true on success, false on failure. -*/ -bool characterRGBA(SDL_Renderer *renderer, float x, float y, char c, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - SDL_FRect srect; - SDL_FRect drect; - bool result; - Uint32 ix, iy; - const unsigned char *charpos; - Uint8 *curpos; - Uint8 patt, mask; - Uint8 *linepos; - Uint32 pitch; - SDL_Surface *character; - SDL_Surface *rotatedCharacter; - Uint32 ci; - - /* - * Setup source rectangle - */ - srect.x = 0; - srect.y = 0; - srect.w = charWidthLocal; - srect.h = charHeightLocal; - - /* - * Setup destination rectangle - */ - drect.x = x; - drect.y = y; - drect.w = charWidthLocal; - drect.h = charHeightLocal; - - /* Character index in cache */ - ci = (unsigned char) c; - - /* - * Create new charWidth x charHeight bitmap surface if not already present. - * Might get rotated later. - */ - if (gfxPrimitivesFont[ci] == NULL) { - /* - * Redraw character into surface - */ - character = SDL_CreateSurface( - charWidth, charHeight, SDL_PIXELFORMAT_RGBA8888); - if (character == NULL) { - return (false); - } - - charpos = currentFontdata + ci * charSize; - linepos = (Uint8 *)character->pixels; - pitch = character->pitch; - - /* - * Drawing loop - */ - patt = 0; - for (iy = 0; iy < charHeight; iy++) { - mask = 0x00; - curpos = linepos; - for (ix = 0; ix < charWidth; ix++) { - if (!(mask >>= 1)) { - patt = *charpos++; - mask = 0x80; - } - if (patt & mask) { - *(Uint32 *)curpos = 0xffffffff; - } else { - *(Uint32 *)curpos = 0; - } - curpos += 4; - } - linepos += pitch; - } - - /* Maybe rotate and replace cached image */ - if (charRotation>0) - { - rotatedCharacter = rotateSurface90Degrees(character, charRotation); - SDL_DestroySurface(character); - character = rotatedCharacter; - } - - /* Convert temp surface into texture */ - gfxPrimitivesFont[ci] = SDL_CreateTextureFromSurface(renderer, character); - SDL_DestroySurface(character); - - /* - * Check pointer - */ - if (gfxPrimitivesFont[ci] == NULL) { - return (false); - } - } - - /* - * Set color - */ - result = true; - result &= SDL_SetTextureColorMod(gfxPrimitivesFont[ci], r, g, b); - result &= SDL_SetTextureAlphaMod(gfxPrimitivesFont[ci], a); - - /* - * Draw texture onto destination - */ - result &= SDL_RenderTexture(renderer, gfxPrimitivesFont[ci], &srect, &drect); - - return (result); -} - - -/*! -\brief Draw a character of the currently set font. - -\param renderer The renderer to draw on. -\param x X (horizontal) coordinate of the upper left corner of the character. -\param y Y (vertical) coordinate of the upper left corner of the character. -\param c The character to draw. -\param color The color value of the character to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool characterColor(SDL_Renderer * renderer, float x, float y, char c, Uint32 color) -{ - Uint8 *co = (Uint8 *)&color; - return characterRGBA(renderer, x, y, c, co[0], co[1], co[2], co[3]); -} - - -/*! -\brief Draw a string in the currently set font. - -The spacing between consequtive characters in the string is the fixed number of pixels -of the character width of the current global font. - -\param renderer The renderer to draw on. -\param x X (horizontal) coordinate of the upper left corner of the string. -\param y Y (vertical) coordinate of the upper left corner of the string. -\param s The string to draw. -\param color The color value of the string to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool stringColor(SDL_Renderer * renderer, float x, float y, const char *s, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return stringRGBA(renderer, x, y, s, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw a string in the currently set font. - -\param renderer The renderer to draw on. -\param x X (horizontal) coordinate of the upper left corner of the string. -\param y Y (vertical) coordinate of the upper left corner of the string. -\param s The string to draw. -\param r The red value of the string to draw. -\param g The green value of the string to draw. -\param b The blue value of the string to draw. -\param a The alpha value of the string to draw. - -\returns Returns true on success, false on failure. -*/ -bool stringRGBA(SDL_Renderer * renderer, float x, float y, const char *s, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - bool result = true; - float curx = x; - float cury = y; - const char *curchar = s; - - while (*curchar && result) { - result &= characterRGBA(renderer, curx, cury, *curchar, r, g, b, a); - switch (charRotation) - { - case 0: - curx += charWidthLocal; - break; - case 2: - curx -= charWidthLocal; - break; - case 1: - cury += charHeightLocal; - break; - case 3: - cury -= charHeightLocal; - break; - } - curchar++; - } - - return (result); -} - -/* ---- Bezier curve */ - -/*! -\brief Internal function to calculate bezier interpolator of data array with ndata values at position 't'. - -\param data Array of values. -\param ndata Size of array. -\param t Position for which to calculate interpolated value. t should be between [0, ndata]. - -\returns Interpolated value at position t, value[0] when t<0, value[n-1] when t>n. -*/ -double _evaluateBezier (double *data, Sint32 ndata, double t) -{ - double mu, result; - Sint32 n,k,kn,nn,nkn; - double blend,muk,munk; - - /* Sanity check bounds */ - if (t<0.0) { - return(data[0]); - } - if (t>=(double)ndata) { - return(data[ndata-1]); - } - - /* Adjust t to the range 0.0 to 1.0 */ - mu=t/(double)ndata; - - /* Calculate interpolate */ - n=ndata-1; - result=0.0; - muk = 1; - munk = pow(1-mu,(double)n); - for (k=0;k<=n;k++) { - nn = n; - kn = k; - nkn = n - k; - blend = muk * munk; - muk *= mu; - munk /= (1-mu); - while (nn >= 1) { - blend *= nn; - nn--; - if (kn > 1) { - blend /= (double)kn; - kn--; - } - if (nkn > 1) { - blend /= (double)nkn; - nkn--; - } - } - result += data[k] * blend; - } - - return (result); -} - -/*! -\brief Draw a bezier curve with alpha blending. - -\param renderer The renderer to draw on. -\param vx Vertex array containing X coordinates of the points of the bezier curve. -\param vy Vertex array containing Y coordinates of the points of the bezier curve. -\param n Number of points in the vertex array. Minimum number is 3. -\param s Number of steps for the interpolation. Minimum number is 2. -\param color The color value of the bezier curve to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool bezierColor(SDL_Renderer * renderer, const float * vx, const float * vy, Sint32 n, Sint32 s, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return bezierRGBA(renderer, vx, vy, n, s, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw a bezier curve with alpha blending. - -\param renderer The renderer to draw on. -\param vx Vertex array containing X coordinates of the points of the bezier curve. -\param vy Vertex array containing Y coordinates of the points of the bezier curve. -\param n Number of points in the vertex array. Minimum number is 3. -\param s Number of steps for the interpolation. Minimum number is 2. -\param r The red value of the bezier curve to draw. -\param g The green value of the bezier curve to draw. -\param b The blue value of the bezier curve to draw. -\param a The alpha value of the bezier curve to draw. - -\returns Returns true on success, false on failure. -*/ -bool bezierRGBA(SDL_Renderer * renderer, const float * vx, const float * vy, Sint32 n, Sint32 s, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - bool result; - Sint32 i; - double *x, *y, t, stepsize; - float x1, y1, x2, y2; - - /* - * Sanity check - */ - if (n < 3) { - return (false); - } - if (s < 2) { - return (false); - } - - /* - * Variable setup - */ - stepsize=(double)1.0/(double)s; - - /* Transfer vertices into float arrays */ - if ((x=(double *)malloc(sizeof(double)*(n+1)))==NULL) { - return(false); - } - if ((y=(double *)malloc(sizeof(double)*(n+1)))==NULL) { - free(x); - return(false); - } - for (i=0; i0. -\param color The color value of the line to draw (0xRRGGBBAA). - -\returns Returns true on success, false on failure. -*/ -bool thickLineColor(SDL_Renderer *renderer, float x1, float y1, float x2, float y2, float width, Uint32 color) -{ - Uint8 *c = (Uint8 *)&color; - return thickLineRGBA(renderer, x1, y1, x2, y2, width, c[0], c[1], c[2], c[3]); -} - -/*! -\brief Draw a thick line with alpha blending. - -\param renderer The renderer to draw on. -\param x1 X coordinate of the first point of the line. -\param y1 Y coordinate of the first point of the line. -\param x2 X coordinate of the second point of the line. -\param y2 Y coordinate of the second point of the line. -\param width Width of the line in pixels. Must be >0. -\param r The red value of the character to draw. -\param g The green value of the character to draw. -\param b The blue value of the character to draw. -\param a The alpha value of the character to draw. - -\returns Returns true on success, false on failure. -*/ -bool thickLineRGBA(SDL_Renderer *renderer, float x1, float y1, float x2, float y2, float width, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - Sint32 wh; - double dx, dy, dx1, dy1, dx2, dy2; - double l, wl2, nx, ny, ang, adj; - float px[4], py[4]; - - if (renderer == NULL) { - return false; - } - - if (width < 1) { - return false; - } - - /* Special case: thick "point" */ - if ((x1 == x2) && (y1 == y2)) { - wh = width / 2; - return boxRGBA(renderer, x1 - wh, y1 - wh, x2 + width, y2 + width, r, g, b, a); - } - - /* Special case: width == 1 */ - if (width == 1) { - return lineRGBA(renderer, x1, y1, x2, y2, r, g, b, a); - } - - /* Calculate offsets for sides */ - dx = (double)(x2 - x1); - dy = (double)(y2 - y1); - l = SDL_sqrt(dx*dx + dy*dy); - ang = SDL_atan2(dx, dy); - adj = 0.1 + 0.9 * SDL_fabs(SDL_cos(2.0 * ang)); - wl2 = ((double)width - adj)/(2.0 * l); - nx = dx * wl2; - ny = dy * wl2; - - /* Build polygon */ - dx1 = (double)x1; - dy1 = (double)y1; - dx2 = (double)x2; - dy2 = (double)y2; - px[0] = (float)(dx1 + ny); - px[1] = (float)(dx1 - ny); - px[2] = (float)(dx2 - ny); - px[3] = (float)(dx2 + ny); - py[0] = (float)(dy1 - nx); - py[1] = (float)(dy1 + nx); - py[2] = (float)(dy2 + nx); - py[3] = (float)(dy2 - nx); - - /* Draw polygon */ - return filledPolygonRGBA(renderer, px, py, 4, r, g, b, a); -} diff --git a/src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives.h b/src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives.h deleted file mode 100644 index a8e9e47..0000000 --- a/src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - -SDL3_gfxPrimitives.h: graphics primitives for SDL - -Copyright (C) 2012-2014 Andreas Schiffler - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. - -Andreas Schiffler -- aschiffler at ferzkopp dot net - -*/ - -#ifndef _SDL3_gfxPrimitives_h -#define _SDL3_gfxPrimitives_h - -#include -#ifndef M_PI -#define M_PI 3.1415926535897932384626433832795 -#endif - -#include - -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - - /* ----- Versioning */ - -#define SDL3_GFXPRIMITIVES_MAJOR 1 -#define SDL3_GFXPRIMITIVES_MINOR 0 -#define SDL3_GFXPRIMITIVES_MICRO 0 - - - /* ---- Function Prototypes */ - -#ifdef _MSC_VER -# if defined(DLL_EXPORT) && !defined(LIBSDL3_GFX_DLL_IMPORT) -# define SDL3_GFXPRIMITIVES_SCOPE __declspec(dllexport) -# else -# ifdef LIBSDL3_GFX_DLL_IMPORT -# define SDL3_GFXPRIMITIVES_SCOPE __declspec(dllimport) -# endif -# endif -#endif -#ifndef SDL3_GFXPRIMITIVES_SCOPE -# define SDL3_GFXPRIMITIVES_SCOPE extern -#endif - - /* Note: all ___Color routines expect the color to be in format 0xRRGGBBAA */ - - /* Pixel */ - - SDL3_GFXPRIMITIVES_SCOPE bool pixelColor(SDL_Renderer * renderer, float x, float y, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool pixelRGBA(SDL_Renderer * renderer, float x, float y, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Horizontal line */ - - SDL3_GFXPRIMITIVES_SCOPE bool hlineColor(SDL_Renderer * renderer, float x1, float x2, float y, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool hlineRGBA(SDL_Renderer * renderer, float x1, float x2, float y, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Vertical line */ - - SDL3_GFXPRIMITIVES_SCOPE bool vlineColor(SDL_Renderer * renderer, float x, float y1, float y2, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool vlineRGBA(SDL_Renderer * renderer, float x, float y1, float y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Rectangle */ - - SDL3_GFXPRIMITIVES_SCOPE bool rectangleColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool rectangleRGBA(SDL_Renderer * renderer, float x1, float y1, - float x2, float y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Rounded-Corner Rectangle */ - - SDL3_GFXPRIMITIVES_SCOPE bool roundedRectangleColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float rad, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool roundedRectangleRGBA(SDL_Renderer * renderer, float x1, float y1, - float x2, float y2, float rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Filled rectangle (Box) */ - - SDL3_GFXPRIMITIVES_SCOPE bool boxColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool boxRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, - float y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Rounded-Corner Filled rectangle (Box) */ - - SDL3_GFXPRIMITIVES_SCOPE bool roundedBoxColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float rad, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool roundedBoxRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, - float y2, float rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Line */ - - SDL3_GFXPRIMITIVES_SCOPE bool lineColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool lineRGBA(SDL_Renderer * renderer, float x1, float y1, - float x2, float y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* AA Line */ - - SDL3_GFXPRIMITIVES_SCOPE bool aalineColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool aalineRGBA(SDL_Renderer * renderer, float x1, float y1, - float x2, float y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Thick Line */ - SDL3_GFXPRIMITIVES_SCOPE bool thickLineColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, - float width, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool thickLineRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, - float width, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Circle */ - - SDL3_GFXPRIMITIVES_SCOPE bool circleColor(SDL_Renderer * renderer, float x, float y, float rad, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool circleRGBA(SDL_Renderer * renderer, float x, float y, float rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Arc */ - - SDL3_GFXPRIMITIVES_SCOPE bool arcColor(SDL_Renderer * renderer, float x, float y, float rad, Sint32 start, Sint32 end, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool arcRGBA(SDL_Renderer * renderer, float x, float y, float rad, Sint32 start, Sint32 end, - Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* AA Circle */ - - SDL3_GFXPRIMITIVES_SCOPE bool aacircleColor(SDL_Renderer * renderer, float x, float y, float rad, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool aacircleRGBA(SDL_Renderer * renderer, float x, float y, - float rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Filled Circle */ - - SDL3_GFXPRIMITIVES_SCOPE bool filledCircleColor(SDL_Renderer * renderer, float x, float y, float r, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool filledCircleRGBA(SDL_Renderer * renderer, float x, float y, - float rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Ellipse */ - - SDL3_GFXPRIMITIVES_SCOPE bool ellipseColor(SDL_Renderer * renderer, float x, float y, float rx, float ry, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool ellipseRGBA(SDL_Renderer * renderer, float x, float y, - float rx, float ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* AA Ellipse */ - - SDL3_GFXPRIMITIVES_SCOPE bool aaellipseColor(SDL_Renderer * renderer, float x, float y, float rx, float ry, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool aaellipseRGBA(SDL_Renderer * renderer, float x, float y, - float rx, float ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Filled Ellipse */ - - SDL3_GFXPRIMITIVES_SCOPE bool filledEllipseColor(SDL_Renderer * renderer, float x, float y, float rx, float ry, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool filledEllipseRGBA(SDL_Renderer * renderer, float x, float y, - float rx, float ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Pie */ - - SDL3_GFXPRIMITIVES_SCOPE bool pieColor(SDL_Renderer * renderer, float x, float y, float rad, - Sint32 start, Sint32 end, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool pieRGBA(SDL_Renderer * renderer, float x, float y, float rad, - Sint32 start, Sint32 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Filled Pie */ - - SDL3_GFXPRIMITIVES_SCOPE bool filledPieColor(SDL_Renderer * renderer, float x, float y, float rad, - Sint32 start, Sint32 end, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool filledPieRGBA(SDL_Renderer * renderer, float x, float y, float rad, - Sint32 start, Sint32 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Trigon */ - - SDL3_GFXPRIMITIVES_SCOPE bool trigonColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float x3, float y3, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool trigonRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float x3, float y3, - Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* AA-Trigon */ - - SDL3_GFXPRIMITIVES_SCOPE bool aatrigonColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float x3, float y3, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool aatrigonRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float x3, float y3, - Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Filled Trigon */ - - SDL3_GFXPRIMITIVES_SCOPE bool filledTrigonColor(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float x3, float y3, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool filledTrigonRGBA(SDL_Renderer * renderer, float x1, float y1, float x2, float y2, float x3, float y3, - Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Polygon */ - - SDL3_GFXPRIMITIVES_SCOPE bool polygonColor(SDL_Renderer * renderer, const float * vx, const float * vy, Sint32 n, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool polygonRGBA(SDL_Renderer * renderer, const float * vx, const float * vy, - Sint32 n, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* AA-Polygon */ - - SDL3_GFXPRIMITIVES_SCOPE bool aapolygonColor(SDL_Renderer * renderer, const float * vx, const float * vy, Sint32 n, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool aapolygonRGBA(SDL_Renderer * renderer, const float * vx, const float * vy, - Sint32 n, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Filled Polygon */ - - SDL3_GFXPRIMITIVES_SCOPE bool filledPolygonColor(SDL_Renderer * renderer, const float * vx, const float * vy, Sint32 n, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool filledPolygonRGBA(SDL_Renderer * renderer, const float * vx, - const float * vy, Sint32 n, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Textured Polygon */ - - SDL3_GFXPRIMITIVES_SCOPE bool texturedPolygon(SDL_Renderer * renderer, const float * vx, const float * vy, Sint32 n, SDL_Surface * texture,Sint32 texture_dx,Sint32 texture_dy); - - /* Bezier */ - - SDL3_GFXPRIMITIVES_SCOPE bool bezierColor(SDL_Renderer * renderer, const float * vx, const float * vy, Sint32 n, Sint32 s, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool bezierRGBA(SDL_Renderer * renderer, const float * vx, const float * vy, - Sint32 n, Sint32 s, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Characters/Strings */ - - SDL3_GFXPRIMITIVES_SCOPE void gfxPrimitivesSetFont(const void *fontdata, Uint32 cw, Uint32 ch); - SDL3_GFXPRIMITIVES_SCOPE void gfxPrimitivesSetFontRotation(Uint32 rotation); - SDL3_GFXPRIMITIVES_SCOPE bool characterColor(SDL_Renderer * renderer, float x, float y, char c, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool characterRGBA(SDL_Renderer * renderer, float x, float y, char c, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - SDL3_GFXPRIMITIVES_SCOPE bool stringColor(SDL_Renderer * renderer, float x, float y, const char *s, Uint32 color); - SDL3_GFXPRIMITIVES_SCOPE bool stringRGBA(SDL_Renderer * renderer, float x, float y, const char *s, Uint8 r, Uint8 g, Uint8 b, Uint8 a); - - /* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif - -#endif /* _SDL3_gfxPrimitives_h */ \ No newline at end of file diff --git a/src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives_font.h b/src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives_font.h deleted file mode 100644 index a5fc0f4..0000000 --- a/src/ogfx/vendor/sdl3_gfx/SDL3_gfxPrimitives_font.h +++ /dev/null @@ -1,3106 +0,0 @@ -/* - -SDL3_gfxPrimitives_font.h: 8x8 font definition - -Copyright (C) 2012-2014 Andreas Schiffler - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. - -Andreas Schiffler -- aschiffler at ferzkopp dot net - -*/ - -#define GFX_FONTDATAMAX (8*256) - -static unsigned char gfxPrimitivesFontdata[GFX_FONTDATAMAX] = { - - /* - * 0 0x00 '^@' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 1 0x01 '^A' - */ - 0x7e, /* 01111110 */ - 0x81, /* 10000001 */ - 0xa5, /* 10100101 */ - 0x81, /* 10000001 */ - 0xbd, /* 10111101 */ - 0x99, /* 10011001 */ - 0x81, /* 10000001 */ - 0x7e, /* 01111110 */ - - /* - * 2 0x02 '^B' - */ - 0x7e, /* 01111110 */ - 0xff, /* 11111111 */ - 0xdb, /* 11011011 */ - 0xff, /* 11111111 */ - 0xc3, /* 11000011 */ - 0xe7, /* 11100111 */ - 0xff, /* 11111111 */ - 0x7e, /* 01111110 */ - - /* - * 3 0x03 '^C' - */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - - /* - * 4 0x04 '^D' - */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x7c, /* 01111100 */ - 0xfe, /* 11111110 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0x10, /* 00010000 */ - 0x00, /* 00000000 */ - - /* - * 5 0x05 '^E' - */ - 0x38, /* 00111000 */ - 0x7c, /* 01111100 */ - 0x38, /* 00111000 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xd6, /* 11010110 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - - /* - * 6 0x06 '^F' - */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x7c, /* 01111100 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0x7c, /* 01111100 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - - /* - * 7 0x07 '^G' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 8 0x08 '^H' - */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xe7, /* 11100111 */ - 0xc3, /* 11000011 */ - 0xc3, /* 11000011 */ - 0xe7, /* 11100111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - - /* - * 9 0x09 '^I' - */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x42, /* 01000010 */ - 0x42, /* 01000010 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 10 0x0a '^J' - */ - 0xff, /* 11111111 */ - 0xc3, /* 11000011 */ - 0x99, /* 10011001 */ - 0xbd, /* 10111101 */ - 0xbd, /* 10111101 */ - 0x99, /* 10011001 */ - 0xc3, /* 11000011 */ - 0xff, /* 11111111 */ - - /* - * 11 0x0b '^K' - */ - 0x0f, /* 00001111 */ - 0x07, /* 00000111 */ - 0x0f, /* 00001111 */ - 0x7d, /* 01111101 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x78, /* 01111000 */ - - /* - * 12 0x0c '^L' - */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - - /* - * 13 0x0d '^M' - */ - 0x3f, /* 00111111 */ - 0x33, /* 00110011 */ - 0x3f, /* 00111111 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x70, /* 01110000 */ - 0xf0, /* 11110000 */ - 0xe0, /* 11100000 */ - - /* - * 14 0x0e '^N' - */ - 0x7f, /* 01111111 */ - 0x63, /* 01100011 */ - 0x7f, /* 01111111 */ - 0x63, /* 01100011 */ - 0x63, /* 01100011 */ - 0x67, /* 01100111 */ - 0xe6, /* 11100110 */ - 0xc0, /* 11000000 */ - - /* - * 15 0x0f '^O' - */ - 0x18, /* 00011000 */ - 0xdb, /* 11011011 */ - 0x3c, /* 00111100 */ - 0xe7, /* 11100111 */ - 0xe7, /* 11100111 */ - 0x3c, /* 00111100 */ - 0xdb, /* 11011011 */ - 0x18, /* 00011000 */ - - /* - * 16 0x10 '^P' - */ - 0x80, /* 10000000 */ - 0xe0, /* 11100000 */ - 0xf8, /* 11111000 */ - 0xfe, /* 11111110 */ - 0xf8, /* 11111000 */ - 0xe0, /* 11100000 */ - 0x80, /* 10000000 */ - 0x00, /* 00000000 */ - - /* - * 17 0x11 '^Q' - */ - 0x02, /* 00000010 */ - 0x0e, /* 00001110 */ - 0x3e, /* 00111110 */ - 0xfe, /* 11111110 */ - 0x3e, /* 00111110 */ - 0x0e, /* 00001110 */ - 0x02, /* 00000010 */ - 0x00, /* 00000000 */ - - /* - * 18 0x12 '^R' - */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - - /* - * 19 0x13 '^S' - */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - - /* - * 20 0x14 '^T' - */ - 0x7f, /* 01111111 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0x7b, /* 01111011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x00, /* 00000000 */ - - /* - * 21 0x15 '^U' - */ - 0x3e, /* 00111110 */ - 0x61, /* 01100001 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x86, /* 10000110 */ - 0x7c, /* 01111100 */ - - /* - * 22 0x16 '^V' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - - /* - * 23 0x17 '^W' - */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - - /* - * 24 0x18 '^X' - */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - - /* - * 25 0x19 '^Y' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - - /* - * 26 0x1a '^Z' - */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0xfe, /* 11111110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 27 0x1b '^[' - */ - 0x00, /* 00000000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xfe, /* 11111110 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 28 0x1c '^\' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 29 0x1d '^]' - */ - 0x00, /* 00000000 */ - 0x24, /* 00100100 */ - 0x66, /* 01100110 */ - 0xff, /* 11111111 */ - 0x66, /* 01100110 */ - 0x24, /* 00100100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 30 0x1e '^^' - */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 31 0x1f '^_' - */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0x7e, /* 01111110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 32 0x20 ' ' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 33 0x21 '!' - */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - - /* - * 34 0x22 '"' - */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x24, /* 00100100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 35 0x23 '#' - */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - - /* - * 36 0x24 '$' - */ - 0x18, /* 00011000 */ - 0x3e, /* 00111110 */ - 0x60, /* 01100000 */ - 0x3c, /* 00111100 */ - 0x06, /* 00000110 */ - 0x7c, /* 01111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - - /* - * 37 0x25 '%' - */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xcc, /* 11001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x66, /* 01100110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* - * 38 0x26 '&' - */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 39 0x27 ''' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 40 0x28 '(' - */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - - /* - * 41 0x29 ')' - */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - - /* - * 42 0x2a '*' - */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0xff, /* 11111111 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 43 0x2b '+' - */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 44 0x2c ',' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - - /* - * 45 0x2d '-' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 46 0x2e '.' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - - /* - * 47 0x2f '/' - */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0x80, /* 10000000 */ - 0x00, /* 00000000 */ - - /* - * 48 0x30 '0' - */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - - /* - * 49 0x31 '1' - */ - 0x18, /* 00011000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - - /* - * 50 0x32 '2' - */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x06, /* 00000110 */ - 0x1c, /* 00011100 */ - 0x30, /* 00110000 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - - /* - * 51 0x33 '3' - */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x06, /* 00000110 */ - 0x3c, /* 00111100 */ - 0x06, /* 00000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 52 0x34 '4' - */ - 0x1c, /* 00011100 */ - 0x3c, /* 00111100 */ - 0x6c, /* 01101100 */ - 0xcc, /* 11001100 */ - 0xfe, /* 11111110 */ - 0x0c, /* 00001100 */ - 0x1e, /* 00011110 */ - 0x00, /* 00000000 */ - - /* - * 53 0x35 '5' - */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xfc, /* 11111100 */ - 0x06, /* 00000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 54 0x36 '6' - */ - 0x38, /* 00111000 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - 0xfc, /* 11111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 55 0x37 '7' - */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - - /* - * 56 0x38 '8' - */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 57 0x39 '9' - */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - - /* - * 58 0x3a ':' - */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - - /* - * 59 0x3b ';' - */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - - /* - * 60 0x3c '<' - */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - - /* - * 61 0x3d '=' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 62 0x3e '>' - */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x00, /* 00000000 */ - - /* - * 63 0x3f '?' - */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - - /* - * 64 0x40 '@' - */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xde, /* 11011110 */ - 0xde, /* 11011110 */ - 0xde, /* 11011110 */ - 0xc0, /* 11000000 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - - /* - * 65 0x41 'A' - */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* - * 66 0x42 'B' - */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xfc, /* 11111100 */ - 0x00, /* 00000000 */ - - /* - * 67 0x43 'C' - */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 68 0x44 'D' - */ - 0xf8, /* 11111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - - /* - * 69 0x45 'E' - */ - 0xfe, /* 11111110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x62, /* 01100010 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - - /* - * 70 0x46 'F' - */ - 0xfe, /* 11111110 */ - 0x62, /* 01100010 */ - 0x68, /* 01101000 */ - 0x78, /* 01111000 */ - 0x68, /* 01101000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - - /* - * 71 0x47 'G' - */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xce, /* 11001110 */ - 0x66, /* 01100110 */ - 0x3a, /* 00111010 */ - 0x00, /* 00000000 */ - - /* - * 72 0x48 'H' - */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* - * 73 0x49 'I' - */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 74 0x4a 'J' - */ - 0x1e, /* 00011110 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x78, /* 01111000 */ - 0x00, /* 00000000 */ - - /* - * 75 0x4b 'K' - */ - 0xe6, /* 11100110 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - - /* - * 76 0x4c 'L' - */ - 0xf0, /* 11110000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0x62, /* 01100010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - - /* - * 77 0x4d 'M' - */ - 0xc6, /* 11000110 */ - 0xee, /* 11101110 */ - 0xfe, /* 11111110 */ - 0xfe, /* 11111110 */ - 0xd6, /* 11010110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* - * 78 0x4e 'N' - */ - 0xc6, /* 11000110 */ - 0xe6, /* 11100110 */ - 0xf6, /* 11110110 */ - 0xde, /* 11011110 */ - 0xce, /* 11001110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* - * 79 0x4f 'O' - */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 80 0x50 'P' - */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - - /* - * 81 0x51 'Q' - */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xce, /* 11001110 */ - 0x7c, /* 01111100 */ - 0x0e, /* 00001110 */ - - /* - * 82 0x52 'R' - */ - 0xfc, /* 11111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x6c, /* 01101100 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - - /* - * 83 0x53 'S' - */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 84 0x54 'T' - */ - 0x7e, /* 01111110 */ - 0x7e, /* 01111110 */ - 0x5a, /* 01011010 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 85 0x55 'U' - */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 86 0x56 'V' - */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - - /* - * 87 0x57 'W' - */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - - /* - * 88 0x58 'X' - */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* - * 89 0x59 'Y' - */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 90 0x5a 'Z' - */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x8c, /* 10001100 */ - 0x18, /* 00011000 */ - 0x32, /* 00110010 */ - 0x66, /* 01100110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - - /* - * 91 0x5b '[' - */ - 0x3c, /* 00111100 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 92 0x5c '\' - */ - 0xc0, /* 11000000 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x06, /* 00000110 */ - 0x02, /* 00000010 */ - 0x00, /* 00000000 */ - - /* - * 93 0x5d ']' - */ - 0x3c, /* 00111100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 94 0x5e '^' - */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 95 0x5f '_' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - - /* - * 96 0x60 '`' - */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 97 0x61 'a' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 98 0x62 'b' - */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x7c, /* 01111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - - /* - * 99 0x63 'c' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 100 0x64 'd' - */ - 0x1c, /* 00011100 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 101 0x65 'e' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 102 0x66 'f' - */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x60, /* 01100000 */ - 0xf8, /* 11111000 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - - /* - * 103 0x67 'g' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0xf8, /* 11111000 */ - - /* - * 104 0x68 'h' - */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x6c, /* 01101100 */ - 0x76, /* 01110110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - - /* - * 105 0x69 'i' - */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 106 0x6a 'j' - */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - - /* - * 107 0x6b 'k' - */ - 0xe0, /* 11100000 */ - 0x60, /* 01100000 */ - 0x66, /* 01100110 */ - 0x6c, /* 01101100 */ - 0x78, /* 01111000 */ - 0x6c, /* 01101100 */ - 0xe6, /* 11100110 */ - 0x00, /* 00000000 */ - - /* - * 108 0x6c 'l' - */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 109 0x6d 'm' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xec, /* 11101100 */ - 0xfe, /* 11111110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0x00, /* 00000000 */ - - /* - * 110 0x6e 'n' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - - /* - * 111 0x6f 'o' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 112 0x70 'p' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - - /* - * 113 0x71 'q' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0x1e, /* 00011110 */ - - /* - * 114 0x72 'r' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x76, /* 01110110 */ - 0x60, /* 01100000 */ - 0x60, /* 01100000 */ - 0xf0, /* 11110000 */ - 0x00, /* 00000000 */ - - /* - * 115 0x73 's' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x06, /* 00000110 */ - 0xfc, /* 11111100 */ - 0x00, /* 00000000 */ - - /* - * 116 0x74 't' - */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0xfc, /* 11111100 */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x36, /* 00110110 */ - 0x1c, /* 00011100 */ - 0x00, /* 00000000 */ - - /* - * 117 0x75 'u' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 118 0x76 'v' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - - /* - * 119 0x77 'w' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xd6, /* 11010110 */ - 0xd6, /* 11010110 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - - /* - * 120 0x78 'x' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* - * 121 0x79 'y' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0xfc, /* 11111100 */ - - /* - * 122 0x7a 'z' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x4c, /* 01001100 */ - 0x18, /* 00011000 */ - 0x32, /* 00110010 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - - /* - * 123 0x7b '{' - */ - 0x0e, /* 00001110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x0e, /* 00001110 */ - 0x00, /* 00000000 */ - - /* - * 124 0x7c '|' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - - /* - * 125 0x7d '}' - */ - 0x70, /* 01110000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x0e, /* 00001110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - - /* - * 126 0x7e '~' - */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 127 0x7f '' - */ - 0x00, /* 00000000 */ - 0x10, /* 00010000 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - - /* - * 128 0x80 '' - */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x0c, /* 00001100 */ - 0x78, /* 01111000 */ - - /* - * 129 0x81 '' - */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 130 0x82 '' - */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 131 0x83 '' - */ - 0x7c, /* 01111100 */ - 0x82, /* 10000010 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 132 0x84 '' - */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 133 0x85 '' - */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 134 0x86 '' - */ - 0x30, /* 00110000 */ - 0x30, /* 00110000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 135 0x87 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0x7e, /* 01111110 */ - 0x0c, /* 00001100 */ - 0x38, /* 00111000 */ - - /* - * 136 0x88 '' - */ - 0x7c, /* 01111100 */ - 0x82, /* 10000010 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 137 0x89 '' - */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 138 0x8a '' - */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 139 0x8b '' - */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 140 0x8c '' - */ - 0x7c, /* 01111100 */ - 0x82, /* 10000010 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 141 0x8d '' - */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 142 0x8e '' - */ - 0xc6, /* 11000110 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* - * 143 0x8f '' - */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* - * 144 0x90 '' - */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xf8, /* 11111000 */ - 0xc0, /* 11000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - - /* - * 145 0x91 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0xd8, /* 11011000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - - /* - * 146 0x92 '' - */ - 0x3e, /* 00111110 */ - 0x6c, /* 01101100 */ - 0xcc, /* 11001100 */ - 0xfe, /* 11111110 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xce, /* 11001110 */ - 0x00, /* 00000000 */ - - /* - * 147 0x93 '' - */ - 0x7c, /* 01111100 */ - 0x82, /* 10000010 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 148 0x94 '' - */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 149 0x95 '' - */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 150 0x96 '' - */ - 0x78, /* 01111000 */ - 0x84, /* 10000100 */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 151 0x97 '' - */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 152 0x98 '' - */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7e, /* 01111110 */ - 0x06, /* 00000110 */ - 0xfc, /* 11111100 */ - - /* - * 153 0x99 '' - */ - 0xc6, /* 11000110 */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - - /* - * 154 0x9a '' - */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 155 0x9b '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 156 0x9c '' - */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x64, /* 01100100 */ - 0xf0, /* 11110000 */ - 0x60, /* 01100000 */ - 0x66, /* 01100110 */ - 0xfc, /* 11111100 */ - 0x00, /* 00000000 */ - - /* - * 157 0x9d '' - */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 158 0x9e '' - */ - 0xf8, /* 11111000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xfa, /* 11111010 */ - 0xc6, /* 11000110 */ - 0xcf, /* 11001111 */ - 0xc6, /* 11000110 */ - 0xc7, /* 11000111 */ - - /* - * 159 0x9f '' - */ - 0x0e, /* 00001110 */ - 0x1b, /* 00011011 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0xd8, /* 11011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - - /* - * 160 0xa0 '' - */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x7c, /* 01111100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 161 0xa1 '' - */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x38, /* 00111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 162 0xa2 '' - */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - - /* - * 163 0xa3 '' - */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 164 0xa4 '' - */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0xdc, /* 11011100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x00, /* 00000000 */ - - /* - * 165 0xa5 '' - */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0xe6, /* 11100110 */ - 0xf6, /* 11110110 */ - 0xde, /* 11011110 */ - 0xce, /* 11001110 */ - 0x00, /* 00000000 */ - - /* - * 166 0xa6 '' - */ - 0x3c, /* 00111100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x3e, /* 00111110 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 167 0xa7 '' - */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 168 0xa8 '' - */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x63, /* 01100011 */ - 0x3e, /* 00111110 */ - 0x00, /* 00000000 */ - - /* - * 169 0xa9 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 170 0xaa '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x06, /* 00000110 */ - 0x06, /* 00000110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 171 0xab '' - */ - 0x63, /* 01100011 */ - 0xe6, /* 11100110 */ - 0x6c, /* 01101100 */ - 0x7e, /* 01111110 */ - 0x33, /* 00110011 */ - 0x66, /* 01100110 */ - 0xcc, /* 11001100 */ - 0x0f, /* 00001111 */ - - /* - * 172 0xac '' - */ - 0x63, /* 01100011 */ - 0xe6, /* 11100110 */ - 0x6c, /* 01101100 */ - 0x7a, /* 01111010 */ - 0x36, /* 00110110 */ - 0x6a, /* 01101010 */ - 0xdf, /* 11011111 */ - 0x06, /* 00000110 */ - - /* - * 173 0xad '' - */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - - /* - * 174 0xae '' - */ - 0x00, /* 00000000 */ - 0x33, /* 00110011 */ - 0x66, /* 01100110 */ - 0xcc, /* 11001100 */ - 0x66, /* 01100110 */ - 0x33, /* 00110011 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 175 0xaf '' - */ - 0x00, /* 00000000 */ - 0xcc, /* 11001100 */ - 0x66, /* 01100110 */ - 0x33, /* 00110011 */ - 0x66, /* 01100110 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 176 0xb0 '' - */ - 0x22, /* 00100010 */ - 0x88, /* 10001000 */ - 0x22, /* 00100010 */ - 0x88, /* 10001000 */ - 0x22, /* 00100010 */ - 0x88, /* 10001000 */ - 0x22, /* 00100010 */ - 0x88, /* 10001000 */ - - /* - * 177 0xb1 '' - */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - 0x55, /* 01010101 */ - 0xaa, /* 10101010 */ - - /* - * 178 0xb2 '' - */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - 0x77, /* 01110111 */ - 0xdd, /* 11011101 */ - - /* - * 179 0xb3 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 180 0xb4 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 181 0xb5 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 182 0xb6 '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf6, /* 11110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 183 0xb7 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 184 0xb8 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 185 0xb9 '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf6, /* 11110110 */ - 0x06, /* 00000110 */ - 0xf6, /* 11110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 186 0xba '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 187 0xbb '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x06, /* 00000110 */ - 0xf6, /* 11110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 188 0xbc '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf6, /* 11110110 */ - 0x06, /* 00000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 189 0xbd '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 190 0xbe '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 191 0xbf '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xf8, /* 11111000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 192 0xc0 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 193 0xc1 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 194 0xc2 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 195 0xc3 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 196 0xc4 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 197 0xc5 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 198 0xc6 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 199 0xc7 '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x37, /* 00110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 200 0xc8 '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x37, /* 00110111 */ - 0x30, /* 00110000 */ - 0x3f, /* 00111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 201 0xc9 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3f, /* 00111111 */ - 0x30, /* 00110000 */ - 0x37, /* 00110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 202 0xca '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf7, /* 11110111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 203 0xcb '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xf7, /* 11110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 204 0xcc '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x37, /* 00110111 */ - 0x30, /* 00110000 */ - 0x37, /* 00110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 205 0xcd '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 206 0xce '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xf7, /* 11110111 */ - 0x00, /* 00000000 */ - 0xf7, /* 11110111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 207 0xcf '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 208 0xd0 '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 209 0xd1 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 210 0xd2 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 211 0xd3 '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x3f, /* 00111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 212 0xd4 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 213 0xd5 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 214 0xd6 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3f, /* 00111111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 215 0xd7 '' - */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0xff, /* 11111111 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - - /* - * 216 0xd8 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0xff, /* 11111111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 217 0xd9 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xf8, /* 11111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 218 0xda '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x1f, /* 00011111 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 219 0xdb '' - */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - - /* - * 220 0xdc '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - - /* - * 221 0xdd '' - */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - 0xf0, /* 11110000 */ - - /* - * 222 0xde '' - */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - 0x0f, /* 00001111 */ - - /* - * 223 0xdf '' - */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0xff, /* 11111111 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 224 0xe0 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0xc8, /* 11001000 */ - 0xdc, /* 11011100 */ - 0x76, /* 01110110 */ - 0x00, /* 00000000 */ - - /* - * 225 0xe1 '' - */ - 0x78, /* 01111000 */ - 0xcc, /* 11001100 */ - 0xcc, /* 11001100 */ - 0xd8, /* 11011000 */ - 0xcc, /* 11001100 */ - 0xc6, /* 11000110 */ - 0xcc, /* 11001100 */ - 0x00, /* 00000000 */ - - /* - * 226 0xe2 '' - */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0xc0, /* 11000000 */ - 0x00, /* 00000000 */ - - /* - * 227 0xe3 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x00, /* 00000000 */ - - /* - * 228 0xe4 '' - */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - - /* - * 229 0xe5 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0x70, /* 01110000 */ - 0x00, /* 00000000 */ - - /* - * 230 0xe6 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x7c, /* 01111100 */ - 0xc0, /* 11000000 */ - - /* - * 231 0xe7 '' - */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - - /* - * 232 0xe8 '' - */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x3c, /* 00111100 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - - /* - * 233 0xe9 '' - */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xfe, /* 11111110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - - /* - * 234 0xea '' - */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0xee, /* 11101110 */ - 0x00, /* 00000000 */ - - /* - * 235 0xeb '' - */ - 0x0e, /* 00001110 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x3e, /* 00111110 */ - 0x66, /* 01100110 */ - 0x66, /* 01100110 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - - /* - * 236 0xec '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 237 0xed '' - */ - 0x06, /* 00000110 */ - 0x0c, /* 00001100 */ - 0x7e, /* 01111110 */ - 0xdb, /* 11011011 */ - 0xdb, /* 11011011 */ - 0x7e, /* 01111110 */ - 0x60, /* 01100000 */ - 0xc0, /* 11000000 */ - - /* - * 238 0xee '' - */ - 0x1e, /* 00011110 */ - 0x30, /* 00110000 */ - 0x60, /* 01100000 */ - 0x7e, /* 01111110 */ - 0x60, /* 01100000 */ - 0x30, /* 00110000 */ - 0x1e, /* 00011110 */ - 0x00, /* 00000000 */ - - /* - * 239 0xef '' - */ - 0x00, /* 00000000 */ - 0x7c, /* 01111100 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0xc6, /* 11000110 */ - 0x00, /* 00000000 */ - - /* - * 240 0xf0 '' - */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0xfe, /* 11111110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 241 0xf1 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x7e, /* 01111110 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - - /* - * 242 0xf2 '' - */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - - /* - * 243 0xf3 '' - */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x18, /* 00011000 */ - 0x0c, /* 00001100 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - - /* - * 244 0xf4 '' - */ - 0x0e, /* 00001110 */ - 0x1b, /* 00011011 */ - 0x1b, /* 00011011 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - - /* - * 245 0xf5 '' - */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0xd8, /* 11011000 */ - 0xd8, /* 11011000 */ - 0x70, /* 01110000 */ - - /* - * 246 0xf6 '' - */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x7e, /* 01111110 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 247 0xf7 '' - */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x76, /* 01110110 */ - 0xdc, /* 11011100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 248 0xf8 '' - */ - 0x38, /* 00111000 */ - 0x6c, /* 01101100 */ - 0x6c, /* 01101100 */ - 0x38, /* 00111000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 249 0xf9 '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 250 0xfa '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 00011000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 251 0xfb '' - */ - 0x0f, /* 00001111 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0x0c, /* 00001100 */ - 0xec, /* 11101100 */ - 0x6c, /* 01101100 */ - 0x3c, /* 00111100 */ - 0x1c, /* 00011100 */ - - /* - * 252 0xfc '' - */ - 0x6c, /* 01101100 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x36, /* 00110110 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 253 0xfd '' - */ - 0x78, /* 01111000 */ - 0x0c, /* 00001100 */ - 0x18, /* 00011000 */ - 0x30, /* 00110000 */ - 0x7c, /* 01111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 254 0xfe '' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x3c, /* 00111100 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* - * 255 0xff ' ' - */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - -}; diff --git a/src/ogfx/vendor/sdl3_gfx/SDL3_imageFilter.c b/src/ogfx/vendor/sdl3_gfx/SDL3_imageFilter.c deleted file mode 100644 index 41d787e..0000000 --- a/src/ogfx/vendor/sdl3_gfx/SDL3_imageFilter.c +++ /dev/null @@ -1,1617 +0,0 @@ -/* - -SDL3_imageFilter.c: byte-image "filter" routines - -Copyright (C) 2012-2014 Andreas Schiffler -Copyright (C) 2013 Sylvain Beucler - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. - -Andreas Schiffler -- aschiffler at ferzkopp dot net - -*/ - -#include -#include -#include - -#include - -#include "SDL3_imageFilter.h" - -/* ------ Custom defines ----- */ - -/*! -\brief Swaps the byte order in a 32bit integer (LSB becomes MSB, etc.). -*/ -#define SWAP_32(x) (((x) >> 24) | (((x) & 0x00ff0000) >> 8) | (((x) & 0x0000ff00) << 8) | ((x) << 24)) - -#define MAX_BYTES_PER_PIXEL 16 -/* ------------------------------------------------------------------------------------ */ - -/*! -\brief Filter using Add: D = saturation255(S1 + S2) - -\param Src1 Pointer to the start of the first source byte array (S1). -\param Src2 Pointer to the start of the second source byte array (S2). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterAdd(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart; - unsigned char *cursrc1, *cursrc2, *curdst; - int result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - cursrc2 = Src2; - curdst = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - result = (int) *cursrc1 + (int) *cursrc2; - if (result > 255) - result = 255; - *curdst = (unsigned char) result; - /* Advance pointers */ - cursrc1++; - cursrc2++; - curdst++; - } - - return true; -} - -/*! -\brief Filter using Mean: D = S1/2 + S2/2 - -\param Src1 Pointer to the start of the first source byte array (S1). -\param Src2 Pointer to the start of the second source byte array (S2). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterMean(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart; - unsigned char *cursrc1, *cursrc2, *curdst; - float tmp, fSrc1, fSrc2; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - cursrc2 = Src2; - curdst = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - fSrc1 = cursrc1[i] / 255.0f; - fSrc2 = cursrc2[i] / 255.0f; - tmp = fSrc1 / 2 + fSrc2 / 2; - curdst[i] = (unsigned char) (tmp * 255) ; - } - - return true; -} - -/*! -\brief Filter using Sub: D = saturation0(S1 - S2) - -\param Src1 Pointer to the start of the first source byte array (S1). -\param Src2 Pointer to the start of the second source byte array (S2). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterSub(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart; - unsigned char *cursrc1, *cursrc2, *curdst; - int result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - cursrc2 = Src2; - curdst = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - result = (int) cursrc1[i] - (int) cursrc2[i]; - if (result < 0) - result = 0; - curdst[i] = (unsigned char) result; - } - return true; -} - -/*! -\brief Filter using AbsDiff: D = | S1 - S2 | - -\param Src1 Pointer to the start of the first source byte array (S1). -\param Src2 Pointer to the start of the second source byte array (S2). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterAbsDiff(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart; - unsigned char *cursrc1, *cursrc2, *curdst; - int result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - cursrc2 = Src2; - curdst = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - result = abs((int) *cursrc1 - (int) *cursrc2); - *curdst = (unsigned char) result; - /* Advance pointers */ - cursrc1++; - cursrc2++; - curdst++; - } - - return true; -} - -/*! -\brief Filter using Mult: D = saturation255(S1 * S2) - -\param Src1 Pointer to the start of the first source byte array (S1). -\param Src2 Pointer to the start of the second source byte array (S2). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterMult(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart; - unsigned char *cursrc1, *cursrc2, *curdst; - float tmp, fSrc1, fSrc2; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - cursrc2 = Src2; - curdst = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - fSrc1 = cursrc1[i] / 255.0f; - fSrc2 = cursrc1[i] / 255.0f; - tmp = fSrc1 * fSrc2; - curdst[i] = (unsigned char) (tmp * 255); - } - - return true; -} - -/*! -\brief Filter using MultUnbound: D = S1 * S2 - No saturation - -\param Src1 Pointer to the start of the first source byte array (S1). -\param Src2 Pointer to the start of the second source byte array (S2). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterMultUnbound(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart, tmp; - unsigned char *cursrc1, *cursrc2, *curdst; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - cursrc2 = Src2; - curdst = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - tmp = (unsigned int) cursrc1[i] * (unsigned int) cursrc2[i]; - curdst[i] = (unsigned char) tmp; - } - - return true; -} - -/*! -\brief Filter using MultInv: D = 255 - ((255 - S1) * (255 - S2)) - -\param Src1 Pointer to the start of the first source byte array (S1). -\param Src2 Pointer to the start of the second source byte array (S2). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterMultInv(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart; - unsigned char *cursrc1, *cursrc2, *curdst; - float tmp, fSrc1, fSrc2; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - cursrc2 = Src2; - curdst = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - fSrc1 = cursrc1[i] / 255.0f; - fSrc2 = cursrc2[i] / 255.0f; - tmp = 1.0f - ((1.0f - fSrc1) * (1.0f - fSrc2)); - curdst[i] = (unsigned char) (tmp * 255); - } - - return true; -} - -/*! -\brief Filter using MultDivby2: D = saturation255(S1/2 * S2) - -\param Src1 Pointer to the start of the first source byte array (S1). -\param Src2 Pointer to the start of the second source byte array (S2). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterMultDivby2(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart; - unsigned char *cursrc1, *cursrc2, *curdst; - int result; - float tmp, fSrc1, fSrc2; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - cursrc2 = Src2; - curdst = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - fSrc1 = cursrc1[i] / 255.0f; - fSrc2 = cursrc2[i] / 255.0f; - tmp = (fSrc1 * fSrc2) / 2.0f; - if (tmp > 1.0f) - tmp = 1.0f; - curdst[i] = (unsigned char) (tmp * 255); - } - - return true; -} - -/*! -\brief Filter using MultDivby4: D = saturation255(S1/2 * S2/2) - -\param Src1 Pointer to the start of the first source byte array (S1). -\param Src2 Pointer to the start of the second source byte array (S2). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterMultDivby4(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart; - unsigned char *cursrc1, *cursrc2, *curdst; - int result; - float tmp, fSrc1, fSrc2; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - cursrc2 = Src2; - curdst = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - fSrc1 = cursrc1[i] / 255.0f; - fSrc2 = cursrc2[i] / 255.0f; - tmp = (fSrc1 * fSrc2) / 4.0f; - if (tmp > 1.0f) - tmp = 1.0f; - curdst[i] = (unsigned char) (tmp * 255); - } - - return true; -} - -/*! -\brief Filter using BitAnd: D = S1 & S2 - -\param Src1 Pointer to the start of the first source byte array (S1). -\param Src2 Pointer to the start of the second source byte array (S2). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterBitAnd(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart; - unsigned char *cursrc1, *cursrc2, *curdst; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - cursrc2 = Src2; - curdst = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - *curdst = (*cursrc1) & (*cursrc2); - /* Advance pointers */ - cursrc1++; - cursrc2++; - curdst++; - } - - return true; -} - -/*! -\brief Filter using BitOr: D = S1 | S2 - -\param Src1 Pointer to the start of the first source byte array (S1). -\param Src2 Pointer to the start of the second source byte array (S2). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterBitOr(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart; - unsigned char *cursrc1, *cursrc2, *curdst; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - cursrc2 = Src2; - curdst = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - *curdst = *cursrc1 | *cursrc2; - /* Advance pointers */ - cursrc1++; - cursrc2++; - curdst++; - } - - return true; -} - -/*! -\brief Filter using Div: D = S1 / S2 - -\param Src1 Pointer to the start of the first source byte array (S1). -\param Src2 Pointer to the start of the second source byte array (S2). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterDiv(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart; - unsigned char *cursrc1, *cursrc2, *curdst; - float tmp, fSrc1, fSrc2; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Src2 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - cursrc2 = Src2; - curdst = Dest; - - for (i = istart; i < length; i++) { - if (cursrc2[i] == 0) { - curdst[i] = 0; - } else { - fSrc1 = cursrc1[i] / 255.0f; - fSrc2 = cursrc2[i] / 255.0f; - tmp = cursrc1[i] / cursrc2[i]; - if (tmp > 1.0f) - tmp = 1.0f; - curdst[i] = (unsigned char) (tmp * 255); - } - } - - return true; -} - -/* ------------------------------------------------------------------------------------ */ - -/*! -\brief Filter using BitNegation: D = !S - -\param Src1 Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source array. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterBitNegation(unsigned char *Src1, unsigned char *Dest, unsigned int length) -{ - unsigned int i, istart; - unsigned char *cursrc1, *curdst; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdst = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - *curdst = ~(*cursrc1); - /* Advance pointers */ - cursrc1++; - curdst++; - } - - return true; -} - -/*! -\brief Filter using AddByte: D = saturation255(S + C) - -\param Src1 Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source array. -\param C Constant value to add (C). - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterAddByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C) -{ - unsigned int i, istart; - int iC; - unsigned char *cursrc1, *curdest; - int result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Special case: C==0 */ - if (C == 0) { - memcpy(Src1, Dest, length); - return true; - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* C routine to process image */ - iC = (int) C; - for (i = istart; i < length; i++) { - result = (int) *cursrc1 + iC; - if (result > 255) - result = 255; - *curdest = (unsigned char) result; - /* Advance pointers */ - cursrc1++; - curdest++; - } - return true; -} - -/*! -\brief Filter using AddUint: D = saturation255((S[i] + Cs[i % BPP]) - -\param Src1 Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source array. -\param bpp The bytes per unit length (BPP) -\param C Constant to add (C). - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterAddUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned int bpp, unsigned int C) -{ - unsigned int i, j, istart; - int iC[MAX_BYTES_PER_PIXEL], k; - unsigned char *cursrc1; - unsigned char *curdest; - int result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Special case: C==0 */ - if (C == 0) { - memcpy(Src1, Dest, length); - return true; - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* Routine to process uint */ - for (k = bpp; k >= 0; k--) { - iC[k] = (int) ((C >> (8*(bpp - k))) & 0xff); - } - - /* Routine to process bytes */ - for (i = istart; i < length; i += bpp) { - for (j = 0; j < bpp; j++) { - if ((i+j) < length) { - result = cursrc1[i+j] + iC[j]; - if (result > 255){ - result = 255; - } - curdest[i+j] = (unsigned char) result; - } - } - } - return true; -} - -/*! -\brief Filter using AddByteToHalf: D = saturation255(S/2 + C) - -\param Src1 Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source array. -\param C Constant to add (C). - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterAddByteToHalf(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C) -{ - unsigned int i, istart; - int iC; - unsigned char *cursrc1; - unsigned char *curdest; - int result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* Routine to process image */ - iC = (int) C; - for (i = istart; i < length; i++) { - result = (int) (*cursrc1 / 2) + iC; - if (result > 255) - result = 255; - *curdest = (unsigned char) result; - /* Advance pointers */ - cursrc1++; - curdest++; - } - - return true; -} - -/*! -\brief Filter using SubByte: D = saturation0(S - C) - -\param Src1 Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. -\param C Constant to subtract (C). - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterSubByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C) -{ - unsigned int i, istart; - int iC; - unsigned char *cursrc1; - unsigned char *curdest; - int result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Special case: C==0 */ - if (C == 0) { - memcpy(Src1, Dest, length); - return true; - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* Routine to process image */ - iC = (int) C; - for (i = istart; i < length; i++) { - result = (int) *cursrc1 - iC; - if (result < 0) - result = 0; - *curdest = (unsigned char) result; - /* Advance pointers */ - cursrc1++; - curdest++; - } - return true; -} - -/*! -\brief Filter using SubUint: D = saturation0(S[i] - Cs[i % BPP]) - -\param Src1 Pointer to the start of the source byte array (S1). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source array. -\param bpp The bytes per unit length (BPP) -\param C Constant to subtract (C). - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterSubUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned int bpp, unsigned int C) -{ - unsigned int i, j, istart; - int iC[MAX_BYTES_PER_PIXEL], k; - unsigned char *cursrc1; - unsigned char *curdest; - int result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Special case: C==0 */ - if (C == 0) { - memcpy(Src1, Dest, length); - return true; - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* Routine to process uint */ - for (k = bpp; k >= 0; k--) { - iC[k] = (int) ((C >> (8*(bpp - k))) & 0xff); - } - - /* Routine to process bytes */ - for (i = istart; i < length; i += bpp) { - for (j = 0; j < bpp; j++) { - if ((i+j) < length) { - result = cursrc1[i+j] - iC[j]; - if (result < 0){ - result = 0; - } - curdest[i+j] = (unsigned char) result; - } - } - } - - return true; -} - -/*! -\brief Filter using ShiftRightUint: D = saturation0((uint)S[i] >> N) - -\param Src1 Pointer to the start of the source byte array (S1). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source array. -\param N Number of bit-positions to shift (N). Valid range is 0 to 8. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterShiftRightUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned int bpp, unsigned char N) -{ - unsigned int i,istart; - unsigned char *cursrc1, *curdest; - unsigned int *icursrc1, *icurdest; - int j, result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Check shift */ - if (N > 8) { - return false; - } - - /* Special case: N==0 */ - if (N == 0) { - memcpy(Src1, Dest, length); - return (0); - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i += bpp) { - if ((i + bpp) < length) { - result = 0; - for (j = bpp; j >= 0; j--) { - result |= (unsigned int) ((cursrc1[i + j] << (sizeof(unsigned int) * j))); - } - /* Do the actual uint shift */ - result = result >> N; - /* Pass the shifted value to each byte */ - for (j = 0; j < bpp; j++) { - curdest[i + j] = (result >> bpp) & 0xFF; - } - } - } - - return true; -} - -/*! -\brief Filter using MultByByte: D = saturation255(S * C) - -\param Src1 Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. -\param C Constant to multiply with (C). - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterMultByByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C) -{ - unsigned int i, istart; - unsigned char *cursrc1; - unsigned char *curdest; - int result; - float tmp, fSrc1, fC; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Special case: C==1 */ - if (C == 1) { - memcpy(Src1, Dest, length); - return true; - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* Routine to process image */ - fC = C / 255.0f; - for (i = istart; i < length; i++) { - fSrc1 = cursrc1[i] / 255.0f; - tmp = fSrc1 * fC; - if (tmp > 1.0f) - tmp = 1.0f; - curdest[i] = (unsigned char) (tmp * 255); - } - - return true; -} - -/*! -\brief Filter using ShiftRightAndMultByByte: D = saturation255((S >> N) * C) - -\param Src1 Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source array. -\param N Number of bit-positions to shift (N). Valid range is 0 to 8. -\param C Constant to multiply with (C). - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterShiftRightAndMultByByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N, - unsigned char C) -{ - unsigned int i, istart; - unsigned char *cursrc1; - unsigned char *curdest; - int result; - float tmp, fSrc1, fC; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Check shift */ - if (N > 8) { - return false; - } - - /* Special case: N==0 && C==1 */ - if ((N == 0) && (C == 1)) { - memcpy(Src1, Dest, length); - return true; - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* Routine to process image */ - fC = C / 255.0f; - for (i = istart; i < length; i++) { - fSrc1 = (cursrc1[i] >> N) / 255.0f; - tmp = fSrc1 * fC; - if (tmp > 1.0f) - tmp = 1.0f; - curdest[i] = (unsigned char) (tmp * 255); - } - - return true; -} - -/*! -\brief Filter using ShiftRight: D = saturation0(S >> N) - -\param Src1 Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. -\param N Number of bit-positions to shift (N). Valid range is 0 to 8. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterShiftRight(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N) -{ - unsigned int i, istart; - unsigned char *cursrc1, *curdest; - int result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Check shift */ - if (N > 8) { - return false; - } - - /* Special case: N==0 */ - if (N == 0) { - memcpy(Src1, Dest, length); - return (0); - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - result = ((int) cursrc1[i]) >> N; - if (result < 0) { - result = 0; - } - curdest[i] = (unsigned char) result; - } - - return true; -} - -/*! -\brief Filter using ShiftLeftByte: D = (S << N) - -\param Src1 Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source arrays. -\param N Number of bit-positions to shift (N). Valid range is 0 to 8. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterShiftLeftByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N) -{ - unsigned int i, istart; - unsigned char *cursrc1, *curdest; - int result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - if (N > 8) { - return (-1); - } - - /* Special case: N==0 */ - if (N == 0) { - memcpy(Src1, Dest, length); - return true; - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - result = ((int) *cursrc1 << N) & 0xff; - *curdest = (unsigned char) result; - /* Advance pointers */ - cursrc1++; - curdest++; - } - - return true; -} - -/*! -\brief Filter using ShiftLeftUint: D = ((uint)S << N) - -\param Src1 Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source array. -\param N Number of bit-positions to shift (N). Valid range is 0 to 32. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterShiftLeftUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned int bpp, unsigned char N) -{ - unsigned int i, istart; - int j; - unsigned char *cursrc1, *curdest; - unsigned int *icursrc1, *icurdest; - unsigned int result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - if (N > 32) { - return false; - } - - /* Special case: N==0 */ - if (N == 0) { - memcpy(Src1, Dest, length); - return true; - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i += bpp) { - if ((i + bpp) < length) { - result = 0; - for (j = bpp; j >= 0; j--) { - result |= (int) ((cursrc1[i + j] << (sizeof(unsigned int) * j))); - } - /* Do the actual uint shift */ - result = result << N; - /* Pass the shifted value to each byte position */ - for (j = 0; j < bpp; j++) { - curdest[i + j] = (result >> bpp) & 0xFF; - } - } - } - - return true; -} - -/*! -\brief Filter ShiftLeft: D = saturation255(S << N) - -\param Src1 Pointer to the start of the source byte array (S1). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source array. -\param N Number of bit-positions to shift (N). Valid range is 0 to 8. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterShiftLeft(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N) -{ - unsigned int i, istart; - unsigned char *cursrc1, *curdest; - int result; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - if (N > 8) { - return false; - } - - /* Special case: N==0 */ - if (N == 0) { - memcpy(Src1, Dest, length); - return true; - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - result = ((int) cursrc1[i]) << N; - if (result > 255) { - result = 255; - } - curdest[i] = (unsigned char) result; - } - - return true; -} - -/*! -\brief Filter using BinarizeUsingThreshold: D = (S >= T) ? 255:0 - -\param Src1 Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source array. -\param T The threshold boundary (inclusive). - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterBinarizeUsingThreshold(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char T) -{ - unsigned int i, istart; - unsigned char *cursrc1; - unsigned char *curdest; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Special case: T==0 */ - if (T == 0) { - memset(Dest, 255, length); - return true; - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* C routine to process image */ - for (i = istart; i < length; i++) { - *curdest = (unsigned char)(((unsigned char)*cursrc1 >= T) ? 255 : 0); - /* Advance pointers */ - cursrc1++; - curdest++; - } - - return true; -} - -/*! -\brief Filter using ClipToRange: D = (S >= Tmin) & (S <= Tmax) S:Tmin | Tmax - -\param Src1 Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source array. -\param Tmin Lower (inclusive) boundary of the clipping range. -\param Tmax Upper (inclusive) boundary of the clipping range. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterClipToRange(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char Tmin, - unsigned char Tmax) -{ - unsigned int i, istart; - unsigned char *cursrc1; - unsigned char *curdest; - - /* Validate input parameters */ - if ((Src1 == NULL) || (Dest == NULL)) - return false; - if (length == 0) - return true; - - /* Special case: Tmin==0 && Tmax = 255 */ - if ((Tmin == 0) && (Tmax == 25)) { - memcpy(Src1, Dest, length); - return true; - } - - /* Setup to process whole image */ - istart = 0; - cursrc1 = Src1; - curdest = Dest; - - /* Routine to process image */ - for (i = istart; i < length; i++) { - if (*cursrc1 < Tmin) { - *curdest = Tmin; - } else if (*cursrc1 > Tmax) { - *curdest = Tmax; - } else { - *curdest = *cursrc1; - } - /* Advance pointers */ - cursrc1++; - curdest++; - } - - return true; -} - -/*! -\brief Filter using NormalizeLinear: D = saturation255((Nmax - Nmin)/(Cmax - Cmin)*(S - Cmin) + Nmin) - -\param Src Pointer to the start of the source byte array (S). -\param Dest Pointer to the start of the destination byte array (D). -\param length The number of bytes in the source array. -\param Cmin Normalization constant. -\param Cmax Normalization constant. -\param Nmin Normalization constant. -\param Nmax Normalization constant. - -\return Returns true for success or false for error. -*/ -bool SDL_imageFilterNormalizeLinear(unsigned char *Src, unsigned char *Dest, unsigned int length, int Cmin, int Cmax, int Nmin, - int Nmax) -{ - unsigned int i, istart; - unsigned char *cursrc; - unsigned char *curdest; - float dN, dC, factor, fCMin, fCMax; - float fNMin, fNMax, fSrc1, tmp; - - /* Validate input parameters */ - if ((Src == NULL) || (Dest == NULL)) - return(-1); - if (length == 0) - return(0); - - /* Setup to process whole image */ - istart = 0; - cursrc = Src; - curdest = Dest; - - /* Routine to process image */ - fCMin = Cmin / 255.0f; - fCMax = Cmax / 255.0f; - fNMin = Nmin / 255.0f; - fNMax = Nmax / 255.0f; - - dC = fCMax - fCMin; - if (dC == 0) - return true; - dN = fNMax - fNMin; - factor = dN / dC; - for (i = istart; i < length; i++) { - fSrc1 = cursrc[i] / 255.0f; - tmp = (factor * (fSrc1 - fCMin)) + fNMin; - if (tmp > 1.0f) - tmp = 1.0f; - curdest[i] = (unsigned char) (tmp * 255); - } - - return true; -} - -/* ------------------------------------------------------------------------------------ */ - -/*! -\brief Filter using ConvolveKernel3x3Divide: Dij = saturation0and255( ... ) - -\param Src The source 2D byte array to convolve. Should be different from destination. -\param Dest The destination 2D byte array to store the result in. Should be different from source. -\param rows Number of rows in source/destination array. Must be >2. -\param columns Number of columns in source/destination array. Must be >2. -\param Kernel The 2D convolution kernel of size 3x3. -\param Divisor The divisor of the convolution sum. Must be >0. - -Note: No implementation available for this function yet. - -\return Returns true if filter was applied, false otherwise. -*/ -bool SDL_imageFilterConvolveKernel3x3Divide(unsigned char *Src, unsigned char *Dest, int rows, int columns, - signed short *Kernel, unsigned char Divisor) -{ - /* Validate input parameters */ - if ((Src == NULL) || (Dest == NULL) || (Kernel == NULL)) - return false; - - if ((columns < 3) || (rows < 3) || (Divisor == 0)) - return false; - - /* No implementation yet */ - return false; -} - -/*! -\brief Filter using ConvolveKernel5x5Divide: Dij = saturation0and255( ... ) - -\param Src The source 2D byte array to convolve. Should be different from destination. -\param Dest The destination 2D byte array to store the result in. Should be different from source. -\param rows Number of rows in source/destination array. Must be >4. -\param columns Number of columns in source/destination array. Must be >4. -\param Kernel The 2D convolution kernel of size 5x5. -\param Divisor The divisor of the convolution sum. Must be >0. - -Note: No implementation available for this function yet. - -\return Returns true if filter was applied, false otherwise. -*/ -bool SDL_imageFilterConvolveKernel5x5Divide(unsigned char *Src, unsigned char *Dest, int rows, int columns, - signed short *Kernel, unsigned char Divisor) -{ - /* Validate input parameters */ - if ((Src == NULL) || (Dest == NULL) || (Kernel == NULL)) - return false; - - if ((columns < 5) || (rows < 5) || (Divisor == 0)) - return false; - - /* No implementation yet */ - return false; -} - -/*! -\brief Filter using ConvolveKernel7x7Divide: Dij = saturation0and255( ... ) - -\param Src The source 2D byte array to convolve. Should be different from destination. -\param Dest The destination 2D byte array to store the result in. Should be different from source. -\param rows Number of rows in source/destination array. Must be >6. -\param columns Number of columns in source/destination array. Must be >6. -\param Kernel The 2D convolution kernel of size 7x7. -\param Divisor The divisor of the convolution sum. Must be >0. - -Note: No implementation available for this function yet. - -\return Returns true if filter was applied, false otherwise. -*/ -bool SDL_imageFilterConvolveKernel7x7Divide(unsigned char *Src, unsigned char *Dest, int rows, int columns, - signed short *Kernel, unsigned char Divisor) -{ - /* Validate input parameters */ - if ((Src == NULL) || (Dest == NULL) || (Kernel == NULL)) - return false; - - if ((columns < 7) || (rows < 7) || (Divisor == 0)) - return false; - - /* No implementation yet */ - return false; -} - -/*! -\brief Filter using ConvolveKernel9x9Divide: Dij = saturation0and255( ... ) - -\param Src The source 2D byte array to convolve. Should be different from destination. -\param Dest The destination 2D byte array to store the result in. Should be different from source. -\param rows Number of rows in source/destination array. Must be >8. -\param columns Number of columns in source/destination array. Must be >8. -\param Kernel The 2D convolution kernel of size 9x9. -\param Divisor The divisor of the convolution sum. Must be >0. - -Note: No implementation available for this function yet. - -\return Returns true if filter was applied, false otherwise. -*/ -bool SDL_imageFilterConvolveKernel9x9Divide(unsigned char *Src, unsigned char *Dest, int rows, int columns, - signed short *Kernel, unsigned char Divisor) -{ - /* Validate input parameters */ - if ((Src == NULL) || (Dest == NULL) || (Kernel == NULL)) - return false; - - if ((columns < 9) || (rows < 9) || (Divisor == 0)) - return false; - - /* No implementation yet */ - return false; -} - -/*! -\brief Filter using ConvolveKernel3x3ShiftRight: Dij = saturation0and255( ... ) - -\param Src The source 2D byte array to convolve. Should be different from destination. -\param Dest The destination 2D byte array to store the result in. Should be different from source. -\param rows Number of rows in source/destination array. Must be >2. -\param columns Number of columns in source/destination array. Must be >2. -\param Kernel The 2D convolution kernel of size 3x3. -\param NRightShift The number of right bit shifts to apply to the convolution sum. Must be <7. - -Note: No implementation available for this function yet. - -\return Returns true if filter was applied, false otherwise. -*/ -bool SDL_imageFilterConvolveKernel3x3ShiftRight(unsigned char *Src, unsigned char *Dest, int rows, int columns, - signed short *Kernel, unsigned char NRightShift) -{ - /* Validate input parameters */ - if ((Src == NULL) || (Dest == NULL) || (Kernel == NULL)) - return false; - - if ((columns < 3) || (rows < 3) || (NRightShift > 7)) - return false; - - /* No implementation yet */ - return false; -} - -/*! -\brief Filter using ConvolveKernel5x5ShiftRight: Dij = saturation0and255( ... ) - -\param Src The source 2D byte array to convolve. Should be different from destination. -\param Dest The destination 2D byte array to store the result in. Should be different from source. -\param rows Number of rows in source/destination array. Must be >4. -\param columns Number of columns in source/destination array. Must be >4. -\param Kernel The 2D convolution kernel of size 5x5. -\param NRightShift The number of right bit shifts to apply to the convolution sum. Must be <7. - -Note: No implementation available for this function yet. - -\return Returns true if filter was applied, false otherwise. -*/ -bool SDL_imageFilterConvolveKernel5x5ShiftRight(unsigned char *Src, unsigned char *Dest, int rows, int columns, - signed short *Kernel, unsigned char NRightShift) -{ - /* Validate input parameters */ - if ((Src == NULL) || (Dest == NULL) || (Kernel == NULL)) - return false; - - if ((columns < 5) || (rows < 5) || (NRightShift > 7)) - return false; - - /* No implementation yet */ - return false; -} - -/*! -\brief Filter using ConvolveKernel7x7ShiftRight: Dij = saturation0and255( ... ) - -\param Src The source 2D byte array to convolve. Should be different from destination. -\param Dest The destination 2D byte array to store the result in. Should be different from source. -\param rows Number of rows in source/destination array. Must be >6. -\param columns Number of columns in source/destination array. Must be >6. -\param Kernel The 2D convolution kernel of size 7x7. -\param NRightShift The number of right bit shifts to apply to the convolution sum. Must be <7. - -Note: No implementation available for this function yet. - -\return Returns true if filter was applied, false otherwise. -*/ -bool SDL_imageFilterConvolveKernel7x7ShiftRight(unsigned char *Src, unsigned char *Dest, int rows, int columns, - signed short *Kernel, unsigned char NRightShift) -{ - /* Validate input parameters */ - if ((Src == NULL) || (Dest == NULL) || (Kernel == NULL)) - return false; - - if ((columns < 7) || (rows < 7) || (NRightShift > 7)) - return false; - - /* No implementation yet */ - return false; -} - -/*! -\brief Filter using ConvolveKernel9x9ShiftRight: Dij = saturation255( ... ) - -\param Src The source 2D byte array to convolve. Should be different from destination. -\param Dest The destination 2D byte array to store the result in. Should be different from source. -\param rows Number of rows in source/destination array. Must be >8. -\param columns Number of columns in source/destination array. Must be >8. -\param Kernel The 2D convolution kernel of size 9x9. -\param NRightShift The number of right bit shifts to apply to the convolution sum. Must be <7. - -Note: No implementation available for this function yet. - -\return Returns true if filter was applied, false otherwise. -*/ -bool SDL_imageFilterConvolveKernel9x9ShiftRight(unsigned char *Src, unsigned char *Dest, int rows, int columns, - signed short *Kernel, unsigned char NRightShift) -{ - /* Validate input parameters */ - if ((Src == NULL) || (Dest == NULL) || (Kernel == NULL)) - return false; - - if ((columns < 9) || (rows < 9) || (NRightShift > 7)) - return false; - - /* No implementation yet */ - return false; -} - -/* ------------------------------------------------------------------------------------ */ - -/*! -\brief Filter using SobelX: Dij = saturation255( ... ) - -\param Src The source 2D byte array to sobel-filter. Should be different from destination. -\param Dest The destination 2D byte array to store the result in. Should be different from source. -\param rows Number of rows in source/destination array. Must be >2. -\param columns Number of columns in source/destination array. Must be >7. - -Note: No implementation available for this function yet. - -\return Returns true if filter was applied, false otherwise. -*/ -bool SDL_imageFilterSobelX(unsigned char *Src, unsigned char *Dest, int rows, int columns) -{ - /* Validate input parameters */ - if ((Src == NULL) || (Dest == NULL)) - return false; - - if ((columns < 8) || (rows < 3)) - return false; - - /* No implementation yet */ - return false; -} - -/*! -\brief Filter using SobelXShiftRight: Dij = saturation255( ... ) - -\param Src The source 2D byte array to sobel-filter. Should be different from destination. -\param Dest The destination 2D byte array to store the result in. Should be different from source. -\param rows Number of rows in source/destination array. Must be >2. -\param columns Number of columns in source/destination array. Must be >8. -\param NRightShift The number of right bit shifts to apply to the filter sum. Must be <7. - -Note: No implementation available for this function yet. - -\return Returns true if filter was applied, false otherwise. -*/ -bool SDL_imageFilterSobelXShiftRight(unsigned char *Src, unsigned char *Dest, int rows, int columns, - unsigned char NRightShift) -{ - /* Validate input parameters */ - if ((Src == NULL) || (Dest == NULL)) - return false; - if ((columns < 8) || (rows < 3) || (NRightShift > 7)) - return false; - - /* No implementation yet */ - return false; -} diff --git a/src/ogfx/vendor/sdl3_gfx/SDL3_imageFilter.h b/src/ogfx/vendor/sdl3_gfx/SDL3_imageFilter.h deleted file mode 100644 index 44edca7..0000000 --- a/src/ogfx/vendor/sdl3_gfx/SDL3_imageFilter.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - -SDL3_imageFilter.h: byte-image "filter" routines - -Copyright (C) 2012-2014 Andreas Schiffler - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. - -Andreas Schiffler -- aschiffler at ferzkopp dot net - -*/ - -#ifndef _SDL3_imageFilter_h -#define _SDL3_imageFilter_h - -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - - /* ---- Function Prototypes */ - -#ifdef _MSC_VER -# if defined(DLL_EXPORT) && !defined(LIBSDL3_GFX_DLL_IMPORT) -# define SDL3_IMAGEFILTER_SCOPE __declspec(dllexport) -# else -# ifdef LIBSDL3_GFX_DLL_IMPORT -# define SDL3_IMAGEFILTER_SCOPE __declspec(dllimport) -# endif -# endif -#endif -#ifndef SDL3_IMAGEFILTER_SCOPE -# define SDL3_IMAGEFILTER_SCOPE extern -#endif - - /* Comments: */ - /* 1.) Convolution routines are not implemented at this time. */ - - // - // All routines return: - // true OK - // false Error (internal error, parameter error) - // - - // SDL_imageFilterAdd: D = saturation255(S1 + S2) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterAdd(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length); - - // SDL_imageFilterMean: D = S1/2 + S2/2 - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterMean(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length); - - // SDL_imageFilterSub: D = saturation0(S1 - S2) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterSub(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length); - - // SDL_imageFilterAbsDiff: D = | S1 - S2 | - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterAbsDiff(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length); - - // SDL_imageFilterMult: D = saturation(S1 * S2) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterMult(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length); - - // SDL_imageFilterMultUnbound: D = S1 * S2 unbound - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterMultUnbound(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length); - - // SDL_imageFilterMultInv: D = 255 - ((255 - S1) * (255 - S2)) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterMultInv(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length); - - // SDL_imageFilterMultDivby2: D = saturation255(S1/2 * S2) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterMultDivby2(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, - unsigned int length); - - // SDL_imageFilterMultDivby4: D = saturation255(S1/2 * S2/2) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterMultDivby4(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, - unsigned int length); - - // SDL_imageFilterBitAnd: D = S1 & S2 - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterBitAnd(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length); - - // SDL_imageFilterBitOr: D = S1 | S2 - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterBitOr(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length); - - // SDL_imageFilterDiv: D = S1 / S2 - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterDiv(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length); - - // SDL_imageFilterBitNegation: D = !S - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterBitNegation(unsigned char *Src1, unsigned char *Dest, unsigned int length); - - // SDL_imageFilterAddByte: D = saturation255(S + C) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterAddByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C); - - // SDL_imageFilterAddUint: D = saturation255(S + (uint)C) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterAddUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned int bpp, unsigned int C); - - // SDL_imageFilterAddByteToHalf: D = saturation255(S/2 + C) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterAddByteToHalf(unsigned char *Src1, unsigned char *Dest, unsigned int length, - unsigned char C); - - // SDL_imageFilterSubByte: D = saturation0(S - C) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterSubByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C); - - // SDL_imageFilterSubUint: D = saturation0(S - (uint)C) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterSubUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned int bpp, unsigned int C); - - // SDL_imageFilterShiftRight: D = saturation0(S >> N) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterShiftRight(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N); - - // SDL_imageFilterShiftRightUint: D = saturation0((uint)S >> N) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterShiftRightUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, - unsigned int bpp, unsigned char N); - - // SDL_imageFilterMultByByte: D = saturation255(S * C) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterMultByByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C); - - // SDL_imageFilterShiftRightAndMultByByte: D = saturation255((S >> N) * C) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterShiftRightAndMultByByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, - unsigned char N, unsigned char C); - - // SDL_imageFilterShiftLeftByte: D = (S << N) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterShiftLeftByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, - unsigned char N); - - // SDL_imageFilterShiftLeftUint: D = ((uint)S << N) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterShiftLeftUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, - unsigned int bpp, unsigned char N); - - // SDL_imageFilterShiftLeft: D = saturation255(S << N) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterShiftLeft(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N); - - // SDL_imageFilterBinarizeUsingThreshold: D = S >= T ? 255:0 - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterBinarizeUsingThreshold(unsigned char *Src1, unsigned char *Dest, unsigned int length, - unsigned char T); - - // SDL_imageFilterClipToRange: D = (S >= Tmin) & (S <= Tmax) 255:0 - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterClipToRange(unsigned char *Src1, unsigned char *Dest, unsigned int length, - unsigned char Tmin, unsigned char Tmax); - - // SDL_imageFilterNormalizeLinear: D = saturation255((Nmax - Nmin)/(Cmax - Cmin)*(S - Cmin) + Nmin) - SDL3_IMAGEFILTER_SCOPE bool SDL_imageFilterNormalizeLinear(unsigned char *Src, unsigned char *Dest, unsigned int length, int Cmin, - int Cmax, int Nmin, int Nmax); - - /* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif - -#endif /* _SDL3_imageFilter_h */ diff --git a/src/ogfx/vendor/sdl3_gfx/SDL3_rotozoom.c b/src/ogfx/vendor/sdl3_gfx/SDL3_rotozoom.c deleted file mode 100644 index 0ba72ac..0000000 --- a/src/ogfx/vendor/sdl3_gfx/SDL3_rotozoom.c +++ /dev/null @@ -1,1636 +0,0 @@ -/* - -SDL3_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces - -Copyright (C) 2012-2014 Andreas Schiffler - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. - -Andreas Schiffler -- aschiffler at ferzkopp dot net - -*/ - -#ifdef WIN32 -#include -#endif - -#include -#include - -#include "SDL3_rotozoom.h" - -/*! -\brief Returns maximum of two numbers a and b. -*/ -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) - -/*! -\brief Number of guard rows added to destination surfaces. - -This is a simple but effective workaround for observed issues. -These rows allocate extra memory and are then hidden from the surface. -Rows are added to the end of destination surfaces when they are allocated. -This catches any potential overflows which seem to happen with -just the right src image dimensions and scale/rotation and can lead -to a situation where the program can segfault. -*/ -#define GUARD_ROWS (2) - -/*! -\brief Lower limit of absolute zoom factor or rotation degrees. -*/ -#define VALUE_LIMIT 0.001 - -/*! -\brief Returns colorkey info for a surface -*/ -Uint32 _colorkey(SDL_Surface *src) -{ - Uint32 key = 0; - SDL_GetSurfaceColorKey(src, &key); - return key; -} - - -/*! -\brief Internal 32 bit integer-factor averaging Shrinker. - -Shrinks 32 bit RGBA/ABGR 'src' surface to 'dst' surface. -Averages color and alpha values values of src pixels to calculate dst pixels. -Assumes src and dst surfaces are of 32 bit depth. -Assumes dst surface was allocated with the correct dimensions. - -\param src The surface to shrink (input). -\param dst The shrunken surface (output). -\param factorx The horizontal shrinking ratio. -\param factory The vertical shrinking ratio. - -\return 0 for success or -1 for error. -*/ -int _shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory) -{ - int x, y, dx, dy, dgap, ra, ga, ba, aa; - int n_average; - SDL_Color *sp, *osp, *oosp; - SDL_Color *dp; - - /* - * Averaging integer shrink - */ - - /* Precalculate division factor */ - n_average = factorx*factory; - - /* - * Scan destination - */ - sp = (SDL_Color *) src->pixels; - - dp = (SDL_Color *) dst->pixels; - dgap = dst->pitch - dst->w * 4; - - for (y = 0; y < dst->h; y++) { - - osp=sp; - for (x = 0; x < dst->w; x++) { - - /* Trace out source box and accumulate */ - oosp=sp; - ra=ga=ba=aa=0; - for (dy=0; dy < factory; dy++) { - for (dx=0; dx < factorx; dx++) { - ra += sp->r; - ga += sp->g; - ba += sp->b; - aa += sp->a; - - sp++; - } - /* src dx loop */ - sp = (SDL_Color *)((Uint8*)sp + (src->pitch - 4*factorx)); // next y - } - /* src dy loop */ - - /* next box-x */ - sp = (SDL_Color *)((Uint8*)oosp + 4*factorx); - - /* Store result in destination */ - dp->r = ra/n_average; - dp->g = ga/n_average; - dp->b = ba/n_average; - dp->a = aa/n_average; - - /* - * Advance destination pointer - */ - dp++; - } - /* dst x loop */ - - /* next box-y */ - sp = (SDL_Color *)((Uint8*)osp + src->pitch*factory); - - /* - * Advance destination pointers - */ - dp = (SDL_Color *) ((Uint8 *) dp + dgap); - } - /* dst y loop */ - - return (0); -} - -/*! -\brief Internal 8 bit integer-factor averaging shrinker. - -Shrinks 8bit Y 'src' surface to 'dst' surface. -Averages color (brightness) values values of src pixels to calculate dst pixels. -Assumes src and dst surfaces are of 8 bit depth. -Assumes dst surface was allocated with the correct dimensions. - -\param src The surface to shrink (input). -\param dst The shrunken surface (output). -\param factorx The horizontal shrinking ratio. -\param factory The vertical shrinking ratio. - -\return 0 for success or -1 for error. -*/ -int _shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory) -{ - int x, y, dx, dy, dgap, a; - int n_average; - Uint8 *sp, *osp, *oosp; - Uint8 *dp; - - /* - * Averaging integer shrink - */ - - /* Precalculate division factor */ - n_average = factorx*factory; - - /* - * Scan destination - */ - sp = (Uint8 *) src->pixels; - - dp = (Uint8 *) dst->pixels; - dgap = dst->pitch - dst->w; - - for (y = 0; y < dst->h; y++) { - - osp=sp; - for (x = 0; x < dst->w; x++) { - - /* Trace out source box and accumulate */ - oosp=sp; - a=0; - for (dy=0; dy < factory; dy++) { - for (dx=0; dx < factorx; dx++) { - a += (*sp); - /* next x */ - sp++; - } - /* end src dx loop */ - /* next y */ - sp = (Uint8 *)((Uint8*)sp + (src->pitch - factorx)); - } - /* end src dy loop */ - - /* next box-x */ - sp = (Uint8 *)((Uint8*)oosp + factorx); - - /* Store result in destination */ - *dp = a/n_average; - - /* - * Advance destination pointer - */ - dp++; - } - /* end dst x loop */ - - /* next box-y */ - sp = (Uint8 *)((Uint8*)osp + src->pitch*factory); - - /* - * Advance destination pointers - */ - dp = (Uint8 *)((Uint8 *)dp + dgap); - } - /* end dst y loop */ - - return (0); -} - -/*! -\brief Internal 32 bit Zoomer with optional anti-aliasing by bilinear interpolation. - -Zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface. -Assumes src and dst surfaces are of 32 bit depth. -Assumes dst surface was allocated with the correct dimensions. - -\param src The surface to zoom (input). -\param dst The zoomed surface (output). -\param flipx Flag indicating if the image should be horizontally flipped. -\param flipy Flag indicating if the image should be vertically flipped. -\param smooth Antialiasing flag; set to SMOOTHING_ON to enable. - -\return 0 for success or -1 for error. -*/ -int _zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy, int smooth) -{ - int x, y, sx, sy, ssx, ssy, *sax, *say, *csax, *csay, *salast, csx, csy, ex, ey, cx, cy, sstep, sstepx, sstepy; - SDL_Color *c00, *c01, *c10, *c11; - SDL_Color *sp, *csp, *dp; - int spixelgap, spixelw, spixelh, dgap, t1, t2; - - /* - * Allocate memory for row/column increments - */ - if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) { - return (-1); - } - if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) { - free(sax); - return (-1); - } - - /* - * Precalculate row increments - */ - spixelw = (src->w - 1); - spixelh = (src->h - 1); - if (smooth) { - sx = (int) (65536.0 * (float) spixelw / (float) (dst->w - 1)); - sy = (int) (65536.0 * (float) spixelh / (float) (dst->h - 1)); - } else { - sx = (int) (65536.0 * (float) (src->w) / (float) (dst->w)); - sy = (int) (65536.0 * (float) (src->h) / (float) (dst->h)); - } - - /* Maximum scaled source size */ - ssx = (src->w << 16) - 1; - ssy = (src->h << 16) - 1; - - /* Precalculate horizontal row increments */ - csx = 0; - csax = sax; - for (x = 0; x <= dst->w; x++) { - *csax = csx; - csax++; - csx += sx; - - /* Guard from overflows */ - if (csx > ssx) { - csx = ssx; - } - } - - /* Precalculate vertical row increments */ - csy = 0; - csay = say; - for (y = 0; y <= dst->h; y++) { - *csay = csy; - csay++; - csy += sy; - - /* Guard from overflows */ - if (csy > ssy) { - csy = ssy; - } - } - - sp = (SDL_Color *) src->pixels; - dp = (SDL_Color *) dst->pixels; - dgap = dst->pitch - dst->w * 4; - spixelgap = src->pitch/4; - - if (flipx) sp += spixelw; - if (flipy) sp += (spixelgap * spixelh); - - /* - * Switch between interpolating and non-interpolating code - */ - if (smooth) { - - /* - * Interpolating Zoom - */ - csay = say; - for (y = 0; y < dst->h; y++) { - csp = sp; - csax = sax; - for (x = 0; x < dst->w; x++) { - /* - * Setup color source pointers - */ - ex = (*csax & 0xffff); - ey = (*csay & 0xffff); - cx = (*csax >> 16); - cy = (*csay >> 16); - sstepx = cx < spixelw; - sstepy = cy < spixelh; - c00 = sp; - c01 = sp; - c10 = sp; - if (sstepy) { - if (flipy) { - c10 -= spixelgap; - } else { - c10 += spixelgap; - } - } - c11 = c10; - if (sstepx) { - if (flipx) { - c01--; - c11--; - } else { - c01++; - c11++; - } - } - - /* - * Draw and interpolate colors - */ - t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff; - t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff; - dp->r = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff; - t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff; - dp->g = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff; - t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff; - dp->b = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff; - t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff; - dp->a = (((t2 - t1) * ey) >> 16) + t1; - /* - * Advance source pointer x - */ - salast = csax; - csax++; - sstep = (*csax >> 16) - (*salast >> 16); - if (flipx) { - sp -= sstep; - } else { - sp += sstep; - } - - /* - * Advance destination pointer x - */ - dp++; - } - /* - * Advance source pointer y - */ - salast = csay; - csay++; - sstep = (*csay >> 16) - (*salast >> 16); - sstep *= spixelgap; - if (flipy) { - sp = csp - sstep; - } else { - sp = csp + sstep; - } - - /* - * Advance destination pointer y - */ - dp = (SDL_Color *) ((Uint8 *) dp + dgap); - } - } else { - /* - * Non-Interpolating Zoom - */ - csay = say; - for (y = 0; y < dst->h; y++) { - csp = sp; - csax = sax; - for (x = 0; x < dst->w; x++) { - /* - * Draw - */ - *dp = *sp; - - /* - * Advance source pointer x - */ - salast = csax; - csax++; - sstep = (*csax >> 16) - (*salast >> 16); - if (flipx) sstep = -sstep; - sp += sstep; - - /* - * Advance destination pointer x - */ - dp++; - } - /* - * Advance source pointer y - */ - salast = csay; - csay++; - sstep = (*csay >> 16) - (*salast >> 16); - sstep *= spixelgap; - if (flipy) sstep = -sstep; - sp = csp + sstep; - - /* - * Advance destination pointer y - */ - dp = (SDL_Color *) ((Uint8 *) dp + dgap); - } - } - - /* - * Remove temp arrays - */ - free(sax); - free(say); - - return (0); -} - -/*! - -\brief Internal 8 bit Zoomer without smoothing. - -Zooms 8bit palette/Y 'src' surface to 'dst' surface. -Assumes src and dst surfaces are of 8 bit depth. -Assumes dst surface was allocated with the correct dimensions. - -\param src The surface to zoom (input). -\param dst The zoomed surface (output). -\param flipx Flag indicating if the image should be horizontally flipped. -\param flipy Flag indicating if the image should be vertically flipped. - -\return 0 for success or -1 for error. -*/ -int _zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy) -{ - int x, y; - Uint32 *sax, *say, *csax, *csay; - int csx, csy; - Uint8 *sp, *dp, *csp; - int dgap; - - /* - * Allocate memory for row increments - */ - if ((sax = (Uint32 *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) { - return (-1); - } - if ((say = (Uint32 *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) { - free(sax); - return (-1); - } - - /* - * Pointer setup - */ - sp = csp = (Uint8 *) src->pixels; - dp = (Uint8 *) dst->pixels; - dgap = dst->pitch - dst->w; - - if (flipx) csp += (src->w-1); - if (flipy) csp = ( (Uint8*)csp + src->pitch*(src->h-1) ); - - /* - * Precalculate row increments - */ - csx = 0; - csax = sax; - for (x = 0; x < dst->w; x++) { - csx += src->w; - *csax = 0; - while (csx >= dst->w) { - csx -= dst->w; - (*csax)++; - } - (*csax) = (*csax) * (flipx ? -1 : 1); - csax++; - } - csy = 0; - csay = say; - for (y = 0; y < dst->h; y++) { - csy += src->h; - *csay = 0; - while (csy >= dst->h) { - csy -= dst->h; - (*csay)++; - } - (*csay) = (*csay) * (flipy ? -1 : 1); - csay++; - } - - /* - * Draw - */ - csay = say; - for (y = 0; y < dst->h; y++) { - csax = sax; - sp = csp; - for (x = 0; x < dst->w; x++) { - /* - * Draw - */ - *dp = *sp; - /* - * Advance source pointers - */ - sp += (*csax); - csax++; - /* - * Advance destination pointer - */ - dp++; - } - /* - * Advance source pointer (for row) - */ - csp += ((*csay) * src->pitch); - csay++; - - /* - * Advance destination pointers - */ - dp += dgap; - } - - /* - * Remove temp arrays - */ - free(sax); - free(say); - - return (0); -} - -/*! -\brief Internal 32 bit rotozoomer with optional anti-aliasing. - -Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control -parameters by scanning the destination surface and applying optionally anti-aliasing -by bilinear interpolation. -Assumes src and dst surfaces are of 32 bit depth. -Assumes dst surface was allocated with the correct dimensions. - -\param src Source surface. -\param dst Destination surface. -\param cx Horizontal center coordinate. -\param cy Vertical center coordinate. -\param isin Integer version of sine of angle. -\param icos Integer version of cosine of angle. -\param flipx Flag indicating horizontal mirroring should be applied. -\param flipy Flag indicating vertical mirroring should be applied. -\param smooth Flag indicating anti-aliasing should be used. -*/ -void _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth) -{ - int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh; - SDL_Color c00, c01, c10, c11, cswap; - SDL_Color *pc, *sp; - int gap; - - /* - * Variable setup - */ - xd = ((src->w - dst->w) << 15); - yd = ((src->h - dst->h) << 15); - ax = (cx << 16) - (icos * cx); - ay = (cy << 16) - (isin * cx); - sw = src->w - 1; - sh = src->h - 1; - pc = (SDL_Color *) dst->pixels; - gap = dst->pitch - dst->w * 4; - - /* - * Switch between interpolating and non-interpolating code - */ - if (smooth) { - for (y = 0; y < dst->h; y++) { - dy = cy - y; - sdx = (ax + (isin * dy)) + xd; - sdy = (ay - (icos * dy)) + yd; - for (x = 0; x < dst->w; x++) { - dx = (sdx >> 16); - dy = (sdy >> 16); - if (flipx) dx = sw - dx; - if (flipy) dy = sh - dy; - if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) { - sp = (SDL_Color *)src->pixels;; - sp += ((src->pitch/4) * dy); - sp += dx; - c00 = *sp; - sp += 1; - c01 = *sp; - sp += (src->pitch/4); - c11 = *sp; - sp -= 1; - c10 = *sp; - if (flipx) { - cswap = c00; c00=c01; c01=cswap; - cswap = c10; c10=c11; c11=cswap; - } - if (flipy) { - cswap = c00; c00=c10; c10=cswap; - cswap = c01; c01=c11; c11=cswap; - } - /* - * Interpolate colors - */ - ex = (sdx & 0xffff); - ey = (sdy & 0xffff); - t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff; - t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff; - pc->r = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff; - t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff; - pc->g = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff; - t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff; - pc->b = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff; - t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff; - pc->a = (((t2 - t1) * ey) >> 16) + t1; - } - sdx += icos; - sdy += isin; - pc++; - } - pc = (SDL_Color *) ((Uint8 *) pc + gap); - } - } else { - for (y = 0; y < dst->h; y++) { - dy = cy - y; - sdx = (ax + (isin * dy)) + xd; - sdy = (ay - (icos * dy)) + yd; - for (x = 0; x < dst->w; x++) { - dx = (short) (sdx >> 16); - dy = (short) (sdy >> 16); - if (flipx) dx = (src->w-1)-dx; - if (flipy) dy = (src->h-1)-dy; - if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) { - sp = (SDL_Color *) ((Uint8 *) src->pixels + src->pitch * dy); - sp += dx; - *pc = *sp; - } - sdx += icos; - sdy += isin; - pc++; - } - pc = (SDL_Color *) ((Uint8 *) pc + gap); - } - } -} - -/*! - -\brief Rotates and zooms 8 bit palette/Y 'src' surface to 'dst' surface without smoothing. - -Rotates and zooms 8 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control -parameters by scanning the destination surface. -Assumes src and dst surfaces are of 8 bit depth. -Assumes dst surface was allocated with the correct dimensions. - -\param src Source surface. -\param dst Destination surface. -\param cx Horizontal center coordinate. -\param cy Vertical center coordinate. -\param isin Integer version of sine of angle. -\param icos Integer version of cosine of angle. -\param flipx Flag indicating horizontal mirroring should be applied. -\param flipy Flag indicating vertical mirroring should be applied. -*/ -void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy) -{ - int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay; - Uint8 *pc, *sp; - int gap; - - /* - * Variable setup - */ - xd = ((src->w - dst->w) << 15); - yd = ((src->h - dst->h) << 15); - ax = (cx << 16) - (icos * cx); - ay = (cy << 16) - (isin * cx); - pc = (Uint8 *) dst->pixels; - gap = dst->pitch - dst->w; - /* - * Clear surface to colorkey - */ - memset(pc, (int)(_colorkey(src) & 0xff), dst->pitch * dst->h); - /* - * Iterate through destination surface - */ - for (y = 0; y < dst->h; y++) { - dy = cy - y; - sdx = (ax + (isin * dy)) + xd; - sdy = (ay - (icos * dy)) + yd; - for (x = 0; x < dst->w; x++) { - dx = (short) (sdx >> 16); - dy = (short) (sdy >> 16); - if (flipx) dx = (src->w-1)-dx; - if (flipy) dy = (src->h-1)-dy; - if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) { - sp = (Uint8 *) (src->pixels); - sp += (src->pitch * dy + dx); - *pc = *sp; - } - sdx += icos; - sdy += isin; - pc++; - } - pc += gap; - } -} - -/*! -\brief Rotates a 8/16/24/32 bit surface in increments of 90 degrees. - -Specialized 90 degree rotator which rotates a 'src' surface in 90 degree -increments clockwise returning a new surface. Faster than rotozoomer since -no scanning or interpolation takes place. Input surface must be 8/16/24/32 bit. -(code contributed by J. Schiller, improved by C. Allport and A. Schiffler) - -\param src Source surface to rotate. -\param numClockwiseTurns Number of clockwise 90 degree turns to apply to the source. - -\returns The new, rotated surface; or NULL for surfaces with incorrect input format. -*/ -SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns) -{ - int row, col, newWidth, newHeight; - int bpp, bpr; - SDL_Surface* dst; - Uint8* srcBuf; - Uint8* dstBuf; - int normalizedClockwiseTurns; - const SDL_PixelFormatDetails* details; - - /* Has to be a valid surface pointer and be a Nbit surface where n is divisible by 8 */ - if (!src || - !src->format) { - SDL_SetError("NULL source surface or source surface format"); - return NULL; - } - - details = SDL_GetPixelFormatDetails(src->format); - if ((details->bits_per_pixel % 8) != 0) { - SDL_SetError("Invalid source surface bit depth"); - return NULL; - } - - /* normalize numClockwiseTurns */ - normalizedClockwiseTurns = (numClockwiseTurns % 4); - if (normalizedClockwiseTurns < 0) { - normalizedClockwiseTurns += 4; - } - - /* If turns are even, our new width/height will be the same as the source surface */ - if (normalizedClockwiseTurns % 2) { - newWidth = src->h; - newHeight = src->w; - } else { - newWidth = src->w; - newHeight = src->h; - } - - dst = SDL_CreateSurface(newWidth, newHeight, src->format); - if(!dst) { - SDL_SetError("Could not create destination surface"); - return NULL; - } - - if (SDL_MUSTLOCK(src)) { - SDL_LockSurface(src); - } - if (SDL_MUSTLOCK(dst)) { - SDL_LockSurface(dst); - } - - /* Calculate byte-per-pixel */ - bpp = details->bits_per_pixel / 8; - - switch(normalizedClockwiseTurns) { - case 0: /* Make a copy of the surface */ - { - /* Unfortunately SDL_BlitSurface cannot be used to make a copy of the surface - since it does not preserve alpha. */ - - if (src->pitch == dst->pitch) { - /* If the pitch is the same for both surfaces, the memory can be copied all at once. */ - memcpy(dst->pixels, src->pixels, (src->h * src->pitch)); - } - else - { - /* If the pitch differs, copy each row separately */ - srcBuf = (Uint8*)(src->pixels); - dstBuf = (Uint8*)(dst->pixels); - bpr = src->w * bpp; - for (row = 0; row < src->h; row++) { - memcpy(dstBuf, srcBuf, bpr); - srcBuf += src->pitch; - dstBuf += dst->pitch; - } - } - } - break; - - /* rotate clockwise */ - case 1: /* rotated 90 degrees clockwise */ - { - for (row = 0; row < src->h; ++row) { - srcBuf = (Uint8*)(src->pixels) + (row * src->pitch); - dstBuf = (Uint8*)(dst->pixels) + (dst->w - row - 1) * bpp; - for (col = 0; col < src->w; ++col) { - memcpy (dstBuf, srcBuf, bpp); - srcBuf += bpp; - dstBuf += dst->pitch; - } - } - } - break; - - case 2: /* rotated 180 degrees clockwise */ - { - for (row = 0; row < src->h; ++row) { - srcBuf = (Uint8*)(src->pixels) + (row * src->pitch); - dstBuf = (Uint8*)(dst->pixels) + ((dst->h - row - 1) * dst->pitch) + (dst->w - 1) * bpp; - for (col = 0; col < src->w; ++col) { - memcpy (dstBuf, srcBuf, bpp); - srcBuf += bpp; - dstBuf -= bpp; - } - } - } - break; - - case 3: /* rotated 270 degrees clockwise */ - { - for (row = 0; row < src->h; ++row) { - srcBuf = (Uint8*)(src->pixels) + (row * src->pitch); - dstBuf = (Uint8*)(dst->pixels) + (row * bpp) + ((dst->h - 1) * dst->pitch); - for (col = 0; col < src->w; ++col) { - memcpy (dstBuf, srcBuf, bpp); - srcBuf += bpp; - dstBuf -= dst->pitch; - } - } - } - break; - } - /* end switch */ - - if (SDL_MUSTLOCK(src)) { - SDL_UnlockSurface(src); - } - if (SDL_MUSTLOCK(dst)) { - SDL_UnlockSurface(dst); - } - - return dst; -} - - -/*! -\brief Internal target surface sizing function for rotozooms with trig result return. - -\param width The source surface width. -\param height The source surface height. -\param angle The angle to rotate in degrees. -\param zoomx The horizontal scaling factor. -\param zoomy The vertical scaling factor. -\param dstwidth The calculated width of the destination surface. -\param dstheight The calculated height of the destination surface. -\param canglezoom The sine of the angle adjusted by the zoom factor. -\param sanglezoom The cosine of the angle adjusted by the zoom factor. - -*/ -void _rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoomx, double zoomy, - int *dstwidth, int *dstheight, - double *canglezoom, double *sanglezoom) -{ - double x, y, cx, cy, sx, sy; - double radangle; - int dstwidthhalf, dstheighthalf; - - /* - * Determine destination width and height by rotating a centered source box - */ - radangle = angle * (M_PI / 180.0); - *sanglezoom = sin(radangle); - *canglezoom = cos(radangle); - *sanglezoom *= zoomx; - *canglezoom *= zoomy; - x = (double)(width / 2); - y = (double)(height / 2); - cx = *canglezoom * x; - cy = *canglezoom * y; - sx = *sanglezoom * x; - sy = *sanglezoom * y; - - dstwidthhalf = MAX((int) - ceil(MAX(MAX(MAX(fabs(cx + sy), fabs(cx - sy)), fabs(-cx + sy)), fabs(-cx - sy))), 1); - dstheighthalf = MAX((int) - ceil(MAX(MAX(MAX(fabs(sx + cy), fabs(sx - cy)), fabs(-sx + cy)), fabs(-sx - cy))), 1); - *dstwidth = 2 * dstwidthhalf; - *dstheight = 2 * dstheighthalf; -} - -/*! -\brief Returns the size of the resulting target surface for a rotozoomSurfaceXY() call. - -\param width The source surface width. -\param height The source surface height. -\param angle The angle to rotate in degrees. -\param zoomx The horizontal scaling factor. -\param zoomy The vertical scaling factor. -\param dstwidth The calculated width of the rotozoomed destination surface. -\param dstheight The calculated height of the rotozoomed destination surface. -*/ -void rotozoomSurfaceSizeXY(int width, int height, double angle, double zoomx, double zoomy, int *dstwidth, int *dstheight) -{ - double dummy_sanglezoom, dummy_canglezoom; - - _rotozoomSurfaceSizeTrig(width, height, angle, zoomx, zoomy, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom); -} - -/*! -\brief Returns the size of the resulting target surface for a rotozoomSurface() call. - -\param width The source surface width. -\param height The source surface height. -\param angle The angle to rotate in degrees. -\param zoom The scaling factor. -\param dstwidth The calculated width of the rotozoomed destination surface. -\param dstheight The calculated height of the rotozoomed destination surface. -*/ -void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight) -{ - double dummy_sanglezoom, dummy_canglezoom; - - _rotozoomSurfaceSizeTrig(width, height, angle, zoom, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom); -} - -/*! -\brief Rotates and zooms a surface and optional anti-aliasing. - -Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. -'angle' is the rotation in degrees and 'zoom' a scaling factor. If 'smooth' is set -then the destination 32bit surface is anti-aliased. If the surface is not 8bit -or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. - -\param src The surface to rotozoom. -\param angle The angle to rotate in degrees. -\param zoom The scaling factor. -\param smooth Antialiasing flag; set to SMOOTHING_ON to enable. - -\return The new rotozoomed surface. -*/ -SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth) -{ - return rotozoomSurfaceXY(src, angle, zoom, zoom, smooth); -} - -/*! -\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing. - -Rotates and zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface. -'angle' is the rotation in degrees, 'zoomx and 'zoomy' scaling factors. If 'smooth' is set -then the destination 32bit surface is anti-aliased. If the surface is not 8bit -or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. - -\param src The surface to rotozoom. -\param angle The angle to rotate in degrees. -\param zoomx The horizontal scaling factor. -\param zoomy The vertical scaling factor. -\param smooth Antialiasing flag; set to SMOOTHING_ON to enable. - -\return The new rotozoomed surface. -*/ -SDL_Surface *rotozoomSurfaceXY(SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth) -{ - SDL_Surface *rz_src; - SDL_Surface *rz_dst; - double zoominv; - double sanglezoom, canglezoom, sanglezoominv, canglezoominv; - int dstwidthhalf, dstwidth, dstheighthalf, dstheight; - int is32bit; - int i, src_converted; - int flipx,flipy; - const SDL_PixelFormatDetails* details; - SDL_Palette* pal_dst; - SDL_Palette* pal_src; - - /* - * Sanity check - */ - if (src == NULL) { - return (NULL); - } - - /* - * Determine if source surface is 32bit or 8bit - */ - details = SDL_GetPixelFormatDetails(src->format); - is32bit = (details->bits_per_pixel == 32); - if ((is32bit) || (details->bits_per_pixel == 8)) { - /* - * Use source surface 'as is' - */ - rz_src = src; - src_converted = 0; - } else { - /* - * New source surface is 32bit with a defined RGBA ordering - */ - rz_src = - SDL_CreateSurface(src->w, src->h, SDL_PIXELFORMAT_RGBA32); - - SDL_BlitSurface(src, NULL, rz_src, NULL); - - src_converted = 1; - is32bit = 1; - } - - /* - * Sanity check zoom factor - */ - flipx = (zoomx<0.0); - if (flipx) zoomx=-zoomx; - flipy = (zoomy<0.0); - if (flipy) zoomy=-zoomy; - if (zoomx < VALUE_LIMIT) zoomx = VALUE_LIMIT; - if (zoomy < VALUE_LIMIT) zoomy = VALUE_LIMIT; - zoominv = 65536.0 / (zoomx * zoomx); - - /* - * Check if we have a rotozoom or just a zoom - */ - if (fabs(angle) > VALUE_LIMIT) { - - /* - * Angle!=0: full rotozoom - */ - /* - * ----------------------- - */ - - /* Determine target size */ - _rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoomx, zoomy, &dstwidth, &dstheight, &canglezoom, &sanglezoom); - - /* - * Calculate target factors from sin/cos and zoom - */ - sanglezoominv = sanglezoom; - canglezoominv = canglezoom; - sanglezoominv *= zoominv; - canglezoominv *= zoominv; - - /* Calculate half size */ - dstwidthhalf = dstwidth / 2; - dstheighthalf = dstheight / 2; - - /* - * Alloc space to completely contain the rotated surface - */ - rz_dst = NULL; - if (is32bit) { - /* - * Target surface is 32bit with source RGBA/ABGR ordering - */ - rz_dst = - SDL_CreateSurface(dstwidth, dstheight + GUARD_ROWS, rz_src->format); - } else { - /* - * Target surface is 8bit - */ - rz_dst = SDL_CreateSurface(dstwidth, dstheight + GUARD_ROWS, SDL_PIXELFORMAT_INDEX8); - pal_dst = SDL_CreateSurfacePalette(rz_dst); - } - - /* Check target */ - if (rz_dst == NULL) - return NULL; - - /* Adjust for guard rows */ - rz_dst->h = dstheight; - - /* - * Lock source surface - */ - if (SDL_MUSTLOCK(rz_src)) { - SDL_LockSurface(rz_src); - } - - /* - * Check which kind of surface we have - */ - if (is32bit) { - /* - * Call the 32bit transformation routine to do the rotation (using alpha) - */ - _transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf, - (int) (sanglezoominv), (int) (canglezoominv), - flipx, flipy, - smooth); - } else { - /* - * Copy palette and colorkey info - */ - pal_src = SDL_GetSurfacePalette(rz_src); - for (i = 0; i < pal_src->ncolors; i++) { - pal_dst->colors[i] = pal_src->colors[i]; - } - pal_dst->ncolors = pal_src->ncolors; - /* - * Call the 8bit transformation routine to do the rotation - */ - transformSurfaceY(rz_src, rz_dst, dstwidthhalf, dstheighthalf, - (int) (sanglezoominv), (int) (canglezoominv), - flipx, flipy); - } - /* - * Unlock source surface - */ - if (SDL_MUSTLOCK(rz_src)) { - SDL_UnlockSurface(rz_src); - } - - } else { - - /* - * Angle=0: Just a zoom - */ - /* - * -------------------- - */ - - /* - * Calculate target size - */ - zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight); - - /* - * Alloc space to completely contain the zoomed surface - */ - rz_dst = NULL; - if (is32bit) { - /* - * Target surface is 32bit with source RGBA/ABGR ordering - */ - rz_dst = - SDL_CreateSurface(dstwidth, dstheight + GUARD_ROWS, rz_src->format); - } else { - /* - * Target surface is 8bit - */ - rz_dst = SDL_CreateSurface(dstwidth, dstheight + GUARD_ROWS, SDL_PIXELFORMAT_INDEX8); - pal_dst = SDL_CreateSurfacePalette(rz_dst); - } - - /* Check target */ - if (rz_dst == NULL) - return NULL; - - /* Adjust for guard rows */ - rz_dst->h = dstheight; - - /* - * Lock source surface - */ - if (SDL_MUSTLOCK(rz_src)) { - SDL_LockSurface(rz_src); - } - - /* - * Check which kind of surface we have - */ - if (is32bit) { - /* - * Call the 32bit transformation routine to do the zooming (using alpha) - */ - _zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth); - - } else { - /* - * Copy palette and colorkey info - */ - pal_src = SDL_GetSurfacePalette(rz_src); - for (i = 0; i < pal_src->ncolors; i++) { - pal_dst->colors[i] = pal_src->colors[i]; - } - pal_dst->ncolors = pal_src->ncolors; - - /* - * Call the 8bit transformation routine to do the zooming - */ - _zoomSurfaceY(rz_src, rz_dst, flipx, flipy); - } - - /* - * Unlock source surface - */ - if (SDL_MUSTLOCK(rz_src)) { - SDL_UnlockSurface(rz_src); - } - } - - /* - * Cleanup temp surface - */ - if (src_converted) { - SDL_DestroySurface(rz_src); - } - - /* - * Return destination surface - */ - return (rz_dst); -} - -/*! -\brief Calculates the size of the target surface for a zoomSurface() call. - -The minimum size of the target surface is 1. The input factors can be positive or negative. - -\param width The width of the source surface to zoom. -\param height The height of the source surface to zoom. -\param zoomx The horizontal zoom factor. -\param zoomy The vertical zoom factor. -\param dstwidth Pointer to an integer to store the calculated width of the zoomed target surface. -\param dstheight Pointer to an integer to store the calculated height of the zoomed target surface. -*/ -void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight) -{ - /* - * Make zoom factors positive - */ - int flipx, flipy; - flipx = (zoomx<0.0); - if (flipx) zoomx = -zoomx; - flipy = (zoomy<0.0); - if (flipy) zoomy = -zoomy; - - /* - * Sanity check zoom factors - */ - if (zoomx < VALUE_LIMIT) { - zoomx = VALUE_LIMIT; - } - if (zoomy < VALUE_LIMIT) { - zoomy = VALUE_LIMIT; - } - - /* - * Calculate target size - */ - *dstwidth = (int) floor(((double) width * zoomx) + 0.5); - *dstheight = (int) floor(((double) height * zoomy) + 0.5); - if (*dstwidth < 1) { - *dstwidth = 1; - } - if (*dstheight < 1) { - *dstheight = 1; - } -} - -/*! -\brief Zoom a surface by independent horizontal and vertical factors with optional smoothing. - -Zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface. -'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is on -then the destination 32bit surface is anti-aliased. If the surface is not 8bit -or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. -If zoom factors are negative, the image is flipped on the axes. - -\param src The surface to zoom. -\param zoomx The horizontal zoom factor. -\param zoomy The vertical zoom factor. -\param smooth Antialiasing flag; set to SMOOTHING_ON to enable. - -\return The new, zoomed surface. -*/ -SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth) -{ - SDL_Surface *rz_src; - SDL_Surface *rz_dst; - int dstwidth, dstheight; - int is32bit; - int i, src_converted; - int flipx, flipy; - const SDL_PixelFormatDetails* details; - SDL_Palette* pal_src; - SDL_Palette* pal_dst; - - /* - * Sanity check - */ - if (src == NULL) - return (NULL); - - /* - * Determine if source surface is 32bit or 8bit - */ - details = SDL_GetPixelFormatDetails(src->format); - is32bit = (details->bits_per_pixel == 32); - if ((is32bit) || (details->bits_per_pixel == 8)) { - /* - * Use source surface 'as is' - */ - rz_src = src; - src_converted = 0; - } else { - /* - * New source surface is 32bit with a defined RGBA ordering - */ - rz_src = - SDL_CreateSurface(src->w, src->h, SDL_PIXELFORMAT_RGBA32); - if (rz_src == NULL) { - return NULL; - } - SDL_BlitSurface(src, NULL, rz_src, NULL); - src_converted = 1; - is32bit = 1; - } - - flipx = (zoomx<0.0); - if (flipx) zoomx = -zoomx; - flipy = (zoomy<0.0); - if (flipy) zoomy = -zoomy; - - /* Get size if target */ - zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight); - - /* - * Alloc space to completely contain the zoomed surface - */ - rz_dst = NULL; - if (is32bit) { - /* - * Target surface is 32bit with source RGBA/ABGR ordering - */ - rz_dst = - SDL_CreateSurface(dstwidth, dstheight + GUARD_ROWS, rz_src->format); - } else { - /* - * Target surface is 8bit - */ - rz_dst = SDL_CreateSurface(dstwidth, dstheight + GUARD_ROWS, SDL_PIXELFORMAT_INDEX8); - pal_dst = SDL_CreateSurfacePalette(rz_dst); - } - - /* Check target */ - if (rz_dst == NULL) { - /* - * Cleanup temp surface - */ - if (src_converted) { - SDL_DestroySurface(rz_src); - } - return NULL; - } - - /* Adjust for guard rows */ - rz_dst->h = dstheight; - - /* - * Lock source surface - */ - if (SDL_MUSTLOCK(rz_src)) { - SDL_LockSurface(rz_src); - } - - /* - * Check which kind of surface we have - */ - if (is32bit) { - /* - * Call the 32bit transformation routine to do the zooming (using alpha) - */ - _zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth); - } else { - /* - * Copy palette and colorkey info - */ - pal_src = SDL_GetSurfacePalette(rz_src); - for (i = 0; i < pal_src->ncolors; i++) { - pal_dst->colors[i] = pal_src->colors[i]; - } - pal_dst->ncolors = pal_src->ncolors; - /* - * Call the 8bit transformation routine to do the zooming - */ - _zoomSurfaceY(rz_src, rz_dst, flipx, flipy); - } - /* - * Unlock source surface - */ - if (SDL_MUSTLOCK(rz_src)) { - SDL_UnlockSurface(rz_src); - } - - /* - * Cleanup temp surface - */ - if (src_converted) { - SDL_DestroySurface(rz_src); - } - - /* - * Return destination surface - */ - return (rz_dst); -} - -/*! -\brief Shrink a surface by an integer ratio using averaging. - -Shrinks a 32bit or 8bit 'src' surface to a newly created 'dst' surface. -'factorx' and 'factory' are the shrinking ratios (i.e. 2=1/2 the size, -3=1/3 the size, etc.) The destination surface is antialiased by averaging -the source box RGBA or Y information. If the surface is not 8bit -or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. -The input surface is not modified. The output surface is newly allocated. - -\param src The surface to shrink. -\param factorx The horizontal shrinking ratio. -\param factory The vertical shrinking ratio. - -\return The new, shrunken surface. -*/ -/*@null@*/ -SDL_Surface *shrinkSurface(SDL_Surface *src, int factorx, int factory) -{ - int result; - SDL_Surface *rz_src; - SDL_Surface *rz_dst = NULL; - int dstwidth, dstheight; - int is32bit; - int i, src_converted; - int haveError = 0; - const SDL_PixelFormatDetails* details; - SDL_Palette* pal_src; - SDL_Palette* pal_dst; - - /* - * Sanity check - */ - if (src == NULL) { - return (NULL); - } - - /* - * Determine if source surface is 32bit or 8bit - */ - details = SDL_GetPixelFormatDetails(src->format); - is32bit = (details->bits_per_pixel == 32); - if ((is32bit) || (details->bits_per_pixel == 8)) { - /* - * Use source surface 'as is' - */ - rz_src = src; - src_converted = 0; - } else { - /* - * New source surface is 32bit with a defined RGBA ordering - */ - rz_src = SDL_CreateSurface(src->w, src->h, SDL_PIXELFORMAT_RGBA32); - if (rz_src==NULL) { - haveError = 1; - goto exitShrinkSurface; - } - - SDL_BlitSurface(src, NULL, rz_src, NULL); - src_converted = 1; - is32bit = 1; - } - - /* - * Lock the surface - */ - if (SDL_MUSTLOCK(rz_src)) { - if (!SDL_LockSurface(rz_src)) { - haveError = 1; - goto exitShrinkSurface; - } - } - - /* Get size for target */ - dstwidth=rz_src->w/factorx; - while (dstwidth*factorx>rz_src->w) { dstwidth--; } - dstheight=rz_src->h/factory; - while (dstheight*factory>rz_src->h) { dstheight--; } - - /* - * Alloc space to completely contain the shrunken surface - * (with added guard rows) - */ - if (is32bit==1) { - /* - * Target surface is 32bit with source RGBA/ABGR ordering - */ - rz_dst = - SDL_CreateSurface(dstwidth, dstheight + GUARD_ROWS, rz_src->format); - } else { - /* - * Target surface is 8bit - */ - rz_dst = SDL_CreateSurface(dstwidth, dstheight + GUARD_ROWS, SDL_PIXELFORMAT_INDEX8); - pal_dst = SDL_CreateSurfacePalette(rz_dst); - } - - /* Check target */ - if (rz_dst == NULL) { - haveError = 1; - goto exitShrinkSurface; - } - - /* Adjust for guard rows */ - rz_dst->h = dstheight; - - /* - * Check which kind of surface we have - */ - if (is32bit==1) { - /* - * Call the 32bit transformation routine to do the shrinking (using alpha) - */ - result = _shrinkSurfaceRGBA(rz_src, rz_dst, factorx, factory); - if ((result!=0) || (rz_dst==NULL)) { - haveError = 1; - goto exitShrinkSurface; - } - } else { - /* - * Copy palette and colorkey info - */ - pal_src = SDL_GetSurfacePalette(rz_src); - for (i = 0; i < pal_src->ncolors; i++) { - pal_dst->colors[i] = pal_src->colors[i]; - } - pal_dst->ncolors = pal_src->ncolors; - /* - * Call the 8bit transformation routine to do the shrinking - */ - result = _shrinkSurfaceY(rz_src, rz_dst, factorx, factory); - if (result!=0) { - haveError = 1; - goto exitShrinkSurface; - } - } - -exitShrinkSurface: - if (rz_src!=NULL) { - /* - * Unlock source surface - */ - if (SDL_MUSTLOCK(rz_src)) { - SDL_UnlockSurface(rz_src); - } - - /* - * Cleanup temp surface - */ - if (src_converted==1) { - SDL_DestroySurface(rz_src); - } - } - - /* Check error state; maybe need to cleanup destination */ - if (haveError==1) { - if (rz_dst!=NULL) { - SDL_DestroySurface(rz_dst); - } - rz_dst=NULL; - } - - /* - * Return destination surface - */ - return (rz_dst); -} diff --git a/src/ogfx/vendor/sdl3_gfx/SDL3_rotozoom.h b/src/ogfx/vendor/sdl3_gfx/SDL3_rotozoom.h deleted file mode 100644 index 015e119..0000000 --- a/src/ogfx/vendor/sdl3_gfx/SDL3_rotozoom.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - -SDL3_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces - -Copyright (C) 2012-2014 Andreas Schiffler - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. - -Andreas Schiffler -- aschiffler at ferzkopp dot net - -*/ - -#ifndef _SDL3_rotozoom_h -#define _SDL3_rotozoom_h - -#include - -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef M_PI -#define M_PI 3.1415926535897932384626433832795 -#endif - -#include - - /* ---- Defines */ - - /*! - \brief Disable anti-aliasing (no smoothing). - */ -#define SMOOTHING_OFF 0 - - /*! - \brief Enable anti-aliasing (smoothing). - */ -#define SMOOTHING_ON 1 - - /* ---- Function Prototypes */ - -#ifdef _MSC_VER -# if defined(DLL_EXPORT) && !defined(LIBSDL3_GFX_DLL_IMPORT) -# define SDL3_ROTOZOOM_SCOPE __declspec(dllexport) -# else -# ifdef LIBSDL3_GFX_DLL_IMPORT -# define SDL3_ROTOZOOM_SCOPE __declspec(dllimport) -# endif -# endif -#endif -#ifndef SDL3_ROTOZOOM_SCOPE -# define SDL3_ROTOZOOM_SCOPE extern -#endif - - /* - - Rotozoom functions - - */ - - SDL3_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth); - - SDL3_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurfaceXY - (SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth); - - - SDL3_ROTOZOOM_SCOPE void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, - int *dstheight); - - SDL3_ROTOZOOM_SCOPE void rotozoomSurfaceSizeXY - (int width, int height, double angle, double zoomx, double zoomy, - int *dstwidth, int *dstheight); - - /* - - Zooming functions - - */ - - SDL3_ROTOZOOM_SCOPE SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth); - - SDL3_ROTOZOOM_SCOPE void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight); - - /* - - Shrinking functions - - */ - - SDL3_ROTOZOOM_SCOPE SDL_Surface *shrinkSurface(SDL_Surface * src, int factorx, int factory); - - /* - - Specialized rotation functions - - */ - - SDL3_ROTOZOOM_SCOPE SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns); - - /* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif - -#endif /* _SDL3_rotozoom_h */ diff --git a/src/ostd/data/Color.cpp b/src/ostd/data/Color.cpp index 902c2e5..a34a7fa 100755 --- a/src/ostd/data/Color.cpp +++ b/src/ostd/data/Color.cpp @@ -5,47 +5,47 @@ namespace ostd { - Color::Color(void) + Color::Color(void) : r(*this), g(*this), b(*this), a(*this) { set(); setTypeName("ox::Color"); BaseObject::setValid(true); } - Color::Color(uint8_t rgb_single_value, uint8_t alpha) + Color::Color(uint8_t rgb_single_value, uint8_t alpha) : r(*this), g(*this), b(*this), a(*this) { set(rgb_single_value, alpha); setTypeName("ox::Color"); BaseObject::setValid(true); } - Color::Color(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t alpha) + Color::Color(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t alpha) : r(*this), g(*this), b(*this), a(*this) { set(_r, _g, _b, alpha); setTypeName("ox::Color"); BaseObject::setValid(true); } - Color::Color(const String& color_string) + Color::Color(const String& color_string) : r(*this), g(*this), b(*this), a(*this) { set(color_string); setTypeName("ox::Color"); BaseObject::setValid(true); } - Color::Color(const FloatCol& normalized_color) + Color::Color(const FloatCol& normalized_color) : r(*this), g(*this), b(*this), a(*this) { set(normalized_color); setTypeName("ox::Color"); BaseObject::setValid(true); } - Color::Color(const Color& copy) : BaseObject(copy) + Color::Color(const Color& copy) : BaseObject(copy), r(*this), g(*this), b(*this), a(*this) { - r = copy.r; - g = copy.g; - b = copy.b; - a = copy.a; + r = static_cast(copy.r); + g = static_cast(copy.g); + b = static_cast(copy.b); + a = static_cast(copy.a); } bool Color::operator==(const Color& col2) @@ -61,10 +61,10 @@ namespace ostd Color& Color::operator=(const Color& copy) { BaseObject::operator=(copy); - r = copy.r; - g = copy.g; - b = copy.b; - a = copy.a; + r = static_cast(copy.r); + g = static_cast(copy.g); + b = static_cast(copy.b); + a = static_cast(copy.a); return *this; } @@ -99,7 +99,9 @@ namespace ostd { String se(color_string); se.trim(); - r = g = b = 0; + r = 0; + g = 0; + b = 0; a = 255; if (se.startsWith("#")) { @@ -204,7 +206,17 @@ namespace ostd Color::FloatCol Color::getNormalizedColor(void) const { - return { r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f }; + if (m_dirty) + { + m_cachedFloat = { + r.value * (1.0f / 255.0f), + g.value * (1.0f / 255.0f), + b.value * (1.0f / 255.0f), + a.value * (1.0f / 255.0f) + }; + m_dirty = false; + } + return m_cachedFloat; } String Color::toString(void) const diff --git a/src/ostd/data/Color.hpp b/src/ostd/data/Color.hpp index a9c591e..8ba44f8 100755 --- a/src/ostd/data/Color.hpp +++ b/src/ostd/data/Color.hpp @@ -39,6 +39,20 @@ namespace ostd FloatCol(void) : r(0.0f), g(0.0f), b(0.0f), a(1.0f) { } FloatCol(float _r, float _g, float _b, float _a) : r(_r), g(_g), b(_b), a(_a) { } }; + public: struct Channel + { + uint8_t value; + Color& parent; + + inline Channel(Color& _parent) : parent(_parent) { value = 0; } + inline operator uint8_t() const { return value; } + inline Channel& operator=(uint8_t v) + { + value = v; + parent.m_dirty = true; + return *this; + } + }; public: enum class eColorFormat { RGBA = 0, ARGB }; @@ -74,10 +88,14 @@ namespace ostd static void HSVtoRGB(float h, float s, float v, float& r, float& g, float& b); public: - uint8_t r; - uint8_t g; - uint8_t b; - uint8_t a; + Channel r; + Channel g; + Channel b; + Channel a; + + private: + mutable bool m_dirty { true }; + mutable FloatCol m_cachedFloat { 0, 0, 0, 0 }; public: }; diff --git a/src/ostd/io/IOHandlers.hpp b/src/ostd/io/IOHandlers.hpp index d55841c..baf9a4b 100644 --- a/src/ostd/io/IOHandlers.hpp +++ b/src/ostd/io/IOHandlers.hpp @@ -28,7 +28,6 @@ namespace ogfx { class WindowCore; - class BasicRenderer2D; }; namespace ostd diff --git a/src/ostd/io/Json.cpp b/src/ostd/io/Json.cpp index f0931a9..122cc83 100644 --- a/src/ostd/io/Json.cpp +++ b/src/ostd/io/Json.cpp @@ -318,10 +318,10 @@ namespace ostd try { json arr = json::array(); - arr.push_back(value.r); - arr.push_back(value.g); - arr.push_back(value.b); - if (value.a != 255) arr.push_back(value.a); + arr.push_back(static_cast(value.r)); + arr.push_back(static_cast(value.g)); + arr.push_back(static_cast(value.b)); + if (value.a != 255) arr.push_back(static_cast(value.a)); root[p] = arr; return true; } catch (...) { return false; } diff --git a/src/ostd/math/Geometry.hpp b/src/ostd/math/Geometry.hpp index 3e9640e..494469e 100755 --- a/src/ostd/math/Geometry.hpp +++ b/src/ostd/math/Geometry.hpp @@ -45,40 +45,6 @@ namespace ostd { - template - class Point : public __i_stringeable - { - public: - T x; - T y; - - public: - inline Point(void) : x(0), y(0) {} - inline Point(T xx, T yy) : x(xx), y(yy) {} - - inline bool operator==(const Point& op2 ) const { return (x == op2.x && y == op2.y); } - inline bool operator!=(const Point& op2 ) const { return (x != op2.x || y != op2.y); } - - template inline Point(Point copy) - { - x = (T2)(copy.x); - y = (T2)(copy.y); - } - - inline String toString(void) const override { return String("{ ").add(x).add(", ").add(y).add(" }"); } - }; - - typedef Point FPoint; - typedef Point DPoint; - typedef Point UIPoint; - typedef Point UI64Point; - typedef Point UI16Point; - typedef Point UI8Point; - typedef Point IPoint; - typedef Point I64Point; - typedef Point I16Point; - typedef Point I8Point; - struct Vec2 : public __i_stringeable { //======================== Data ======================== @@ -146,6 +112,7 @@ namespace ostd //===================== Operators ====================== inline bool operator==(const Vec2& op2 ) const { return (x == op2.x && y == op2.y); } inline bool operator!=(const Vec2& op2 ) const { return (x != op2.x || y != op2.y); } + inline Vec2 operator-() const { return { -x, -y }; } inline Vec2 operator+ (const Vec2& op2 ) const { return add(op2); } inline Vec2 operator- (const Vec2& op2 ) const { return sub(op2); } inline Vec2 operator+ (const float& op2) const { return add(op2, op2); } @@ -167,6 +134,62 @@ namespace ostd }; + template + class Point : public __i_stringeable + { + public: + T x; + T y; + + public: + inline Point(void) : x(0), y(0) { } + inline Point(T xx, T yy) : x(xx), y(yy) {} + inline Point(const Vec2& vec) { x = vec.x; y = vec.y; } + inline Point& set(const Point& v2) { x = v2.x; y = v2.y; return *this; } + inline Point& set(float xx, float yy) { x = xx; y = yy; return *this; } + + //===================== Operators ====================== + inline bool operator==(const Point& op2 ) const { return (x == op2.x && y == op2.y); } + inline bool operator!=(const Point& op2 ) const { return (x != op2.x || y != op2.y); } + inline operator Vec2() const { return { static_cast(x), static_cast(y) }; } + inline Point operator+ (const Point& op2 ) const { return { x + op2.x, y + op2.y }; } + inline Point operator- (const Point& op2 ) const { return { x - op2.x, y - op2.y }; } + inline Point operator+ (const T& op2) const { return { x + op2, y + op2 }; } + inline Point operator- (const T& op2) const { return { x + op2, y + op2 }; } + inline Point operator* (const T& op2) const { return { x * op2, y * op2 }; } + inline Point operator/ (const T& op2) const { return { x / op2, y / op2 }; } + inline Point& operator= (const Point& val ) { return set(val); } + inline Point& operator= (const T& val) { return set(val, val); } + inline Point& operator+=(const Point& op2 ) { x += op2.x; y += op2.y; return *this; } + inline Point& operator-=(const Point& op2 ) { x -= op2.x; y -= op2.y; return *this; } + inline Point& operator+=(const T& op2) { x += op2; y += op2; return *this;; } + inline Point& operator-=(const T& op2) { x -= op2; y -= op2; return *this; } + inline Point& operator*=(const T& op2) { return x *= op2; y *= op2; return *this; } + inline Point& operator/=(const T& op2) { return x /= op2; y /= op2; return *this; } + //====================================================== + + template inline Point(Point copy) + { + x = (T2)(copy.x); + y = (T2)(copy.y); + } + + inline Vec2 asVec2(void) const { return { static_cast(x), static_cast(y) }; } + + inline String toString(void) const override { return String("{ ").add(x).add(", ").add(y).add(" }"); } + }; + + typedef Point FPoint; + typedef Point DPoint; + typedef Point UIPoint; + typedef Point UI64Point; + typedef Point UI16Point; + typedef Point UI8Point; + typedef Point IPoint; + typedef Point I64Point; + typedef Point I16Point; + typedef Point I8Point; + struct Vec3 : public __i_stringeable { inline Vec3(float xx = 0, float yy = 0, float zz = 0) diff --git a/src/test/GraphicsWindowTest.cpp b/src/test/GraphicsWindowTest.cpp index 38a37fd..e94fec5 100644 --- a/src/test/GraphicsWindowTest.cpp +++ b/src/test/GraphicsWindowTest.cpp @@ -26,20 +26,11 @@ ostd::ConsoleOutputHandler out; class Window : public ogfx::GraphicsWindow { public: - inline Window(void) : m_sigHandler(m_textInput, *this) { } + inline Window(void) { } inline void onInitialize(void) override { connectSignal(ogfx::gui::RawTextInput::actionEventSignalID); - m_gfx.init(*this); - m_gfx.setFont("res/ttf/Courier Prime.ttf"); - - float w = getWindowWidth(); - float h = 40.0f; - m_textInput.create({ 0.0f, (float)(getWindowHeight() - h) }, { w, h }, "MainInputTXT"); - m_textInput.setEventListener(m_sigHandler); - // m_textInput.setCharacterFilter(m_numCharFilter); - m_textInput.getTheme().extraPaddingTop = 3; } inline void handleSignal(ostd::Signal& signal) override @@ -50,44 +41,30 @@ class Window : public ogfx::GraphicsWindow if (evtData.keyCode == ogfx::KeyCode::Escape) close(); } - if (signal.ID == ogfx::gui::RawTextInput::actionEventSignalID) - { - auto& data = (ogfx::gui::RawTextInput::ActionEventData&)signal.userData; - if (data.senderName != "MainInputTXT") - return; - if (data.eventType == ogfx::gui::RawTextInput::eActionEventType::Enter) - { - out().fg(ostd::ConsoleColors::Green).p(data.sender.getText()).reset().nl(); - data.sender.setText(""); - } - else if (data.eventType == ogfx::gui::RawTextInput::eActionEventType::Tab) - { - out().fg(ostd::ConsoleColors::Red).p("TAB").reset().nl(); - data.sender.appendText("TAB"); - } - } } inline void onRender(void) override { - m_textInput.render(m_gfx); + auto l_rndPoint = [&](void) -> ostd::FPoint { + using rnd = ostd::Random; + return rnd::getVec2({ 0, (float)getWindowWidth() }, { 0, (float)getWindowHeight() }); + }; + for (int32_t i = 0; i < 10000; i++) + m_gfx.drawLine({ l_rndPoint(), l_rndPoint() }, ostd::Colors::Crimson, 10); + m_gfx.endFrame(); } inline void onFixedUpdate(double frameTime_s) override { - m_textInput.fixedUpdate(); + std::cout << (int)getFPS() << "\n"; } inline void onUpdate(void) override { - m_textInput.update(); } private: - ogfx::gui::RawTextInput m_textInput; ogfx::BasicRenderer2D m_gfx; - ogfx::gui::RawTextInputEventListener m_sigHandler; - ogfx::gui::RawTextInputNumberCharacterFilter m_numCharFilter; }; int main(int argc, char** argv) diff --git a/src/test/GuiTest.cpp b/src/test/GuiTest.cpp index 4af12ca..2f2dc5f 100644 --- a/src/test/GuiTest.cpp +++ b/src/test/GuiTest.cpp @@ -30,6 +30,20 @@ class Window : public ogfx::gui::Window inline Window(void) { } inline void onInitialize(void) override { + test.loadFromFile("./test.png", m_gfx); + ogfx::Animation::AnimationData ad; + ad.backwards = false; + ad.columns = 9; + ad.rows = 4; + ad.frame_width = 256; + ad.frame_height = 256; + ad.length = 36; + ad.random = false; + ad.still = false; + ad.speed = 0; + m_anim.create(ad); + m_anim.setSpriteSheet(test); + m_panel1.setSize(300, 140); m_panel1.setPosition(350, 50); m_panel1.setMousePressedCallback([&](const ogfx::gui::Event& event) -> void { @@ -132,7 +146,16 @@ class Window : public ogfx::gui::Window void onRedraw(ogfx::BasicRenderer2D& gfx) override { - // wout().fg(ostd::Color { 255, 0, 0 }).p("Hello ").fg(ostd::Color { 0, 0, 255 }).p("World"); + // auto l_rndPoint = [&](void) -> ostd::FPoint { + // using rnd = ostd::Random; + // return rnd::getVec2({ 0, (float)getWindowWidth() / 2 }, { 0, (float)getWindowHeight() / 2 }); + // }; + // for (int32_t i = 0; i < 1000; i++) + // gfx.drawLine({ l_rndPoint(), l_rndPoint() }, ostd::Colors::Crimson, 10); + // gfx.drawLine({ { 10, 10 }, { 200, 100 } }, ostd::Colors::Crimson, 3); + // gfx.drawRect({ 50, 50, 200, 120 }, ostd::Colors::Aquamarine, 1); + + // std::cout << (int)(gfx.getDrawCallCount() + 1) << "\n"; } private: @@ -144,6 +167,8 @@ class Window : public ogfx::gui::Window ogfx::gui::widgets::CheckBox m_check1 { *this }; ostd::Stylesheet m_theme; ostd::Vec2 pos { 0, 0 }; + ogfx::Image test; + ogfx::Animation m_anim; }; int main(int argc, char** argv)