Skip to content

Commit

Permalink
Merge pull request #840 from Daft-Freak/picovision-modes
Browse files Browse the repository at this point in the history
More PicoVision modes
  • Loading branch information
Daft-Freak committed May 22, 2024
2 parents 97b5c4f + eed6738 commit 9134c1c
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 37 deletions.
21 changes: 21 additions & 0 deletions 32blit-pico/display_picovision.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
25 changes: 6 additions & 19 deletions 32blit-sdl/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down
6 changes: 2 additions & 4 deletions 32blit-sdl/Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
21 changes: 15 additions & 6 deletions 32blit-sdl/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -339,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++);
Expand All @@ -354,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() {
Expand Down
12 changes: 10 additions & 2 deletions 32blit-stm32/Src/display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
9 changes: 5 additions & 4 deletions 32blit/engine/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions 32blit/engine/engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit 9134c1c

Please sign in to comment.