From fefdf9e93b73ac5e18945c4b0d6da80e78aefdf0 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Sat, 22 Jul 2023 11:32:17 +0100 Subject: [PATCH 1/5] pico: add more PicoVision modes Works most of the time --- 32blit-pico/display_picovision.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/32blit-pico/display_picovision.cpp b/32blit-pico/display_picovision.cpp index b492f5bbd..0e75219b2 100644 --- a/32blit-pico/display_picovision.cpp +++ b/32blit-pico/display_picovision.cpp @@ -22,11 +22,15 @@ static constexpr uint I2C_SCL = 7; static constexpr uint I2C_ADDR = 0x0D; static constexpr uint I2C_REG_SET_RES = 0xFC; static constexpr uint I2C_REG_START = 0xFD; +static constexpr uint I2C_REG_STOP = 0xFF; static constexpr uint32_t base_address = 0x10000; static const blit::Size resolutions[]{ {640, 480}, + {720, 480}, + {720, 400}, + {720, 576}, }; static pimoroni::APS6404 ram(CS, D0, pio1); @@ -385,6 +389,23 @@ void update_display(uint32_t time) { auto new_res = find_resolution(cur_surf_info.bounds); + // resolution switch + if(new_res != cur_resolution) { + // if display was already enabled, we're too late so stop and restart + if(display_enabled) { + uint8_t buf[2] = {I2C_REG_STOP, 1}; + i2c_write_blocking(i2c1, I2C_ADDR, buf, 2, false); + + display_enabled = false; + + sleep_ms(50); // wait a bit + } + + uint8_t buf[2] = {I2C_REG_SET_RES, uint8_t(new_res)}; + i2c_write_blocking(i2c1, I2C_ADDR, buf, 2, false); + cur_resolution = new_res; + } + auto &base_bounds = resolutions[new_res]; uint8_t h_repeat = base_bounds.w / cur_surf_info.bounds.w, v_repeat = base_bounds.h / cur_surf_info.bounds.h; From d2a52bd47f75f00df9ac7f56ff7bb669a5cd01e1 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Sun, 19 Nov 2023 15:05:59 +0000 Subject: [PATCH 2/5] stm32: minimally handle bounds in set_screen_mode_format --- 32blit-stm32/Src/display.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/32blit-stm32/Src/display.cpp b/32blit-stm32/Src/display.cpp index bb8f55cf9..3b364a1b7 100644 --- a/32blit-stm32/Src/display.cpp +++ b/32blit-stm32/Src/display.cpp @@ -145,14 +145,22 @@ namespace display { switch(new_mode) { case ScreenMode::lores: - new_surf_template.bounds = lores_screen_size; + if(new_surf_template.bounds.empty()) + new_surf_template.bounds = lores_screen_size; + else + new_surf_template.bounds /= 2; break; case ScreenMode::hires: case ScreenMode::hires_palette: - new_surf_template.bounds = hires_screen_size; + if(new_surf_template.bounds.empty()) + new_surf_template.bounds = hires_screen_size; break; } + // only two resolutions supported + if(new_surf_template.bounds != lores_screen_size && new_surf_template.bounds != hires_screen_size) + return false; + switch(new_surf_template.format) { case PixelFormat::RGB: case PixelFormat::RGB565: From e7dde22cadad260da9012b5fca86a6c64b6c42e5 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Sun, 19 Nov 2023 15:13:05 +0000 Subject: [PATCH 3/5] sdl: minimally handle bounds in set_screen_mode_format --- 32blit-sdl/System.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/32blit-sdl/System.cpp b/32blit-sdl/System.cpp index 24f3de965..f12c0a542 100644 --- a/32blit-sdl/System.cpp +++ b/32blit-sdl/System.cpp @@ -45,16 +45,23 @@ static bool set_screen_mode_format(blit::ScreenMode new_mode, blit::SurfaceTempl if(new_surf_template.format == (blit::PixelFormat)-1) new_surf_template.format = blit::PixelFormat::RGB; + blit::Size default_bounds(System::width, System::height); + + if(new_surf_template.bounds.empty()) + new_surf_template.bounds = default_bounds; + switch(new_mode) { case blit::ScreenMode::lores: - new_surf_template.bounds = blit::Size(System::width / 2, System::height / 2); + new_surf_template.bounds /= 2; break; case blit::ScreenMode::hires: case blit::ScreenMode::hires_palette: - new_surf_template.bounds = blit::Size(System::width, System::height); break; } + if(new_surf_template.bounds != default_bounds && new_surf_template.bounds != default_bounds / 2) + return false; + switch(new_surf_template.format) { case blit::PixelFormat::RGB: case blit::PixelFormat::RGB565: From e567e975149d005bfd09667ba52c99617988c951 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Fri, 21 Jul 2023 12:45:31 +0100 Subject: [PATCH 4/5] Add optional bounds to set_screen_mode --- 32blit/engine/engine.cpp | 9 +++++---- 32blit/engine/engine.hpp | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/32blit/engine/engine.cpp b/32blit/engine/engine.cpp index bfc647560..80b1679b0 100644 --- a/32blit/engine/engine.cpp +++ b/32blit/engine/engine.cpp @@ -13,16 +13,17 @@ namespace blit { void (*update)(uint32_t time) = nullptr; void (*render)(uint32_t time) = nullptr; - void set_screen_mode(ScreenMode new_mode) { + void set_screen_mode(ScreenMode new_mode, Size bounds) { if(new_mode == ScreenMode::hires_palette) - set_screen_mode(ScreenMode::hires, PixelFormat::P); + set_screen_mode(ScreenMode::hires, PixelFormat::P, bounds); else - set_screen_mode(new_mode, (PixelFormat)-1); + set_screen_mode(new_mode, (PixelFormat)-1, bounds); } - bool set_screen_mode(ScreenMode new_mode, PixelFormat format) { + bool set_screen_mode(ScreenMode new_mode, PixelFormat format, Size bounds) { SurfaceTemplate new_screen; new_screen.format = format; + new_screen.bounds = bounds; if(!api.set_screen_mode_format(new_mode, new_screen)) return false; diff --git a/32blit/engine/engine.hpp b/32blit/engine/engine.hpp index 152608642..4351aeb35 100644 --- a/32blit/engine/engine.hpp +++ b/32blit/engine/engine.hpp @@ -15,8 +15,8 @@ namespace blit { extern void (*update) (uint32_t time); extern void (*render) (uint32_t time); - void set_screen_mode(ScreenMode new_mode); - bool set_screen_mode(ScreenMode new_mode, PixelFormat format); + void set_screen_mode(ScreenMode new_mode, Size bounds = {0, 0}); + bool set_screen_mode(ScreenMode new_mode, PixelFormat format, Size bounds = {0, 0}); void set_screen_palette(const Pen *colours, int num_cols); uint32_t now(); From eed67381fc1ba30e33a8d2ad2737a0aef7d874e0 Mon Sep 17 00:00:00 2001 From: Charlie Birks Date: Sun, 19 Nov 2023 15:29:54 +0000 Subject: [PATCH 5/5] sdl: use the same textures for hires/lores Simpilfies Renderer a bit and only requires minor changes to System::update_texture --- 32blit-sdl/Renderer.cpp | 25 ++++++------------------- 32blit-sdl/Renderer.hpp | 6 ++---- 32blit-sdl/System.cpp | 10 ++++++---- 3 files changed, 14 insertions(+), 27 deletions(-) diff --git a/32blit-sdl/Renderer.cpp b/32blit-sdl/Renderer.cpp index e51a00257..0f5e734fb 100644 --- a/32blit-sdl/Renderer.cpp +++ b/32blit-sdl/Renderer.cpp @@ -16,7 +16,7 @@ Renderer::Renderer(SDL_Window *window, int width, int height) : sys_width(width) std::cerr << "could not create renderer: " << SDL_GetError() << std::endl; } - current = fb_hires_texture; + current = fb_texture; int w, h; SDL_GetWindowSize(window, &w, &h); @@ -28,17 +28,13 @@ Renderer::Renderer(SDL_Window *window, int width, int height) : sys_width(width) SDL_RenderClear(renderer); SDL_RenderPresent(renderer); - fb_lores_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STREAMING, sys_width/2, sys_height/2); - fb_hires_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STREAMING, sys_width, sys_height); - fb_lores_565_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_BGR565, SDL_TEXTUREACCESS_STREAMING, sys_width/2, sys_height/2); - fb_hires_565_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_BGR565, SDL_TEXTUREACCESS_STREAMING, sys_width, sys_height); + fb_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STREAMING, sys_width, sys_height); + fb_565_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_BGR565, SDL_TEXTUREACCESS_STREAMING, sys_width, sys_height); } Renderer::~Renderer() { - SDL_DestroyTexture(fb_lores_texture); - SDL_DestroyTexture(fb_hires_texture); - SDL_DestroyTexture(fb_lores_565_texture); - SDL_DestroyTexture(fb_hires_565_texture); + SDL_DestroyTexture(fb_texture); + SDL_DestroyTexture(fb_565_texture); SDL_DestroyRenderer(renderer); } @@ -70,11 +66,7 @@ void Renderer::resize(int width, int height) { void Renderer::update(System *sys) { auto format = blit::PixelFormat(sys->format()); - if (sys->mode() == 0) { - current = format == blit::PixelFormat::RGB565 ? fb_lores_565_texture : fb_lores_texture; - } else { - current = format == blit::PixelFormat::RGB565 ? fb_hires_565_texture : fb_hires_texture; - } + current = format == blit::PixelFormat::RGB565 ? fb_565_texture : fb_texture; if(is_lores != (sys->mode() == 0)) { is_lores = sys->mode() == 0; @@ -98,11 +90,6 @@ void Renderer::present() { dest.w = sys_width; dest.h = sys_height; - if (is_lores) { - dest.w /= 2; - dest.h /= 2; - } - _render(nullptr, &dest); SDL_RenderPresent(renderer); } diff --git a/32blit-sdl/Renderer.hpp b/32blit-sdl/Renderer.hpp index a3db8ed35..306809068 100644 --- a/32blit-sdl/Renderer.hpp +++ b/32blit-sdl/Renderer.hpp @@ -23,9 +23,7 @@ class Renderer { Mode mode = KeepPixels; SDL_Renderer *renderer = nullptr; - SDL_Texture *fb_lores_texture = nullptr; - SDL_Texture *fb_hires_texture = nullptr; - SDL_Texture *fb_lores_565_texture = nullptr; - SDL_Texture *fb_hires_565_texture = nullptr; + SDL_Texture *fb_texture = nullptr; + SDL_Texture *fb_565_texture = nullptr; SDL_Texture *current = nullptr; }; diff --git a/32blit-sdl/System.cpp b/32blit-sdl/System.cpp index f12c0a542..d005b5a48 100644 --- a/32blit-sdl/System.cpp +++ b/32blit-sdl/System.cpp @@ -346,13 +346,15 @@ Uint32 System::format() { void System::update_texture(SDL_Texture *texture) { bool is_lores = _mode == blit::ScreenMode::lores; - auto stride = (is_lores ? width / 2 : width) * blit::pixel_format_stride[int(cur_format)]; + + SDL_Rect dest_rect{0, 0, is_lores ? width / 2 : width, is_lores ? height / 2 : height}; + auto stride = dest_rect.w * blit::pixel_format_stride[int(cur_format)]; if(cur_format == blit::PixelFormat::P) { uint8_t col_fb[max_width * max_height * 3]; auto in = framebuffer, out = col_fb; - auto size = is_lores ? (width / 2) * (height / 2) : width * height; + auto size = dest_rect.w * dest_rect.h; for(int i = 0; i < size; i++) { uint8_t index = *(in++); @@ -361,9 +363,9 @@ void System::update_texture(SDL_Texture *texture) { (*out++) = palette[index].b; } - SDL_UpdateTexture(texture, nullptr, col_fb, stride * 3); + SDL_UpdateTexture(texture, &dest_rect, col_fb, stride * 3); } else - SDL_UpdateTexture(texture, nullptr, framebuffer, stride); + SDL_UpdateTexture(texture, &dest_rect, framebuffer, stride); } void System::notify_redraw() {