Implement paletted framebuffer (320x200 for now)
This commit is contained in:
parent
557d5dfa75
commit
844ad3b073
3 changed files with 33 additions and 12 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
typedef unsigned long long uint64_t;
|
typedef unsigned long long uint64_t;
|
||||||
typedef unsigned long uint32_t;
|
typedef unsigned long uint32_t;
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
#define MTIME_BASE 0x0200BFF8
|
#define MTIME_BASE 0x0200BFF8
|
||||||
|
|
||||||
volatile uint32_t* mtime_upper = (uint32_t*)(MTIME_BASE+4);
|
volatile uint32_t* mtime_upper = (uint32_t*)(MTIME_BASE+4);
|
||||||
|
@ -36,10 +37,10 @@ int fib(int n) {
|
||||||
|
|
||||||
void draw() {
|
void draw() {
|
||||||
for (int k = 0; k < 200; k++) {
|
for (int k = 0; k < 200; k++) {
|
||||||
for (int i = 0; i< 640; i++) {
|
for (int i = 0; i< 320; i++) {
|
||||||
for (int j = 0; j < 480; j++) {
|
for (int j = 0; j < 200; j++) {
|
||||||
uint32_t color = i*(j + k);
|
uint8_t color = i*(j + k);
|
||||||
uint32_t* addr = (uint32_t*)(FRAMEBUFFER_BASE + ((j*640) + i) *4);
|
uint8_t* addr = (uint8_t*)(FRAMEBUFFER_BASE + (j*320) + i);
|
||||||
*addr = color;
|
*addr = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,21 @@ SDL_Window* window = nullptr;
|
||||||
SDL_Renderer* renderer = nullptr;
|
SDL_Renderer* renderer = nullptr;
|
||||||
SDL_Texture* texture = 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) {
|
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||||
throw std::runtime_error("Failed to initialize SDL");
|
throw std::runtime_error("Failed to initialize SDL");
|
||||||
}
|
}
|
||||||
window = SDL_CreateWindow("rve Framebuffer", SDL_WINDOWPOS_CENTERED,
|
window = SDL_CreateWindow("rve Framebuffer", SDL_WINDOWPOS_CENTERED,
|
||||||
SDL_WINDOWPOS_CENTERED, 640, 480, 0);
|
SDL_WINDOWPOS_CENTERED, width, height, 0);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
throw std::runtime_error("Failed to create SDL 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");
|
throw std::runtime_error("Failed to create SDL renderer");
|
||||||
}
|
}
|
||||||
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
|
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
|
||||||
SDL_TEXTUREACCESS_STREAMING, 640, 480);
|
SDL_TEXTUREACCESS_STREAMING, width, height);
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
throw std::runtime_error("Failed to create SDL 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() {
|
void Framebuffer::draw() {
|
||||||
SDL_UpdateTexture(texture, nullptr, &mem[0],
|
for (size_t i = 0; i < width * height; i++) {
|
||||||
640 * 4); // Update the SDL texture
|
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_RenderClear(renderer);
|
||||||
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
|
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
|
@ -54,7 +70,7 @@ void Framebuffer::draw() {
|
||||||
void Framebuffer::write_mem_u8(uint8_t* src, size_t addr) {
|
void Framebuffer::write_mem_u8(uint8_t* src, size_t addr) {
|
||||||
Device::write_mem_u8(src, 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 to the screen when the last byte is written
|
||||||
draw();
|
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) {
|
void Framebuffer::write_mem_u16(uint16_t* src, size_t addr) {
|
||||||
Device::write_mem_u16(src, 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 to the screen when the last byte is written
|
||||||
draw();
|
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) {
|
void Framebuffer::write_mem_u32(uint32_t* src, size_t addr) {
|
||||||
Device::write_mem_u32(src, 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 to the screen when the last byte is written
|
||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,10 @@ class Framebuffer final : public Device {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void draw();
|
void draw();
|
||||||
|
|
||||||
|
size_t width;
|
||||||
|
size_t height;
|
||||||
|
std::vector<uint32_t> buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VM {
|
class VM {
|
||||||
|
|
Loading…
Reference in a new issue