Mercurial > repos > blastem
changeset 2685:da2e06c42d16
Add a compile-time flag to use RGB565 instead of ABGR/ARGB
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 30 Mar 2025 00:06:53 -0700 |
parents | c649bcc18487 |
children | 05915f01046d |
files | Makefile cd_graphics.c oscilloscope.c pixel.h png.c png.h ppm.c ppm.h render.h render_sdl.c vdp.c vdp.h |
diffstat | 12 files changed, 241 insertions(+), 141 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Sat Mar 29 23:54:45 2025 -0700 +++ b/Makefile Sun Mar 30 00:06:53 2025 -0700 @@ -67,6 +67,10 @@ USE_GLES:=1 endif +ifdef USE_RGB565 +CFLAGS+= -DUSE_RGB565 +endif + ifdef USE_FBDEV LIBS=alsa ifndef NOGL
--- a/cd_graphics.c Sat Mar 29 23:54:45 2025 -0700 +++ b/cd_graphics.c Sun Mar 30 00:06:53 2025 -0700 @@ -263,7 +263,7 @@ static void render_graphics_debug(segacd_context *cd) { int pitch; - uint32_t *fb = render_get_framebuffer(cd->graphics_debug_window, &pitch); + pixel_t *fb = render_get_framebuffer(cd->graphics_debug_window, &pitch); uint32_t pixels = (cd->gate_array[GA_STAMP_SIZE] & BIT_SMS) ? 4096 : 256; uint32_t stamp_size = (cd->gate_array[GA_STAMP_SIZE] & BIT_STS) ? 32 : 16; uint32_t num_stamps = pixels / stamp_size; @@ -284,7 +284,7 @@ { for (uint32_t y = start_y; y < start_y + stamp_size; y++) { - uint32_t *line = fb + y * pitch / sizeof(uint32_t); + pixel_t *line = fb + y * pitch / sizeof(uint32_t); for (uint32_t x = tile_x; x < tile_x + 8; x += 4) {
--- a/oscilloscope.c Sat Mar 29 23:54:45 2025 -0700 +++ b/oscilloscope.c Sun Mar 30 00:06:53 2025 -0700 @@ -56,15 +56,16 @@ void scope_render(oscilloscope *scope) { int pitch; - uint32_t *fb = render_get_framebuffer(scope->window, &pitch); + pixel_t *fb = render_get_framebuffer(scope->window, &pitch); memset(fb, 0, HEIGHT * pitch); - pitch /= sizeof(uint32_t); + pitch /= sizeof(pixel_t); int offset = 0; int column_width = WIDTH/3; int width = column_width * 3; int row_height = HEIGHT / ((scope->num_channels + 2) / 3); float value_scale = (float)row_height / 20000.0f; - uint32_t *cur_line = fb; + pixel_t *cur_line = fb; + pixel_t white = render_map_color(255, 255, 255); for (uint8_t i = 0; i < scope->num_channels; i++) { float samples_per_pixel = (float)scope->channels[i].period / (float)(2*column_width); @@ -96,13 +97,13 @@ int delta = last_y > y ? -1 : 1; while (last_y != y) { - cur_line[last_y * pitch + x ] = 0xFFFFFFFF; + cur_line[last_y * pitch + x ] = white; last_y += delta; } } else { last_y = y; } - cur_line[y * pitch + x ] = 0xFFFFFFFF; + cur_line[y * pitch + x ] = white; cur_sample += samples_per_pixel; if (cur_sample + 0.5f >= scope->channels[i].period) { cur_sample -= scope->channels[i].period;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pixel.h Sun Mar 30 00:06:53 2025 -0700 @@ -0,0 +1,14 @@ +#ifndef PIXEL_H_ +#define PIXEL_H_ + +#include <stdint.h> +#ifdef USE_RGB565 +typedef uint16_t pixel_t; +#else +typedef uint32_t pixel_t; +#endif + +#define PITCH_BYTES(width) (sizeof(uint32_t) * ((width * sizeof(pixel_t) + sizeof(uint32_t) - 1) / sizeof(uint32_t))) +#define PITCH_PIXEL_T(width) ((width * sizeof(pixel_t) + sizeof(uint32_t) - 1) / sizeof(uint32_t)) * (sizeof(uint32_t) / sizeof(pixel_t)) + +#endif //PIXEL_H_
--- a/png.c Sat Mar 29 23:54:45 2025 -0700 +++ b/png.c Sun Mar 30 00:06:53 2025 -0700 @@ -60,25 +60,37 @@ write_chunk(f, ihdr, chunk, sizeof(chunk)); } -void save_png24_frame(FILE *f, uint32_t *buffer, apng_state *apng, uint32_t width, uint32_t height, uint32_t pitch) +void save_png24_frame(FILE *f, pixel_t *buffer, apng_state *apng, uint32_t width, uint32_t height, uint32_t pitch) { uint32_t idat_size = (1 + width*3) * height; uint8_t *idat_buffer = malloc(idat_size); - uint32_t *pixel = buffer; + pixel_t *pixel = buffer; uint8_t *cur = idat_buffer; for (uint32_t y = 0; y < height; y++) { //save filter type *(cur++) = 0; - uint32_t *start = pixel; + pixel_t *start = pixel; for (uint32_t x = 0; x < width; x++, pixel++) { - uint32_t value = *pixel; + pixel_t value = *pixel; +#ifdef USE_RGB565 + *(cur++) = (value >> 8 & 0xF8) | (value >> (8+5)); + *(cur++) = (value >> 3 & 0xFC) | (value >> (3+5) & 0x3); + *(cur++) = value << 3 | (value >> (5-3) & 0x3); +#else +#ifdef USE_GLES + *(cur++) = value; + *(cur++) = value >> 8; + *(cur++) = value >> 16; +#else *(cur++) = value >> 16; *(cur++) = value >> 8; *(cur++) = value; +#endif +#endif } - pixel = start + pitch / sizeof(uint32_t); + pixel = start + pitch / sizeof(pixel_t); } uLongf compress_buffer_size = idat_size + 5 * (idat_size/16383 + 1) + 3; @@ -147,27 +159,27 @@ free(apng); } -void save_png24(FILE *f, uint32_t *buffer, uint32_t width, uint32_t height, uint32_t pitch) +void save_png24(FILE *f, pixel_t *buffer, uint32_t width, uint32_t height, uint32_t pitch) { write_header(f, width, height, COLOR_TRUE); save_png24_frame(f, buffer, NULL, width, height, pitch); write_chunk(f, iend, NULL, 0); } -void save_png(FILE *f, uint32_t *buffer, uint32_t width, uint32_t height, uint32_t pitch) +void save_png(FILE *f, pixel_t *buffer, uint32_t width, uint32_t height, uint32_t pitch) { - uint32_t palette[256]; + pixel_t palette[256]; uint8_t pal_buffer[256*3]; uint32_t num_pal = 0; uint32_t index_size = (1 + width) * height; uint8_t *index_buffer = malloc(index_size); uint8_t *cur = index_buffer; - uint32_t *pixel = buffer; + pixel_t *pixel = buffer; for (uint32_t y = 0; y < height; y++) { //save filter type *(cur++) = 0; - uint32_t *start = pixel; + pixel_t *start = pixel; for (uint32_t x = 0; x < width; x++, pixel++, cur++) { uint32_t value = (*pixel) & 0xFFFFFF; @@ -189,15 +201,27 @@ } *cur = i; } - pixel = start + pitch / sizeof(uint32_t); + pixel = start + pitch / sizeof(pixel_t); } write_header(f, width, height, COLOR_INDEXED); cur = pal_buffer; for (uint32_t i = 0; i < num_pal; i++) { +#ifdef USE_RGB565 + *(cur++) = (palette[i] >> 8 & 0xF8) | (palette[i] >> (8+5)); + *(cur++) = (palette[i] >> 3 & 0xFC) | (palette[i] >> (3+5) & 0x3); + *(cur++) = palette[i] << 3 | (palette[i] >> (5-3) & 0x3); +#else +#ifdef USE_GLES + *(cur++) = palette[i]; + *(cur++) = palette[i] >> 8; + *(cur++) = palette[i] >> 16; +#else *(cur++) = palette[i] >> 16; *(cur++) = palette[i] >> 8; *(cur++) = palette[i]; +#endif +#endif } write_chunk(f, plte, pal_buffer, num_pal * 3); uLongf compress_buffer_size = index_size + 5 * (index_size/16383 + 1) + 3;
--- a/png.h Sat Mar 29 23:54:45 2025 -0700 +++ b/png.h Sun Mar 30 00:06:53 2025 -0700 @@ -1,6 +1,8 @@ #ifndef PNG_H_ #define PNG_H_ +#include "pixel.h" + typedef struct { uint32_t sequence_number; uint32_t num_frames; @@ -9,9 +11,9 @@ uint16_t delay_den; } apng_state; -void save_png24_frame(FILE *f, uint32_t *buffer, apng_state *apng, uint32_t width, uint32_t height, uint32_t pitch); -void save_png24(FILE *f, uint32_t *buffer, uint32_t width, uint32_t height, uint32_t pitch); -void save_png(FILE *f, uint32_t *buffer, uint32_t width, uint32_t height, uint32_t pitch); +void save_png24_frame(FILE *f, pixel_t *buffer, apng_state *apng, uint32_t width, uint32_t height, uint32_t pitch); +void save_png24(FILE *f, pixel_t *buffer, uint32_t width, uint32_t height, uint32_t pitch); +void save_png(FILE *f, pixel_t *buffer, uint32_t width, uint32_t height, uint32_t pitch); apng_state* start_apng(FILE *f, uint32_t width, uint32_t height, float frame_rate); void end_apng(FILE *f, apng_state *apng); uint32_t *load_png(uint8_t *buffer, uint32_t buf_size, uint32_t *width, uint32_t *height);
--- a/ppm.c Sat Mar 29 23:54:45 2025 -0700 +++ b/ppm.c Sun Mar 30 00:06:53 2025 -0700 @@ -1,21 +1,34 @@ #include <stdint.h> #include <stdio.h> +#include "pixel.h" -void save_ppm(FILE *f, uint32_t *buffer, uint32_t width, uint32_t height, uint32_t pitch) +void save_ppm(FILE *f, pixel_t *buffer, uint32_t width, uint32_t height, uint32_t pitch) { fprintf(f, "P6\n%d %d\n255\n", width, height); for(uint32_t y = 0; y < height; y++) { - uint32_t *line = buffer; + pixel_t *line = buffer; for (uint32_t x = 0; x < width; x++, line++) { uint8_t buf[3] = { +#ifdef USE_RGB565 + (*line >> 8 & 0xF8) | (*line >> (8+5)), //red + (*line >> 3 & 0xFC) | (*line >> (3+5) & 0x3), //green + *line << 3 | (*line >> (5-3) & 0x3) //blue +#else +#ifdef USE_GLES + *line, //red + *line >> 8, //green + *line >> 16 //blue +#else *line >> 16, //red *line >> 8, //green *line //blue +#endif +#endif }; fwrite(buf, 1, sizeof(buf), f); } - buffer = buffer + pitch / sizeof(uint32_t); + buffer = buffer + pitch / sizeof(pixel_t); } }
--- a/ppm.h Sat Mar 29 23:54:45 2025 -0700 +++ b/ppm.h Sun Mar 30 00:06:53 2025 -0700 @@ -1,6 +1,7 @@ #ifndef PPM_H_ #define PPM_H_ +#include "pixel.h" -void save_ppm(FILE *f, uint32_t *buffer, uint32_t width, uint32_t height, uint32_t pitch); +void save_ppm(FILE *f, pixel_t *buffer, uint32_t width, uint32_t height, uint32_t pitch); #endif //PPM_H_
--- a/render.h Sat Mar 29 23:54:45 2025 -0700 +++ b/render.h Sun Mar 30 00:06:53 2025 -0700 @@ -99,14 +99,16 @@ typedef void (*ui_render_fun)(void); typedef int (*render_thread_fun)(void*); -uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b); +#include "pixel.h" + +pixel_t render_map_color(uint8_t r, uint8_t g, uint8_t b); void render_save_screenshot(char *path); uint8_t render_saving_video(void); void render_end_video(void); void render_save_video(char *path); uint8_t render_create_window(char *caption, uint32_t width, uint32_t height, window_close_handler close_handler); void render_destroy_window(uint8_t which); -uint32_t *render_get_framebuffer(uint8_t which, int *pitch); +pixel_t *render_get_framebuffer(uint8_t which, int *pitch); void render_framebuffer_updated(uint8_t which, int width); //returns the framebuffer index associated with the Window that has focus uint8_t render_get_active_framebuffer(void);
--- a/render_sdl.c Sat Mar 29 23:54:45 2025 -0700 +++ b/render_sdl.c Sun Mar 30 00:06:53 2025 -0700 @@ -44,7 +44,7 @@ uint8_t num_static; #ifndef DISABLE_OPENGL SDL_GLContext *gl_context; - uint32_t *texture_buf; + pixel_t *texture_buf; uint32_t tex_width; uint32_t tex_height; GLuint gl_texture[2]; @@ -94,7 +94,7 @@ static uint8_t sync_src; static uint32_t min_buffered; -uint32_t **frame_buffers; +pixel_t **frame_buffers; uint32_t num_buffers; uint32_t buffer_storage; @@ -339,13 +339,17 @@ return is_fullscreen; } -uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b) +pixel_t render_map_color(uint8_t r, uint8_t g, uint8_t b) { +#ifdef USE_RGB565 + return r << 8 & 0xF800 | g << 3 & 0x07E0 | b >> 3; +#else #ifdef USE_GLES return 255UL << 24 | b << 16 | g << 8 | r; #else return 255UL << 24 | r << 16 | g << 8 | b; #endif +#endif } static uint8_t external_sync; @@ -457,19 +461,38 @@ } #endif -static uint32_t texture_buf[512 * 513]; +static pixel_t texture_buf[512 * 513]; #ifdef DISABLE_OPENGL +#ifdef USE_RGB565 +#define RENDER_FORMAT SDL_PIXELFORMAT_RGB565 +#else #define RENDER_FORMAT SDL_PIXELFORMAT_ARGB8888 -#else +#endif +#else //DISABLE_OPENGL +#ifdef USE_RGB565 +#define INTERNAL_FORMAT GL_RGB +#define SRC_FORMAT GL_RGB +#define SRC_TYPE GL_UNSIGNED_SHORT_5_6_5 +#define RENDER_FORMAT SDL_PIXELFORMAT_RGB565 +#else //USE_RGB565 +#define SRC_TYPE GL_UNSIGNED_BYTE #ifdef USE_GLES #define INTERNAL_FORMAT GL_RGBA #define SRC_FORMAT GL_RGBA #define RENDER_FORMAT SDL_PIXELFORMAT_ABGR8888 -#else +#else //USE_GLES #define INTERNAL_FORMAT GL_RGBA8 #define SRC_FORMAT GL_BGRA #define RENDER_FORMAT SDL_PIXELFORMAT_ARGB8888 +#endif //USE_GLES +#endif //USE_RGB565 + +#ifdef USE_GLES +#define SRC_FORMAT32 GL_RGBA +#else +#define SRC_FORMAT32 GL_BGRA #endif + static void gl_setup() { tern_val def = {.ptrval = "linear"}; @@ -494,10 +517,10 @@ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (i < 2) { //TODO: Fixme for PAL + invalid display mode - glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, tex_width, tex_height, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, texture_buf); + glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, tex_width, tex_height, 0, SRC_FORMAT, SRC_TYPE, texture_buf); } else { - uint32_t blank = 255UL << 24; - glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, 1, 1, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, &blank); + pixel_t blank = render_map_color(0, 0, 0); + glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, 1, 1, 0, SRC_FORMAT, SRC_TYPE, &blank); } } glGenBuffers(2, buffers); @@ -538,7 +561,7 @@ glDeleteBuffers(2, buffers); glDeleteTextures(3, textures); } -#endif +#endif //DISABLE_OPENGL static uint8_t texture_init; static void render_alloc_surfaces() @@ -1190,7 +1213,7 @@ free_buffer_mutex = SDL_CreateMutex(); frame_ready = SDL_CreateCond(); buffer_storage = 4; - frame_buffers = calloc(buffer_storage, sizeof(uint32_t*)); + frame_buffers = calloc(buffer_storage, sizeof(pixel_t*)); frame_buffers[0] = texture_buf; num_buffers = 1; } @@ -1688,7 +1711,7 @@ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (i) { - glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, 1, 1, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, extras[win_idx].color); + glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, 1, 1, 0, SRC_FORMAT, SRC_TYPE, extras[win_idx].color); } else { extras[win_idx].tex_width = width; extras[win_idx].tex_height = height; @@ -1697,8 +1720,8 @@ extras[win_idx].tex_width = nearest_pow2(width); extras[win_idx].tex_height = nearest_pow2(height); } - extras[win_idx].texture_buf = calloc(extras[win_idx].tex_width * extras[win_idx].tex_height, sizeof(uint32_t)); - glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, extras[win_idx].tex_width, extras[win_idx].tex_height, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, extras[win_idx].texture_buf); + extras[win_idx].texture_buf = calloc(PITCH_PIXEL_T(extras[win_idx].tex_width) * extras[win_idx].tex_height, sizeof(pixel_t)); + glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, extras[win_idx].tex_width, extras[win_idx].tex_height, 0, SRC_FORMAT, SRC_TYPE, extras[win_idx].texture_buf); } } glGenBuffers(3, extras[win_idx].gl_buffers); @@ -1876,12 +1899,12 @@ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); //TODO: maybe make this respect the npot texture setting? - glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, width, height, 0, SRC_FORMAT, GL_UNSIGNED_BYTE, pixels); + glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, width, height, 0, SRC_FORMAT32, GL_UNSIGNED_BYTE, pixels); } else #endif { extra->static_images[img_index] = SDL_CreateTexture(extra->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, width, height); - SDL_UpdateTexture(extra->static_images[img_index], NULL, pixels, sizeof(uint32_t) * width); + SDL_UpdateTexture(extra->static_images[img_index], NULL, pixels, sizeof(pixel_t) * width); } free(pixels); return img_index; @@ -1963,7 +1986,7 @@ extra->color[1] = g; extra->color[2] = r; glBindTexture(GL_TEXTURE_2D, extra->gl_texture[1]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, SRC_FORMAT, GL_UNSIGNED_BYTE, extra->color); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, SRC_FORMAT, SRC_TYPE, extra->color); extra_draw_quad(extra, extra->gl_texture[1], 1.0f, 1.0f); } #endif @@ -1982,18 +2005,18 @@ #endif } -uint32_t *locked_pixels; +pixel_t *locked_pixels; uint32_t locked_pitch; -uint32_t *render_get_framebuffer(uint8_t which, int *pitch) +pixel_t *render_get_framebuffer(uint8_t which, int *pitch) { if (sync_src == SYNC_AUDIO_THREAD || sync_src == SYNC_EXTERNAL) { - *pitch = LINEBUF_SIZE * sizeof(uint32_t); - uint32_t *buffer; + *pitch = PITCH_BYTES(LINEBUF_SIZE); + pixel_t *buffer; SDL_LockMutex(free_buffer_mutex); if (num_buffers) { buffer = frame_buffers[--num_buffers]; } else { - buffer = calloc(tex_width*(tex_height + 1), sizeof(uint32_t)); + buffer = calloc(tex_width*(tex_height + 1), sizeof(pixel_t)); } SDL_UnlockMutex(free_buffer_mutex); locked_pixels = buffer; @@ -2001,11 +2024,11 @@ } #ifndef DISABLE_OPENGL if (render_gl && which <= FRAMEBUFFER_EVEN) { - *pitch = LINEBUF_SIZE * sizeof(uint32_t); + *pitch = PITCH_BYTES(LINEBUF_SIZE); return texture_buf; } else if (render_gl && which >= FRAMEBUFFER_USER_START) { uint8_t win_idx = which - FRAMEBUFFER_USER_START; - *pitch = extras[win_idx].width * sizeof(uint32_t); + *pitch = PITCH_BYTES(extras[win_idx].width); return extras[win_idx].texture_buf; } else { #endif @@ -2030,7 +2053,7 @@ } static uint8_t last; if (which <= FRAMEBUFFER_EVEN) { - locked_pixels = (uint32_t *)pixels; + locked_pixels = (pixel_t *)pixels; if (which == FRAMEBUFFER_EVEN) { pixels += *pitch; } @@ -2040,18 +2063,18 @@ } last = which; } - return (uint32_t *)pixels; + return (pixel_t *)pixels; #ifndef DISABLE_OPENGL } #endif } -static void release_buffer(uint32_t *buffer) +static void release_buffer(pixel_t *buffer) { SDL_LockMutex(free_buffer_mutex); if (num_buffers == buffer_storage) { buffer_storage *= 2; - frame_buffers = realloc(frame_buffers, sizeof(uint32_t*)*buffer_storage); + frame_buffers = realloc(frame_buffers, sizeof(pixel_t*)*buffer_storage); } frame_buffers[num_buffers++] = buffer; SDL_UnlockMutex(free_buffer_mutex); @@ -2066,7 +2089,7 @@ static uint32_t last_width, last_height; static uint8_t interlaced, last_field; -static void process_framebuffer(uint32_t *buffer, uint8_t which, int width) +static void process_framebuffer(pixel_t *buffer, uint8_t which, int width) { if (sync_src == SYNC_VIDEO && which <= FRAMEBUFFER_EVEN && source_frame_count < 0) { source_frame++; @@ -2100,24 +2123,24 @@ screenshot_path = NULL; } interlaced = last_field != which; - buffer += overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]; + buffer += overscan_left[video_standard] + PITCH_PIXEL_T(LINEBUF_SIZE) * overscan_top[video_standard]; } #ifndef DISABLE_OPENGL if (render_gl && which <= FRAMEBUFFER_EVEN) { SDL_GL_MakeCurrent(main_window, main_context); glBindTexture(GL_TEXTURE_2D, textures[which]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, LINEBUF_SIZE, height, SRC_FORMAT, GL_UNSIGNED_BYTE, buffer); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, LINEBUF_SIZE, height, SRC_FORMAT, SRC_TYPE, buffer); if (screenshot_file) { //properly supporting interlaced modes here is non-trivial, so only save the odd field for now #ifndef DISABLE_ZLIB if (!strcasecmp(ext, "png")) { free(ext); - save_png(screenshot_file, buffer, width, height, LINEBUF_SIZE*sizeof(uint32_t)); + save_png(screenshot_file, buffer, width, height, PITCH_BYTES(LINEBUF_SIZE)); } else { free(ext); #endif - save_ppm(screenshot_file, buffer, width, height, LINEBUF_SIZE*sizeof(uint32_t)); + save_ppm(screenshot_file, buffer, width, height, PITCH_BYTES(LINEBUF_SIZE)); #ifndef DISABLE_ZLIB } #endif @@ -2128,14 +2151,14 @@ //TODO: more precise frame rate apng = start_apng(apng_file, width, height, video_standard == VID_PAL ? 50.0 : 60.0); } - save_png24_frame(apng_file, buffer, apng, width, height, LINEBUF_SIZE*sizeof(uint32_t)); + save_png24_frame(apng_file, buffer, apng, width, height, PITCH_BYTES(LINEBUF_SIZE)); } #endif } else if (render_gl && which >= FRAMEBUFFER_USER_START) { uint8_t win_idx = which - FRAMEBUFFER_USER_START; SDL_GL_MakeCurrent(extras[win_idx].win, extras[win_idx].gl_context); glBindTexture(GL_TEXTURE_2D, extras[win_idx].gl_texture[0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, extras[win_idx].width, extras[win_idx].height, SRC_FORMAT, GL_UNSIGNED_BYTE, buffer); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, extras[win_idx].width, extras[win_idx].height, SRC_FORMAT, SRC_TYPE, buffer); } else { #endif uint32_t shot_height = height; @@ -2298,7 +2321,7 @@ } typedef struct { - uint32_t *buffer; + pixel_t *buffer; int width; uint8_t which; } frame; @@ -2337,6 +2360,20 @@ frame_queue_len++; SDL_CondSignal(frame_ready); SDL_UnlockMutex(frame_mutex); +#ifdef __ANDROID__ + if (which <= FRAMEBUFFER_EVEN) { + static uint32_t frame_counter, start; + frame_counter++; + uint32_t last_frame= SDL_GetTicks(); + if ((last_frame - start) > FPS_INTERVAL) { + if (start && (last_frame-start)) { + debug_message("%s - %.1f fps (emulated)", caption, ((float)frame_counter) / (((float)(last_frame-start)) / 1000.0)); + } + start = last_frame; + frame_counter = 0; + } + } +#endif return; } //TODO: Maybe fixme for render API
--- a/vdp.c Sat Mar 29 23:54:45 2025 -0700 +++ b/vdp.c Sun Mar 30 00:06:53 2025 -0700 @@ -160,8 +160,8 @@ { vdp_context *context = calloc(1, sizeof(vdp_context) + VRAM_SIZE); if (headless) { - context->fb = malloc(512 * LINEBUF_SIZE * sizeof(uint32_t)); - context->output_pitch = LINEBUF_SIZE * sizeof(uint32_t); + context->fb = malloc(512 * LINEBUF_SIZE * sizeof(pixel_t)); + context->output_pitch = LINEBUF_SIZE * sizeof(pixel_t); } else { context->cur_buffer = FRAMEBUFFER_ODD; context->fb = render_get_framebuffer(FRAMEBUFFER_ODD, &context->output_pitch); @@ -339,7 +339,7 @@ context->flags2 |= FLAG2_REGION_PAL; } update_video_params(context); - context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * context->border_top); + context->output = (pixel_t *)(((char *)context->fb) + context->output_pitch * context->border_top); return context; } @@ -999,7 +999,7 @@ )) { uint8_t bg_end_slot = BG_START_SLOT + (context->regs[REG_MODE_4] & BIT_H40) ? LINEBUF_SIZE/2 : (256+HORIZ_BORDER)/2; if (context->hslot < bg_end_slot) { - uint32_t color = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->colors[addr] : context->colors[addr + MODE4_OFFSET]; + pixel_t color = (context->regs[REG_MODE_2] & BIT_MODE_5) ? context->colors[addr] : context->colors[addr + MODE4_OFFSET]; context->output[(context->hslot - BG_START_SLOT)*2 + 1] = color; } } @@ -1820,7 +1820,7 @@ dst = context->compositebuf + BORDER_LEFT + col * 8; } else { dst = context->compositebuf; - uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; + pixel_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; memset(dst, 0, BORDER_LEFT); context->done_composite = dst + BORDER_LEFT; return; @@ -2059,7 +2059,7 @@ line += context->border_top; } if (context->enabled_debuggers & (1 << DEBUG_CRAM)) { - uint32_t *fb = context->debug_fbs[DEBUG_CRAM] + context->debug_fb_pitch[DEBUG_CRAM] * line / sizeof(uint32_t); + pixel_t *fb = context->debug_fbs[DEBUG_CRAM] + context->debug_fb_pitch[DEBUG_CRAM] * line / sizeof(pixel_t); if (context->regs[REG_MODE_2] & BIT_MODE_5) { for (int i = 0; i < 64; i++) { @@ -2082,7 +2082,7 @@ { uint8_t entry = context->vdpmem[mode4_address_map[address] ^ 1]; uint8_t fg = entry >> 4, bg = entry & 0xF; - uint32_t fg_full, bg_full; + pixel_t fg_full, bg_full; if (context->type == VDP_GAMEGEAR) { //Game Gear uses CRAM entries 16-31 for TMS9918A modes fg_full = context->colors[fg + 16 + MODE4_OFFSET]; @@ -2110,7 +2110,7 @@ context->enabled_debuggers & (1 << DEBUG_COMPOSITE) && line < (context->inactive_start + context->border_bot + context->border_top) ) { - uint32_t *fb = context->debug_fbs[DEBUG_COMPOSITE] + context->debug_fb_pitch[DEBUG_COMPOSITE] * line / sizeof(uint32_t); + pixel_t *fb = context->debug_fbs[DEBUG_COMPOSITE] + context->debug_fb_pitch[DEBUG_COMPOSITE] * line / sizeof(pixel_t); if (is_mode_5) { uint32_t left, right; uint16_t top_line, bottom_line; @@ -2175,7 +2175,7 @@ } } -static void vram_debug_mode5(uint32_t *fb, uint32_t pitch, vdp_context *context) +static void vram_debug_mode5(pixel_t *fb, uint32_t pitch, vdp_context *context) { uint8_t pal = (context->debug_modes[DEBUG_VRAM] % 4) << 4; int yshift, ymask, tilesize; @@ -2190,7 +2190,7 @@ } for (int y = 0; y < 512; y++) { - uint32_t *line = fb + y * pitch / sizeof(uint32_t); + pixel_t *line = fb + y * pitch / sizeof(pixel_t); int row = y >> yshift; int yoff = y >> 1 & ymask; for (int col = 0; col < 64; col++) @@ -2210,11 +2210,11 @@ } } -static void vram_debug_mode4(uint32_t *fb, uint32_t pitch, vdp_context *context) +static void vram_debug_mode4(pixel_t *fb, uint32_t pitch, vdp_context *context) { for (int y = 0; y < 256; y++) { - uint32_t *line = fb + y * pitch / sizeof(uint32_t); + pixel_t *line = fb + y * pitch / sizeof(pixel_t); int row = y >> 4; int yoff = y >> 1 & 7; for (int col = 0; col < 64; col++) @@ -2237,13 +2237,13 @@ } } -static void vram_debug_tms(uint32_t *fb, uint32_t pitch, vdp_context *context) +static void vram_debug_tms(pixel_t *fb, uint32_t pitch, vdp_context *context) { uint8_t pal = ((context->debug_modes[DEBUG_VRAM] % 14) + 2) << 1; pal = (pal & 0xE) | (pal << 1 & 0x20); for (int y = 0; y < 512; y++) { - uint32_t *line = fb + y * pitch / sizeof(uint32_t); + pixel_t *line = fb + y * pitch / sizeof(pixel_t); int row = y >> 4; int yoff = y >> 1 & 7; for (int col = 0; col < 64; col++) @@ -2261,7 +2261,7 @@ } } -static void plane_debug_mode5(uint32_t *fb, uint32_t pitch, vdp_context *context) +static void plane_debug_mode5(pixel_t *fb, uint32_t pitch, vdp_context *context) { uint16_t hscroll_mask; uint16_t v_mul; @@ -2309,7 +2309,7 @@ vscroll_mask = 0x1F; break; } - uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; + pixel_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; uint16_t num_rows; int num_lines; if (context->double_res) { @@ -2330,7 +2330,7 @@ uint16_t entry = context->vdpmem[address] << 8 | context->vdpmem[address + 1]; uint8_t pal = entry >> 9 & 0x30; - uint32_t *dst = fb + (row * pitch * num_lines / sizeof(uint32_t)) + col * 8; + pixel_t *dst = fb + (row * pitch * num_lines / sizeof(pixel_t)) + col * 8; if (context->double_res) { address = (entry & 0x3FF) * 64; } else { @@ -2349,7 +2349,7 @@ for (int y = 0; y < num_lines; y++) { uint16_t trow_address = address; - uint32_t *row_dst = dst; + pixel_t *row_dst = dst; for (int x = 0; x < 4; x++) { uint8_t byte = context->vdpmem[trow_address]; @@ -2366,25 +2366,25 @@ *(row_dst++) = right ? context->colors[right|pal] : bg_color; } address += y_diff; - dst += pitch / sizeof(uint32_t); + dst += pitch / sizeof(pixel_t); } } } } -static void sprite_debug_mode5(uint32_t *fb, uint32_t pitch, vdp_context *context) +static void sprite_debug_mode5(pixel_t *fb, uint32_t pitch, vdp_context *context) { - uint32_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; + pixel_t bg_color = context->colors[context->regs[REG_BG_COLOR] & 0x3F]; //clear a single alpha channel bit so we can distinguish between actual bg color and sprite //pixels that just happen to be the same color bg_color &= 0xFEFFFFFF; - uint32_t *line = fb; - uint32_t border_line = render_map_color(0, 0, 255); - uint32_t sprite_outline = render_map_color(255, 0, 255); + pixel_t *line = fb; + pixel_t border_line = render_map_color(0, 0, 255); + pixel_t sprite_outline = render_map_color(255, 0, 255); int right_border = 256 + ((context->h40_lines > context->output_lines / 2) ? 640 : 512); for (int y = 0; y < 1024; y++) { - uint32_t *cur = line; + pixel_t *cur = line; if (y != 256 && y != 256+context->inactive_start*2) { for (int x = 0; x < 255; x++) { @@ -2406,7 +2406,7 @@ *(cur++) = border_line; } } - line += pitch / sizeof(uint32_t); + line += pitch / sizeof(pixel_t); } for (int i = 0, index = 0; i < context->max_sprites_frame; i++) { @@ -2431,8 +2431,8 @@ uint16_t hflip = tileinfo & MAP_BIT_H_FLIP; uint16_t vflip = tileinfo & MAP_BIT_V_FLIP; uint32_t x = (((context->vdpmem[att_addr+ 2] & 0x3) << 8 | context->vdpmem[att_addr + 3]) & 0x1FF) * 2; - uint32_t *line = fb + y * pitch / sizeof(uint32_t) + x; - uint32_t *cur = line; + pixel_t *line = fb + y * pitch / sizeof(pixel_t) + x; + pixel_t *cur = line; for (uint32_t cx = x, x2 = x + pixel_width; cx < x2; cx++) { *(cur++) = sprite_outline; @@ -2453,7 +2453,7 @@ } for (; y < y2; y++) { - line += pitch / sizeof(uint32_t); + line += pitch / sizeof(pixel_t); cur = line; *(cur++) = sprite_outline; uint16_t line_addr = tile_addr; @@ -2463,7 +2463,7 @@ for (uint8_t cx = 0; cx < 4; cx++) { uint8_t pair = context->vdpmem[cur_addr]; - uint32_t left, right; + pixel_t left, right; if (hflip) { right = pair >> 4; left = pair & 0xF; @@ -2506,7 +2506,7 @@ advance_source = !advance_source; } if (y2 != 1024) { - line += pitch / sizeof(uint32_t); + line += pitch / sizeof(pixel_t); cur = line; for (uint32_t cx = x, x2 = x + pixel_width; cx < x2; cx++) { @@ -2520,13 +2520,13 @@ } } -static void plane_debug_mode4(uint32_t *fb, uint32_t pitch, vdp_context *context) +static void plane_debug_mode4(pixel_t *fb, uint32_t pitch, vdp_context *context) { - uint32_t bg_color = context->colors[(context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET]; + pixel_t bg_color = context->colors[(context->regs[REG_BG_COLOR] & 0xF) + MODE4_OFFSET]; uint32_t address = (context->regs[REG_SCROLL_A] & 0xE) << 10; for (uint32_t row_address = address, end = address + 32*32*2; row_address < end; row_address += 2 * 32) { - uint32_t *col = fb; + pixel_t *col = fb; for(uint32_t cur = row_address, row_end = row_address + 2 * 32; cur < row_end; cur += 2) { uint32_t mapped = mode4_address_map[cur]; @@ -2551,7 +2551,7 @@ } else { tile_inc = 4; } - uint32_t *line = col; + pixel_t *line = col; for (int y = 0; y < 16; y++) { uint32_t first = mode4_address_map[tile_address]; @@ -2560,10 +2560,10 @@ pixels |= planar_to_chunky[context->vdpmem[first+1]]; pixels |= planar_to_chunky[context->vdpmem[last]] << 3; pixels |= planar_to_chunky[context->vdpmem[last+1]] << 2; - uint32_t *out = line; + pixel_t *out = line; for (uint32_t i = i_init; i != i_limit; i += i_inc) { - uint32_t pixel = context->colors[((pixels >> i & 0xF) | pal) + MODE4_OFFSET]; + pixel_t pixel = context->colors[((pixels >> i & 0xF) | pal) + MODE4_OFFSET]; *(out++) = pixel; *(out++) = pixel; } @@ -2572,22 +2572,22 @@ if (y & 1) { tile_address += tile_inc; } - line += pitch / sizeof(uint32_t); + line += pitch / sizeof(pixel_t); } col += 16; } - fb += 16 * pitch / sizeof(uint32_t); + fb += 16 * pitch / sizeof(pixel_t); } } -static void sprite_debug_mode4(uint32_t *fb, uint32_t pitch, vdp_context *context) +static void sprite_debug_mode4(pixel_t *fb, uint32_t pitch, vdp_context *context) { } -uint32_t tms_map_color(vdp_context *context, uint8_t color) +pixel_t tms_map_color(vdp_context *context, uint8_t color) { if (context->type == VDP_GAMEGEAR) { //Game Gear uses CRAM entries 16-31 for TMS9918A modes @@ -2599,7 +2599,7 @@ } } -static void plane_debug_tms(uint32_t *fb, uint32_t pitch, vdp_context *context) +static void plane_debug_tms(pixel_t *fb, uint32_t pitch, vdp_context *context) { uint16_t table_address = context->regs[REG_SCROLL_A] << 10 & 0x3C00; uint16_t color_address = context->regs[REG_COLOR_TABLE] << 6; @@ -2636,10 +2636,10 @@ } for (uint32_t row = 0; row < 24; row++) { - uint32_t *colfb = fb; + pixel_t *colfb = fb; for (uint32_t col = 0; col < cols; col++) { - uint32_t *linefb = colfb; + pixel_t *linefb = colfb; uint8_t pattern = context->vdpmem[mode4_address_map[table_address] ^ 1]; uint16_t caddress = color_address; uint16_t paddress = pattern_address; @@ -2665,7 +2665,7 @@ bg = tms_map_color(context, colors & 0xF); } - uint32_t *curfb = linefb; + pixel_t *curfb = linefb; for (uint32_t x = 0; x < pixels; x++) { *(curfb++) = (bits & 0x80) ? fg : bg; @@ -2673,7 +2673,7 @@ bits <<= 1; } } - linefb += pitch / sizeof(uint32_t); + linefb += pitch / sizeof(pixel_t); if (y & 1) { if (context->regs[REG_MODE_1] & BIT_M3) { caddress++; @@ -2685,11 +2685,11 @@ table_address++; colfb += pixels; } - fb += 16 * pitch / sizeof(uint32_t); + fb += 16 * pitch / sizeof(pixel_t); } } -static void sprite_debug_tms(uint32_t *fb, uint32_t pitch, vdp_context *context) +static void sprite_debug_tms(pixel_t *fb, uint32_t pitch, vdp_context *context) { } @@ -2698,7 +2698,7 @@ if (context->enabled_debuggers & (1 << DEBUG_PLANE)) { uint32_t pitch; - uint32_t *fb = render_get_framebuffer(context->debug_fb_indices[DEBUG_PLANE], &pitch); + pixel_t *fb = render_get_framebuffer(context->debug_fb_indices[DEBUG_PLANE], &pitch); if (context->type == VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_MODE_5)) { if ((context->debug_modes[DEBUG_PLANE] & 3) == 3) { sprite_debug_mode5(fb, pitch, context); @@ -2723,7 +2723,7 @@ if (context->enabled_debuggers & (1 << DEBUG_VRAM)) { uint32_t pitch; - uint32_t *fb = render_get_framebuffer(context->debug_fb_indices[DEBUG_VRAM], &pitch); + pixel_t *fb = render_get_framebuffer(context->debug_fb_indices[DEBUG_VRAM], &pitch); if (context->type == VDP_GENESIS && (context->regs[REG_MODE_2] & BIT_MODE_5)) { vram_debug_mode5(fb, pitch, context); } else if (context->type != VDP_TMS9918A && (context->regs[REG_MODE_1] & BIT_MODE_4)) { @@ -2736,12 +2736,13 @@ if (context->enabled_debuggers & (1 << DEBUG_CRAM)) { uint32_t starting_line = 512 - 32*4; - uint32_t *line = context->debug_fbs[DEBUG_CRAM] - + context->debug_fb_pitch[DEBUG_CRAM] * starting_line / sizeof(uint32_t); + pixel_t *line = context->debug_fbs[DEBUG_CRAM] + + context->debug_fb_pitch[DEBUG_CRAM] * starting_line / sizeof(pixel_t); + pixel_t black = render_map_color(0, 0, 0); if (context->regs[REG_MODE_2] & BIT_MODE_5) { for (int pal = 0; pal < 4; pal ++) { - uint32_t *cur; + pixel_t *cur; for (int y = 0; y < 31; y++) { cur = line; @@ -2751,21 +2752,21 @@ { *(cur++) = context->colors[pal * 16 + offset]; } - *(cur++) = 0xFF000000; + *(cur++) = black; } - line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(uint32_t); + line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(pixel_t); } cur = line; for (int x = 0; x < 512; x++) { - *(cur++) = 0xFF000000; + *(cur++) = black; } - line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(uint32_t); + line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(pixel_t); } } else { for (int pal = 0; pal < 2; pal ++) { - uint32_t *cur; + pixel_t *cur; for (int y = 0; y < 31; y++) { cur = line; @@ -2775,16 +2776,16 @@ { *(cur++) = context->colors[pal * 16 + offset]; } - *(cur++) = 0xFF000000; + *(cur++) = black; } - line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(uint32_t); + line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(pixel_t); } cur = line; for (int x = 0; x < 512; x++) { - *(cur++) = 0xFF000000; + *(cur++) = black; } - line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(uint32_t); + line += context->debug_fb_pitch[DEBUG_CRAM] / sizeof(pixel_t); } } render_framebuffer_updated(context->debug_fb_indices[DEBUG_CRAM], 512); @@ -2869,7 +2870,7 @@ context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch); } output_line += context->top_offset; - context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * output_line); + context->output = (pixel_t *)(((char *)context->fb) + context->output_pitch * output_line); #ifdef DEBUG_FB_FILL for (int i = 0; i < LINEBUF_SIZE; i++) { @@ -2894,7 +2895,7 @@ uint16_t lines_max = context->inactive_start + context->border_bot + context->border_top; if (context->output_lines <= lines_max && context->output_lines > 0) { context->fb = render_get_framebuffer(context->cur_buffer, &context->output_pitch); - context->output = (uint32_t *)(((char *)context->fb) + context->output_pitch * (context->output_lines - 1 + context->top_offset)); + context->output = (pixel_t *)(((char *)context->fb) + context->output_pitch * (context->output_lines - 1 + context->top_offset)); } else { context->output = NULL; } @@ -2965,7 +2966,7 @@ #define CHECK_LIMIT if (context->flags & FLAG_DMA_RUN) { run_dma_src(context, -1); } context->hslot++; context->cycles += slot_cycles; CHECK_ONLY #define OUTPUT_PIXEL(slot) if ((slot) >= BG_START_SLOT) {\ uint8_t *src = context->compositebuf + ((slot) - BG_START_SLOT) *2;\ - uint32_t *dst = context->output + ((slot) - BG_START_SLOT) *2;\ + pixel_t *dst = context->output + ((slot) - BG_START_SLOT) *2;\ if ((*src & 0x3F) | test_layer) {\ *(dst++) = context->colors[*(src++)];\ } else {\ @@ -2980,7 +2981,7 @@ #define OUTPUT_PIXEL_H40(slot) if (slot <= (BG_START_SLOT + LINEBUF_SIZE/2)) {\ uint8_t *src = context->compositebuf + (slot - BG_START_SLOT) *2;\ - uint32_t *dst = context->output + (slot - BG_START_SLOT) *2;\ + pixel_t *dst = context->output + (slot - BG_START_SLOT) *2;\ if ((*src & 0x3F) | test_layer) {\ *(dst++) = context->colors[*(src++)];\ } else {\ @@ -2999,7 +3000,7 @@ #define OUTPUT_PIXEL_H32(slot) if (slot <= (BG_START_SLOT + (256+HORIZ_BORDER)/2)) {\ uint8_t *src = context->compositebuf + (slot - BG_START_SLOT) *2;\ - uint32_t *dst = context->output + (slot - BG_START_SLOT) *2;\ + pixel_t *dst = context->output + (slot - BG_START_SLOT) *2;\ if ((*src & 0x3F) | test_layer) {\ *(dst++) = context->colors[*(src++)];\ } else {\ @@ -3020,7 +3021,7 @@ //BG_START_SLOT + 13/2=6, dst = 6, src = border + comp + 13 #define OUTPUT_PIXEL_MODE4(slot) if ((slot) >= BG_START_SLOT) {\ uint8_t *src = context->compositebuf + ((slot) - BG_START_SLOT) *2;\ - uint32_t *dst = context->output + ((slot) - BG_START_SLOT) *2;\ + pixel_t *dst = context->output + ((slot) - BG_START_SLOT) *2;\ if ((slot) - BG_START_SLOT < BORDER_LEFT/2) {\ *(dst++) = context->colors[bgindex];\ *(dst++) = context->colors[bgindex];\ @@ -3269,7 +3270,7 @@ render_sprite_cells_mode4(context);\ MODE4_CHECK_SLOT_LINE(CALC_SLOT(slot, 5)) -static uint32_t dummy_buffer[LINEBUF_SIZE]; +static pixel_t dummy_buffer[LINEBUF_SIZE]; static void vdp_h40_line(vdp_context * context) { uint16_t address; @@ -3314,7 +3315,7 @@ //Do palette lookup for end of previous line uint8_t *src = context->compositebuf + (LINE_CHANGE_H40 - BG_START_SLOT) *2; - uint32_t *dst = context->output + (LINE_CHANGE_H40 - BG_START_SLOT) *2; + pixel_t *dst = context->output + (LINE_CHANGE_H40 - BG_START_SLOT) *2; if (context->output) { if (test_layer) { for (int i = 0; i < LINEBUF_SIZE - (LINE_CHANGE_H40 - BG_START_SLOT) * 2; i++) @@ -4292,7 +4293,7 @@ return; } } - uint32_t color; + pixel_t color; if (context->type == VDP_GAMEGEAR) { //Game Gear uses CRAM entries 16-31 for TMS9918A modes color = context->colors[(context->regs[REG_BG_COLOR] & 0xF) + 16 + MODE4_OFFSET]; @@ -4801,7 +4802,7 @@ active_line = 0x200; } } - uint32_t *dst; + pixel_t *dst; uint8_t *debug_dst; if (context->output && context->hslot >= BG_START_SLOT && context->hslot <= bg_end_slot) { dst = context->output + 2 * (context->hslot - BG_START_SLOT); @@ -4873,7 +4874,7 @@ if (dst) { uint8_t bg_index; - uint32_t bg_color; + pixel_t bg_color; if (mode_5) { bg_index = context->regs[REG_BG_COLOR] & 0x3F; bg_color = context->colors[bg_index];
--- a/vdp.h Sat Mar 29 23:54:45 2025 -0700 +++ b/vdp.h Sun Mar 30 00:06:53 2025 -0700 @@ -10,6 +10,7 @@ #include <stdio.h> #include "system.h" #include "serialize.h" +#include "pixel.h" #define VDP_REGS 24 #define CRAM_SIZE 64 @@ -183,11 +184,11 @@ struct vdp_context { system_header *system; //pointer to current line in framebuffer - uint32_t *output; + pixel_t *output; //pointer to current framebuffer - uint32_t *fb; + pixel_t *fb; uint8_t *done_composite; - uint32_t *debug_fbs[NUM_DEBUG_TYPES]; + pixel_t *debug_fbs[NUM_DEBUG_TYPES]; char *kmod_msg_buffer; vdp_hook dma_hook; vdp_reg_hook reg_hook; @@ -203,8 +204,8 @@ uint32_t address; uint32_t address_latch; uint32_t serial_address; - uint32_t colors[CRAM_SIZE*4]; - uint32_t debugcolors[1 << (3 + 1 + 1 + 1)];//3 bits for source, 1 bit for priority, 1 bit for shadow, 1 bit for hilight + pixel_t colors[CRAM_SIZE*4]; + pixel_t debugcolors[1 << (3 + 1 + 1 + 1)];//3 bits for source, 1 bit for priority, 1 bit for shadow, 1 bit for hilight uint16_t cram[CRAM_SIZE]; uint32_t frame; uint32_t vsram_size;