Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More PicoVision modes #840

Merged
merged 5 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
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 Expand Up @@ -65,7 +66,7 @@
return api.random();
}

void debug(std::string message) {

Check warning on line 69 in 32blit/engine/engine.cpp

View workflow job for this annotation

GitHub Actions / Linux

the parameter 'message' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param]
api.debug(message.c_str());
}

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
Loading