shithub: cstory

Download patch

ref: daa55b1a3c542c7747eb0b845fd9a1675500b8be
parent: 17da39fa14c542d8465c2cefaf98b826ad09a3d2
author: Clownacy <Clownacy@users.noreply.github.com>
date: Mon Sep 14 08:07:52 EDT 2020

Allow font atlases to be non-square

Saves a little memory in some cases. It's the backend's job to decide
if this is a problem or not, and pad it if it has to.

--- a/src/Backends/Rendering.h
+++ b/src/Backends/Rendering.h
@@ -24,7 +24,7 @@
 void RenderBackend_UnlockSurface(RenderBackend_Surface *surface, size_t width, size_t height);
 void RenderBackend_Blit(RenderBackend_Surface *source_surface, const RenderBackend_Rect *rect, RenderBackend_Surface *destination_surface, long x, long y, bool colour_key);
 void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBackend_Rect *rect, unsigned char red, unsigned char green, unsigned char blue);
-RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size);
+RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height);
 void RenderBackend_DestroyGlyphAtlas(RenderBackend_GlyphAtlas *atlas);
 void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height);
 void RenderBackend_PrepareToDrawGlyphs(RenderBackend_GlyphAtlas *atlas, RenderBackend_Surface *destination_surface, unsigned char red, unsigned char green, unsigned char blue);
--- a/src/Backends/Rendering/OpenGL3.cpp
+++ b/src/Backends/Rendering/OpenGL3.cpp
@@ -40,7 +40,8 @@
 typedef struct RenderBackend_GlyphAtlas
 {
 	GLuint texture_id;
-	size_t size;
+	size_t width;
+	size_t height;
 } RenderBackend_GlyphAtlas;
 
 typedef struct Coordinate2D
@@ -866,21 +867,22 @@
 // Glyph management //
 //////////////////////
 
-RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size)
+RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height)
 {
 	RenderBackend_GlyphAtlas *atlas = (RenderBackend_GlyphAtlas*)malloc(sizeof(RenderBackend_GlyphAtlas));
 
 	if (atlas != NULL)
 	{
-		atlas->size = size;
+		atlas->width = width;
+		atlas->height = height;
 
 		glGenTextures(1, &atlas->texture_id);
 		glBindTexture(GL_TEXTURE_2D, atlas->texture_id);
 
 	#ifdef USE_OPENGLES2
-		glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, size, size, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
 	#else
-		glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, size, size, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
 	#endif
 
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -986,10 +988,10 @@
 		vertex_buffer_slot->vertices[1][2].position.x = vertex_left;
 		vertex_buffer_slot->vertices[1][2].position.y = vertex_bottom;
 
-		const GLfloat texture_left = glyph_x / (GLfloat)atlas->size;
-		const GLfloat texture_top = glyph_y / (GLfloat)atlas->size;
-		const GLfloat texture_right = (glyph_x + glyph_width) / (GLfloat)atlas->size;
-		const GLfloat texture_bottom = (glyph_y + glyph_height) / (GLfloat)atlas->size;
+		const GLfloat texture_left = glyph_x / (GLfloat)atlas->width;
+		const GLfloat texture_top = glyph_y / (GLfloat)atlas->height;
+		const GLfloat texture_right = (glyph_x + glyph_width) / (GLfloat)atlas->width;
+		const GLfloat texture_bottom = (glyph_y + glyph_height) / (GLfloat)atlas->height;
 
 		vertex_buffer_slot->vertices[0][0].texture.x = texture_left;
 		vertex_buffer_slot->vertices[0][0].texture.y = texture_top;
--- a/src/Backends/Rendering/SDLSurface.cpp
+++ b/src/Backends/Rendering/SDLSurface.cpp
@@ -197,13 +197,13 @@
 		Backend_PrintError("Couldn't fill rectangle with color: %s", SDL_GetError());
 }
 
-RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size)
+RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height)
 {
 	RenderBackend_GlyphAtlas *atlas = (RenderBackend_GlyphAtlas*)malloc(sizeof(RenderBackend_GlyphAtlas));
 
 	if (atlas != NULL)
 	{
-		atlas->sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, size, size, 0, SDL_PIXELFORMAT_RGBA32);
+		atlas->sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 0, SDL_PIXELFORMAT_RGBA32);
 
 		if (atlas->sdlsurface != NULL)
 		{
--- a/src/Backends/Rendering/SDLTexture.cpp
+++ b/src/Backends/Rendering/SDLTexture.cpp
@@ -335,13 +335,13 @@
 		Backend_PrintError("Couldn't enable alpha blending for drawing operations: %s", SDL_GetError());
 }
 
-RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size)
+RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height)
 {
 	RenderBackend_GlyphAtlas *atlas = (RenderBackend_GlyphAtlas*)malloc(sizeof(RenderBackend_GlyphAtlas));
 
 	if (atlas != NULL)
 	{
-		atlas->texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, size, size);
+		atlas->texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, width, height);
 
 		if (atlas->texture != NULL)
 		{
--- a/src/Backends/Rendering/Software.cpp
+++ b/src/Backends/Rendering/Software.cpp
@@ -22,7 +22,8 @@
 typedef struct RenderBackend_GlyphAtlas
 {
 	unsigned char *pixels;
-	size_t size;
+	size_t width;
+	size_t height;
 } RenderBackend_GlyphAtlas;
 
 static RenderBackend_Surface framebuffer;
@@ -258,17 +259,18 @@
 	}
 }
 
-RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size)
+RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height)
 {
 	RenderBackend_GlyphAtlas *atlas = (RenderBackend_GlyphAtlas*)malloc(sizeof(RenderBackend_GlyphAtlas));
 
 	if (atlas != NULL)
 	{
-		atlas->pixels = (unsigned char*)malloc(size * size);
+		atlas->pixels = (unsigned char*)malloc(width * height);
 
 		if (atlas->pixels != NULL)
 		{
-			atlas->size = size;
+			atlas->width = width;
+			atlas->height = height;
 
 			return atlas;
 		}
@@ -288,7 +290,7 @@
 void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height)
 {
 	for (size_t i = 0; i < height; ++i)
-		memcpy(&atlas->pixels[(y + i) * atlas->size + x], &pixels[i * width], width);
+		memcpy(&atlas->pixels[(y + i) * atlas->width + x], &pixels[i * width], width);
 }
 
 void RenderBackend_PrepareToDrawGlyphs(RenderBackend_GlyphAtlas *atlas, RenderBackend_Surface *destination_surface, unsigned char red, unsigned char green, unsigned char blue)
@@ -311,7 +313,7 @@
 	{
 		for (unsigned int ix = MAX(-x, 0); x + ix < MIN(x + glyph_width, glyph_destination_surface->width); ++ix)
 		{
-			const unsigned char alpha_int = atlas->pixels[(glyph_y + iy) * atlas->size + (glyph_x + ix)];
+			const unsigned char alpha_int = atlas->pixels[(glyph_y + iy) * atlas->width + (glyph_x + ix)];
 
 			if (alpha_int != 0)
 			{
--- a/src/Backends/Rendering/WiiU.cpp
+++ b/src/Backends/Rendering/WiiU.cpp
@@ -722,7 +722,7 @@
 	}
 }
 
-RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t size)
+RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height)
 {
 	RenderBackend_GlyphAtlas *atlas = (RenderBackend_GlyphAtlas*)malloc(sizeof(RenderBackend_GlyphAtlas));
 
@@ -730,8 +730,8 @@
 	{
 		// Initialise texture
 		memset(&atlas->texture, 0, sizeof(atlas->texture));
-		atlas->texture.surface.width = size;
-		atlas->texture.surface.height = size;
+		atlas->texture.surface.width = width;
+		atlas->texture.surface.height = height;
 		atlas->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8;
 		atlas->texture.surface.depth = 1;
 		atlas->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
--- a/src/Font.cpp
+++ b/src/Font.cpp
@@ -12,8 +12,6 @@
 #include "File.h"
 #include "Backends/Rendering.h"
 
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
 // Cave Story wasn't intended to use font anti-aliasing. It's only because Microsoft enabled it
 // by default from Windows Vista onwards that the game started using it.
 // Font anti-aliasing conflicts with the game's colour-keying, causing ugly artifacting around
@@ -1087,7 +1085,7 @@
 
 					font->atlas_row_length = atlas_columns;
 
-					font->atlas = RenderBackend_CreateGlyphAtlas(MAX(atlas_columns * atlas_entry_width, atlas_rows * atlas_entry_height));
+					font->atlas = RenderBackend_CreateGlyphAtlas(atlas_columns * atlas_entry_width, atlas_rows * atlas_entry_height);
 
 					if (font->atlas != NULL)
 					{