From 844ad3b073d48cfeccce32a35d2e02ea0b29552f Mon Sep 17 00:00:00 2001 From: Konstantin Nazarov Date: Sun, 22 Dec 2024 02:18:02 +0000 Subject: [PATCH] Implement paletted framebuffer (320x200 for now) --- example/example.c | 9 +++++---- src/framebuffer.cpp | 32 ++++++++++++++++++++++++-------- src/vm.hpp | 4 ++++ 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/example/example.c b/example/example.c index 6a9f074..7a15378 100644 --- a/example/example.c +++ b/example/example.c @@ -2,6 +2,7 @@ typedef unsigned long long uint64_t; typedef unsigned long uint32_t; +typedef unsigned char uint8_t; #define MTIME_BASE 0x0200BFF8 volatile uint32_t* mtime_upper = (uint32_t*)(MTIME_BASE+4); @@ -36,10 +37,10 @@ int fib(int n) { void draw() { for (int k = 0; k < 200; k++) { - for (int i = 0; i< 640; i++) { - for (int j = 0; j < 480; j++) { - uint32_t color = i*(j + k); - uint32_t* addr = (uint32_t*)(FRAMEBUFFER_BASE + ((j*640) + i) *4); + for (int i = 0; i< 320; i++) { + for (int j = 0; j < 200; j++) { + uint8_t color = i*(j + k); + uint8_t* addr = (uint8_t*)(FRAMEBUFFER_BASE + (j*320) + i); *addr = color; } } diff --git a/src/framebuffer.cpp b/src/framebuffer.cpp index 9ffc275..4c20425 100644 --- a/src/framebuffer.cpp +++ b/src/framebuffer.cpp @@ -9,12 +9,21 @@ SDL_Window* window = nullptr; SDL_Renderer* renderer = nullptr; SDL_Texture* texture = nullptr; -Framebuffer::Framebuffer() : Device(FRAMEBUFFER_ADDR, 640 * 480 * 4) { +#define FB_WIDTH 320 +#define FB_HEIGHT 200 +#define FB_SCALE 2 +#define FB_OFFSET 0x10000 + +Framebuffer::Framebuffer() + : Device(FRAMEBUFFER_ADDR, FB_WIDTH * FB_HEIGHT + FB_OFFSET), + width(FB_WIDTH), + height(FB_HEIGHT), + buf(FB_WIDTH * FB_HEIGHT, 0) { if (SDL_Init(SDL_INIT_VIDEO) < 0) { throw std::runtime_error("Failed to initialize SDL"); } window = SDL_CreateWindow("rve Framebuffer", SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, 640, 480, 0); + SDL_WINDOWPOS_CENTERED, width, height, 0); if (!window) { throw std::runtime_error("Failed to create SDL window"); } @@ -33,7 +42,7 @@ Framebuffer::Framebuffer() : Device(FRAMEBUFFER_ADDR, 640 * 480 * 4) { throw std::runtime_error("Failed to create SDL renderer"); } texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, 640, 480); + SDL_TEXTUREACCESS_STREAMING, width, height); if (!texture) { throw std::runtime_error("Failed to create SDL texture"); } @@ -44,8 +53,15 @@ Framebuffer::Framebuffer() : Device(FRAMEBUFFER_ADDR, 640 * 480 * 4) { } void Framebuffer::draw() { - SDL_UpdateTexture(texture, nullptr, &mem[0], - 640 * 4); // Update the SDL texture + for (size_t i = 0; i < width * height; i++) { + uint8_t color = mem[i + FB_OFFSET]; + uint32_t cmap = ((uint32_t*)&mem[0])[color]; + + buf[i] = cmap; + } + + SDL_UpdateTexture(texture, nullptr, &buf[0], + width * 4); // Update the SDL texture SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, nullptr, nullptr); SDL_RenderPresent(renderer); @@ -54,7 +70,7 @@ void Framebuffer::draw() { void Framebuffer::write_mem_u8(uint8_t* src, size_t addr) { Device::write_mem_u8(src, addr); - if (addr + 1 == base() + (640 * 480) * 4) { + if (addr + 1 == base() + width * height + FB_OFFSET) { // draw to the screen when the last byte is written draw(); } @@ -63,7 +79,7 @@ void Framebuffer::write_mem_u8(uint8_t* src, size_t addr) { void Framebuffer::write_mem_u16(uint16_t* src, size_t addr) { Device::write_mem_u16(src, addr); - if (addr + 2 == base() + (640 * 480) * 4) { + if (addr + 2 == base() + width * height + FB_OFFSET) { // draw to the screen when the last byte is written draw(); } @@ -72,7 +88,7 @@ void Framebuffer::write_mem_u16(uint16_t* src, size_t addr) { void Framebuffer::write_mem_u32(uint32_t* src, size_t addr) { Device::write_mem_u32(src, addr); - if (addr + 4 == base() + (640 * 480) * 4) { + if (addr + 4 == base() + width * height + FB_OFFSET) { // draw to the screen when the last byte is written draw(); } diff --git a/src/vm.hpp b/src/vm.hpp index 478f8a7..a9c3458 100644 --- a/src/vm.hpp +++ b/src/vm.hpp @@ -114,6 +114,10 @@ class Framebuffer final : public Device { protected: void draw(); + + size_t width; + size_t height; + std::vector buf; }; class VM {