Adjust rendering code to 4-byte pixel format with unused byte

This commit is contained in:
John Lorentzson 2025-04-06 22:48:08 +02:00
parent 33b59f8219
commit 6ab4984350
2 changed files with 37 additions and 24 deletions

View file

@ -75,7 +75,7 @@ RenderBackend_Surface* RenderBackend_CreateSurface(size_t width, size_t height,
if (surface == NULL) if (surface == NULL)
return NULL; return NULL;
surface->pixels = (unsigned char*)malloc(width * height * 3); surface->pixels = (unsigned char*)malloc(width * height * 4);
if (surface->pixels == NULL) if (surface->pixels == NULL)
{ {
@ -85,7 +85,7 @@ RenderBackend_Surface* RenderBackend_CreateSurface(size_t width, size_t height,
surface->width = width; surface->width = width;
surface->height = height; surface->height = height;
surface->pitch = width * 3; surface->pitch = width * 4;
return surface; return surface;
} }
@ -111,7 +111,15 @@ void RenderBackend_RestoreSurface(RenderBackend_Surface *surface)
void RenderBackend_UploadSurface(RenderBackend_Surface *surface, const unsigned char *pixels, size_t width, size_t height) void RenderBackend_UploadSurface(RenderBackend_Surface *surface, const unsigned char *pixels, size_t width, size_t height)
{ {
for (size_t y = 0; y < height; ++y) { for (size_t y = 0; y < height; ++y) {
memcpy(&surface->pixels[y * surface->pitch], &pixels[y * width * 3], width * 3); int srcl = y * width * 3;
int dstl = y * surface->pitch;
for (size_t x = 0; x < width; ++x) {
int srcr = x * 3;
int dstr = x * 4;
surface->pixels[dstl + dstr + 0] = pixels[srcl + srcr + 0];
surface->pixels[dstl + dstr + 1] = pixels[srcl + srcr + 1];
surface->pixels[dstl + dstr + 2] = pixels[srcl + srcr + 2];
}
} }
} }
@ -160,33 +168,34 @@ ATTRIBUTE_HOT void RenderBackend_Blit(RenderBackend_Surface *source_surface, con
{ {
for (long j = 0; j < rect_clamped.bottom - rect_clamped.top; ++j) for (long j = 0; j < rect_clamped.bottom - rect_clamped.top; ++j)
{ {
const unsigned char *source_pointer = &source_surface->pixels[((rect_clamped.top + j) * source_surface->pitch) + (rect_clamped.left * 3)]; const unsigned char *source_pointer = &source_surface->pixels[((rect_clamped.top + j) * source_surface->pitch) + (rect_clamped.left * 4)];
unsigned char *destination_pointer = &destination_surface->pixels[((y + j) * destination_surface->pitch) + (x * 3)]; unsigned char *destination_pointer = &destination_surface->pixels[((y + j) * destination_surface->pitch) + (x * 4)];
for (long i = 0; i < rect_clamped.right - rect_clamped.left; ++i) for (long i = 0; i < rect_clamped.right - rect_clamped.left; ++i)
{ {
if (UNLIKELY(source_pointer[0] == 0 && source_pointer[1] == 0 && source_pointer[2] == 0)) // Assumes the colour key will always be #000000 (black) if (UNLIKELY(source_pointer[0] == 0 && source_pointer[1] == 0 && source_pointer[2] == 0)) // Assumes the colour key will always be #000000 (black)
{ {
source_pointer += 3; source_pointer += 4;
destination_pointer += 3; destination_pointer += 4;
} }
else else
{ {
*destination_pointer++ = *source_pointer++; *destination_pointer++ = *source_pointer++;
*destination_pointer++ = *source_pointer++; *destination_pointer++ = *source_pointer++;
*destination_pointer++ = *source_pointer++; *destination_pointer++ = *source_pointer++;
*destination_pointer++ = *source_pointer++;
} }
} }
} }
} }
else else
{ {
const unsigned char *source_pointer = &source_surface->pixels[(rect_clamped.top * source_surface->pitch) + (rect_clamped.left * 3)]; const unsigned char *source_pointer = &source_surface->pixels[(rect_clamped.top * source_surface->pitch) + (rect_clamped.left * 4)];
unsigned char *destination_pointer = &destination_surface->pixels[(y * destination_surface->pitch) + (x * 3)]; unsigned char *destination_pointer = &destination_surface->pixels[(y * destination_surface->pitch) + (x * 4)];
for (long j = 0; j < rect_clamped.bottom - rect_clamped.top; ++j) for (long j = 0; j < rect_clamped.bottom - rect_clamped.top; ++j)
{ {
memcpy(destination_pointer, source_pointer, (rect_clamped.right - rect_clamped.left) * 3); memcpy(destination_pointer, source_pointer, (rect_clamped.right - rect_clamped.left) * 4);
source_pointer += source_surface->pitch; source_pointer += source_surface->pitch;
destination_pointer += destination_surface->pitch; destination_pointer += destination_surface->pitch;
@ -245,6 +254,7 @@ ATTRIBUTE_HOT void RenderBackend_ColourFill(RenderBackend_Surface *surface, cons
*destination_pointer++ = red; *destination_pointer++ = red;
*destination_pointer++ = green; *destination_pointer++ = green;
*destination_pointer++ = blue; *destination_pointer++ = blue;
destination_pointer++;
} }
} }
} }
@ -353,7 +363,7 @@ void RenderBackend_DrawGlyph(long x, long y, size_t glyph_x, size_t glyph_y, siz
{ {
const float alpha = alpha_int / 255.0f; const float alpha = alpha_int / 255.0f;
unsigned char *bitmap_pixel = &glyph_destination_surface->pixels[(surface_y + iy) * glyph_destination_surface->pitch + (surface_x + ix) * 3]; unsigned char *bitmap_pixel = &glyph_destination_surface->pixels[(surface_y + iy) * glyph_destination_surface->pitch + (surface_x + ix) * 4];
for (unsigned int j = 0; j < 3; ++j) for (unsigned int j = 0; j < 3; ++j)
bitmap_pixel[j] = (unsigned char)((glyph_colour_channels[j] * alpha) + (bitmap_pixel[j] * (1.0f - alpha))); // Alpha blending bitmap_pixel[j] = (unsigned char)((glyph_colour_channels[j] * alpha) + (bitmap_pixel[j] * (1.0f - alpha))); // Alpha blending

View file

@ -3,6 +3,7 @@
#include <X11/X.h> #include <X11/X.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -10,7 +11,7 @@
static Window window; static Window window;
static XImage* framebufferImage; static XImage* framebufferImage;
static char* framebufferPixels; static unsigned char* framebufferPixels;
static int framebufferPitch; static int framebufferPitch;
static unsigned char* xfriendlyFB; static unsigned char* xfriendlyFB;
static GC gc; static GC gc;
@ -45,8 +46,9 @@ bool WindowBackend_Software_CreateWindow(const char *window_title, size_t screen
intermediate = XCreatePixmap(xDisplay, window, screenWidth, screenHeight, depth); intermediate = XCreatePixmap(xDisplay, window, screenWidth, screenHeight, depth);
// Setting up the framebuffer // Setting up the framebuffer
framebufferPixels = (char*)malloc(screen_width * screen_height * 3); framebufferPixels = (unsigned char*)malloc(screen_width * screen_height * 4);
xfriendlyFB = (unsigned char*)malloc(screen_width * screen_height * 4); //xfriendlyFB = (unsigned char*)malloc(screen_width * screen_height * 4);
xfriendlyFB = framebufferPixels;
framebufferImage = XCreateImage(xDisplay, xVisual,//DefaultVisual(xDisplay, DefaultScreen(xDisplay)), framebufferImage = XCreateImage(xDisplay, xVisual,//DefaultVisual(xDisplay, DefaultScreen(xDisplay)),
depth, ZPixmap, 0, depth, ZPixmap, 0,
(char*)xfriendlyFB, screen_width, screen_height, (char*)xfriendlyFB, screen_width, screen_height,
@ -54,7 +56,7 @@ bool WindowBackend_Software_CreateWindow(const char *window_title, size_t screen
if(framebufferImage == 0) { if(framebufferImage == 0) {
return false; return false;
} }
framebufferPitch = screen_width * 3; framebufferPitch = screen_width * 4;
return true; return true;
} }
@ -80,14 +82,15 @@ void WindowBackend_Software_Display(void) {
// Convert Cave Story's framebuffer format to the Sun's // Convert Cave Story's framebuffer format to the Sun's
// This is the exact reverse of how it is on modern // This is the exact reverse of how it is on modern
// computers. Yup, it's endianess. // computers. Yup, it's endianess.
int srci = 0; // int srci = 0;
for(int i = 0; i < screenWidth * screenHeight * 4; i += 4) { // for(int i = 0; i < screenWidth * screenHeight * 4; i += 4) {
int src; // int src;
xfriendlyFB[i + 0] = 0; // UNUSED // xfriendlyFB[i + 3] = 0; // UNUSED
xfriendlyFB[i + 1] = framebufferPixels[srci + 2]; // BLUE // xfriendlyFB[i + 2] = framebufferPixels[srci + 0]; // BLUE
xfriendlyFB[i + 2] = framebufferPixels[srci + 1]; // GREEN // xfriendlyFB[i + 1] = framebufferPixels[srci + 1]; // GREEN
xfriendlyFB[i + 3] = framebufferPixels[srci + 0]; // RED // xfriendlyFB[i + 0] = framebufferPixels[srci + 2]; // RED
srci += 3; // srci += 4;
} // }
//memcpy(xfriendlyFB, framebufferPixels, screenWidth * screenHeight * 4);
XPutImage(xDisplay, window, gc, framebufferImage, 0, 0, 0, 0, screenWidth, screenHeight); XPutImage(xDisplay, window, gc, framebufferImage, 0, 0, 0, 0, screenWidth, screenHeight);
} }