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)
return NULL;
surface->pixels = (unsigned char*)malloc(width * height * 3);
surface->pixels = (unsigned char*)malloc(width * height * 4);
if (surface->pixels == NULL)
{
@ -85,7 +85,7 @@ RenderBackend_Surface* RenderBackend_CreateSurface(size_t width, size_t height,
surface->width = width;
surface->height = height;
surface->pitch = width * 3;
surface->pitch = width * 4;
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)
{
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)
{
const unsigned char *source_pointer = &source_surface->pixels[((rect_clamped.top + j) * source_surface->pitch) + (rect_clamped.left * 3)];
unsigned char *destination_pointer = &destination_surface->pixels[((y + j) * destination_surface->pitch) + (x * 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 * 4)];
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)
{
source_pointer += 3;
destination_pointer += 3;
source_pointer += 4;
destination_pointer += 4;
}
else
{
*destination_pointer++ = *source_pointer++;
*destination_pointer++ = *source_pointer++;
*destination_pointer++ = *source_pointer++;
*destination_pointer++ = *source_pointer++;
}
}
}
}
else
{
const unsigned char *source_pointer = &source_surface->pixels[(rect_clamped.top * source_surface->pitch) + (rect_clamped.left * 3)];
unsigned char *destination_pointer = &destination_surface->pixels[(y * destination_surface->pitch) + (x * 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 * 4)];
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;
destination_pointer += destination_surface->pitch;
@ -245,6 +254,7 @@ ATTRIBUTE_HOT void RenderBackend_ColourFill(RenderBackend_Surface *surface, cons
*destination_pointer++ = red;
*destination_pointer++ = green;
*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;
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)
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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <X11/Xlib.h>
@ -10,7 +11,7 @@
static Window window;
static XImage* framebufferImage;
static char* framebufferPixels;
static unsigned char* framebufferPixels;
static int framebufferPitch;
static unsigned char* xfriendlyFB;
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);
// Setting up the framebuffer
framebufferPixels = (char*)malloc(screen_width * screen_height * 3);
xfriendlyFB = (unsigned char*)malloc(screen_width * screen_height * 4);
framebufferPixels = (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)),
depth, ZPixmap, 0,
(char*)xfriendlyFB, screen_width, screen_height,
@ -54,7 +56,7 @@ bool WindowBackend_Software_CreateWindow(const char *window_title, size_t screen
if(framebufferImage == 0) {
return false;
}
framebufferPitch = screen_width * 3;
framebufferPitch = screen_width * 4;
return true;
}
@ -80,14 +82,15 @@ void WindowBackend_Software_Display(void) {
// Convert Cave Story's framebuffer format to the Sun's
// This is the exact reverse of how it is on modern
// computers. Yup, it's endianess.
int srci = 0;
for(int i = 0; i < screenWidth * screenHeight * 4; i += 4) {
int src;
xfriendlyFB[i + 0] = 0; // UNUSED
xfriendlyFB[i + 1] = framebufferPixels[srci + 2]; // BLUE
xfriendlyFB[i + 2] = framebufferPixels[srci + 1]; // GREEN
xfriendlyFB[i + 3] = framebufferPixels[srci + 0]; // RED
srci += 3;
}
// int srci = 0;
// for(int i = 0; i < screenWidth * screenHeight * 4; i += 4) {
// int src;
// xfriendlyFB[i + 3] = 0; // UNUSED
// xfriendlyFB[i + 2] = framebufferPixels[srci + 0]; // BLUE
// xfriendlyFB[i + 1] = framebufferPixels[srci + 1]; // GREEN
// xfriendlyFB[i + 0] = framebufferPixels[srci + 2]; // RED
// srci += 4;
// }
//memcpy(xfriendlyFB, framebufferPixels, screenWidth * screenHeight * 4);
XPutImage(xDisplay, window, gc, framebufferImage, 0, 0, 0, 0, screenWidth, screenHeight);
}