Skip to content

Commit 79cf00c

Browse files
committed
Add transparent index and optimize font rendering with shadows.
1 parent 96fdc35 commit 79cf00c

28 files changed

+280
-72
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ if(MSVC)
3838
string(REGEX REPLACE "/W3" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
3939
# we would probably like to pass /Wall instead of /W4, but there's a lot
4040
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /permissive- /W4")
41+
#LibPNG is not linking on MSVC correctly, disable it.
42+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMIN_BUILD")
4143
else()
4244
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wformat -pedantic -Wvla")
4345
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -DDEBUGMODE -Werror -fno-omit-frame-pointer")
@@ -235,6 +237,8 @@ add_dependencies(openomf copy_shaders)
235237

236238
# Build tools if requested
237239
set(TOOL_TARGET_NAMES)
240+
241+
238242
# always build languagetool, for BuildLanguages.cmake
239243
add_executable(languagetool tools/languagetool/main.c)
240244
list(APPEND TOOL_TARGET_NAMES languagetool)

src/formats/bk.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "formats/internal/writer.h"
1111
#include "formats/palette.h"
1212
#include "formats/pcx.h"
13+
#include "formats/transparent.h"
1314
#include "formats/vga_image.h"
1415
#include "utils/allocator.h"
1516

@@ -134,7 +135,7 @@ int sd_bk_load(sd_bk_file *bk, const char *filename) {
134135

135136
// Read background image
136137
bk->background = omf_calloc(1, sizeof(sd_vga_image));
137-
if((ret = sd_vga_image_create(bk->background, img_w, img_h)) != SD_SUCCESS) {
138+
if((ret = sd_vga_image_create(bk->background, img_w, img_h, BACKGROUND_TRANSPARENT_INDEX)) != SD_SUCCESS) {
138139
goto exit_0;
139140
}
140141
int bsize = img_w * img_h;

src/formats/fonts.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "formats/fonts.h"
55
#include "formats/internal/reader.h"
66
#include "formats/internal/writer.h"
7+
#include <assert.h>
78

89
int sd_font_create(sd_font *font) {
910
if(font == NULL) {
@@ -57,18 +58,20 @@ int sd_font_save(const sd_font *font, const char *file) {
5758
return SD_SUCCESS;
5859
}
5960

60-
int sd_font_decode(const sd_font *font, sd_vga_image *o, uint8_t ch, uint8_t color) {
61+
int sd_font_decode(const sd_font *font, sd_vga_image *o, uint8_t ch, uint8_t color, int transparent) {
6162
if(font == NULL || o == NULL || ch >= 224) {
6263
return SD_INVALID_INPUT;
6364
}
6465

66+
assert((transparent >= 0) && (transparent < 256));
67+
6568
int t = 0;
6669
for(unsigned i = 0; i < font->h; i++) {
6770
for(int k = font->h - 1; k >= 0; k--) {
6871
if(font->chars[ch].data[i] & (1 << k)) {
6972
o->data[t] = color;
7073
} else {
71-
o->data[t] = 0;
74+
o->data[t] = (char)transparent;
7275
}
7376
t++;
7477
}

src/formats/fonts.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ int sd_font_save(const sd_font *font, const char *filename);
9393
* \param ch Character to load. Must be 0 <= ch <= 224.
9494
* \param color Color palette index (0 - 0xFF)
9595
*/
96-
int sd_font_decode(const sd_font *font, sd_vga_image *surface, uint8_t ch, uint8_t color);
96+
int sd_font_decode(const sd_font *font, sd_vga_image *surface, uint8_t ch, uint8_t color, int transparent);
9797

9898
/**
9999
* Same as sd_font_decode, but decodes to an RGBA surface.

src/formats/pcx.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include "formats/pcx.h"
22
#include "formats/error.h"
33
#include "formats/internal/reader.h"
4+
#include "formats/transparent.h"
45
#include "utils/allocator.h"
6+
#include <assert.h>
57
#include <inttypes.h>
68
#include <stdio.h>
79
#include <string.h>
@@ -69,7 +71,7 @@ int pcx_load(pcx_file *pcx, const char *filename) {
6971
}
7072

7173
int ret;
72-
if((ret = sd_vga_image_create(&(pcx->image), 320, 200)) != SD_SUCCESS) {
74+
if((ret = sd_vga_image_create(&(pcx->image), 320, 200, FONT_TRANSPARENT_INDEX)) != SD_SUCCESS) {
7375
return ret;
7476
}
7577

@@ -141,19 +143,22 @@ int pcx_load_font(pcx_font *font, const char *filename) {
141143
return SD_SUCCESS;
142144
}
143145

144-
int pcx_font_decode(const pcx_font *font, sd_vga_image *o, uint8_t ch, int8_t palette_offset) {
146+
int pcx_font_decode(const pcx_font *font, sd_vga_image *o, uint8_t ch, int8_t palette_offset, int transparent) {
145147
if(ch >= font->glyph_count || font == NULL || o == NULL) {
146148
return SD_INVALID_INPUT;
147149
}
148150

151+
// Fonts always need to have a transparent value.
152+
assert((transparent >= 0) && (transparent < 256));
153+
149154
int k = 0;
150155
for(int i = font->glyphs[ch].y; i < font->glyphs[ch].y + font->glyph_height; i++) {
151156
int l = 0;
152157
for(int j = font->glyphs[ch].x; j < font->glyphs[ch].x + font->glyphs[ch].width; j++) {
153158
if(font->pcx.image.data[(i * 320) + j]) {
154159
o->data[(k * font->glyphs[ch].width) + l] = palette_offset + (int)font->pcx.image.data[(i * 320) + j];
155160
} else {
156-
o->data[(k * font->glyphs[ch].width) + l] = 0;
161+
o->data[(k * font->glyphs[ch].width) + l] = transparent;
157162
}
158163

159164
l++;

src/formats/pcx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ typedef struct {
4949

5050
int pcx_load(pcx_file *pcx, const char *filename);
5151
int pcx_load_font(pcx_font *font, const char *filename);
52-
int pcx_font_decode(const pcx_font *font, sd_vga_image *o, uint8_t ch, int8_t palette_offset);
52+
int pcx_font_decode(const pcx_font *font, sd_vga_image *o, uint8_t ch, int8_t palette_offset, int transparent);
5353
void pcx_free(pcx_file *pcx);
5454
void pcx_font_free(pcx_font *font);
5555

src/formats/sprite.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "formats/error.h"
55
#include "formats/palette.h"
66
#include "formats/sprite.h"
7+
#include "formats/transparent.h"
78
#include "utils/allocator.h"
89

910
int sd_sprite_create(sd_sprite *sprite) {
@@ -271,6 +272,7 @@ int sd_sprite_vga_decode(sd_vga_image *dst, const sd_sprite *src) {
271272
uint16_t c = 0;
272273
uint16_t data = 0;
273274
char op = 0;
275+
int transparent = SPRITE_TRANSPARENT_INDEX;
274276

275277
// Make sure we aren't being fed BS
276278
if(dst == NULL || src == NULL) {
@@ -279,9 +281,9 @@ int sd_sprite_vga_decode(sd_vga_image *dst, const sd_sprite *src) {
279281

280282
// If image data length is 0, then size should be 1x1
281283
if(src->len > 0) {
282-
sd_vga_image_create(dst, src->width, src->height);
284+
sd_vga_image_create(dst, src->width, src->height, transparent);
283285
} else {
284-
sd_vga_image_create(dst, 1, 1);
286+
sd_vga_image_create(dst, 1, 1, transparent);
285287
}
286288

287289
// XXX CREDITS.BK has a bunch of 0 width sprites, for some unknown reason
@@ -310,6 +312,7 @@ int sd_sprite_vga_decode(sd_vga_image *dst, const sd_sprite *src) {
310312
uint8_t b = src->data[i];
311313
int pos = ((y * src->width) + x);
312314
dst->data[pos] = b;
315+
assert(b != transparent);
313316
i++; // we read 1 byte
314317
x++;
315318
data--;
@@ -324,6 +327,8 @@ int sd_sprite_vga_decode(sd_vga_image *dst, const sd_sprite *src) {
324327
}
325328
}
326329

330+
dst->transparent = transparent;
331+
327332
// All done. dst should now contain a valid vga image.
328333
return SD_SUCCESS;
329334
}

src/formats/transparent.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*! \file
2+
* \brief Transparent VGA pixel values
3+
* \details Describes the transparancy index value for various engine components.
4+
* \copyright MIT license.
5+
* \date 2024
6+
* \author Andrew Thompson
7+
* \author Tuomas Virtanen
8+
*/
9+
10+
#ifndef TRANSPARENT_H
11+
#define TRANSPARENT_H
12+
13+
// Default's.
14+
// Please do not use the default definitions in the code directly. Define a new value below instead.
15+
// This way all different transparency values are stored in one place.
16+
#define DEFAULT_TRANSPARENT_INDEX 0
17+
#define DEFAULT_NOT_TRANSPARENT -1
18+
19+
// All sprites have holes, these holes need to be transparent.
20+
#define SPRITE_TRANSPARENT_INDEX DEFAULT_TRANSPARENT_INDEX
21+
22+
// Backgrounds have no transparent pixels and need all pixels to be rendered.
23+
#define BACKGROUND_TRANSPARENT_INDEX DEFAULT_NOT_TRANSPARENT
24+
25+
// Force an opaque menu for now.
26+
#define MENU_TRANSPARENT_INDEX DEFAULT_NOT_TRANSPARENT
27+
28+
// Portraits have a transparancy index that needs to offset past other items in the global palette.
29+
// TODO: Should really become default.
30+
#define PORTRAIT_TRANSPARENT_INDEX 0xD0
31+
32+
// Fonts need a transparent index that does not conflict with the lower 8 colors on the N64 otherwise there will be a
33+
// combinatorial explosion.
34+
#define FONT_TRANSPARENT_INDEX DEFAULT_TRANSPARENT_INDEX
35+
#define PCX_FONT_TRANSPARENT_INDEX DEFAULT_TRANSPARENT_INDEX
36+
37+
// Gauges in the player select have an opaque background and are not transparent.
38+
#define GAUGE_TRANSPARENT_INDEX DEFAULT_NOT_TRANSPARENT
39+
40+
#endif

src/formats/vga_image.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
1+
#if !defined(MIN_BUILD)
12
#include <png.h>
3+
#endif
4+
#include <assert.h>
25
#include <stdint.h>
36
#include <stdio.h>
47
#include <stdlib.h>
58
#include <string.h>
69

710
#include "formats/error.h"
11+
#include "formats/transparent.h"
812
#include "formats/vga_image.h"
913
#include "utils/allocator.h"
1014
#include "utils/png_writer.h"
1115

12-
int sd_vga_image_create(sd_vga_image *img, unsigned int w, unsigned int h) {
16+
int sd_vga_image_create(sd_vga_image *img, unsigned int w, unsigned int h, int transparent) {
1317
if(img == NULL) {
1418
return SD_INVALID_INPUT;
1519
}
1620
img->w = w;
1721
img->h = h;
1822
img->len = w * h;
19-
img->data = omf_calloc(1, w * h);
23+
img->transparent = transparent;
24+
img->data = omf_alloc_with_options(1, img->len, ALLOC_HINT_TEXTURE);
25+
assert((img->data != NULL) || (img->len == 0));
26+
if(img->data != NULL) {
27+
memset(img->data, 0, img->len);
28+
}
29+
2030
return SD_SUCCESS;
2131
}
2232

@@ -27,7 +37,8 @@ int sd_vga_image_copy(sd_vga_image *dst, const sd_vga_image *src) {
2737
dst->w = src->w;
2838
dst->h = src->h;
2939
dst->len = src->len;
30-
dst->data = omf_calloc(src->len, 1);
40+
dst->data = omf_malloc(src->len);
41+
dst->transparent = src->transparent;
3142
memcpy(dst->data, src->data, src->len);
3243
return SD_SUCCESS;
3344
}
@@ -36,7 +47,7 @@ void sd_vga_image_free(sd_vga_image *img) {
3647
if(img == NULL) {
3748
return;
3849
}
39-
omf_free(img->data);
50+
omf_free_with_options(img->data, ALLOC_HINT_TEXTURE);
4051
}
4152

4253
int sd_vga_image_decode(sd_rgba_image *dst, const sd_vga_image *src, const vga_palette *pal) {
@@ -62,6 +73,9 @@ int sd_vga_image_decode(sd_rgba_image *dst, const sd_vga_image *src, const vga_p
6273
}
6374

6475
int sd_vga_image_from_png(sd_vga_image *img, const char *filename) {
76+
#if defined(MIN_BUILD)
77+
return 0;
78+
#else
6579
png_structp png_ptr;
6680
png_infop info_ptr;
6781
int ret = SD_SUCCESS;
@@ -136,7 +150,7 @@ int sd_vga_image_from_png(sd_vga_image *img, const char *filename) {
136150
png_read_image(png_ptr, row_pointers);
137151

138152
// Convert
139-
if(sd_vga_image_create(img, w, h) != SD_SUCCESS) {
153+
if(sd_vga_image_create(img, w, h, DEFAULT_NOT_TRANSPARENT) != SD_SUCCESS) {
140154
ret = SD_OUT_OF_MEMORY;
141155
goto error_3;
142156
}
@@ -159,6 +173,7 @@ int sd_vga_image_from_png(sd_vga_image *img, const char *filename) {
159173
fclose(handle);
160174
error_0:
161175
return ret;
176+
#endif
162177
}
163178

164179
int sd_vga_image_to_png(const sd_vga_image *img, const vga_palette *pal, const char *filename) {

src/formats/vga_image.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ typedef struct {
2727
unsigned int h; ///< Pixel height
2828
unsigned int len; ///< Byte length
2929
char *data; ///< Palette representation of image data
30+
int transparent;
3031
} sd_vga_image;
3132

3233
/*! \brief Initialize VGA image structure
@@ -41,7 +42,7 @@ typedef struct {
4142
* \param w Image width in pixels
4243
* \param h Image height in pixels
4344
*/
44-
int sd_vga_image_create(sd_vga_image *img, unsigned int w, unsigned int h);
45+
int sd_vga_image_create(sd_vga_image *img, unsigned int w, unsigned int h, int transparent);
4546

4647
/*! \brief Copy VGA image structure
4748
*

0 commit comments

Comments
 (0)