Skip to content

Commit 5e76088

Browse files
committed
Implement transparent index and put all the different defines in a common location
1 parent 95b33e5 commit 5e76088

File tree

19 files changed

+136
-54
lines changed

19 files changed

+136
-54
lines changed

src/engine.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ void engine_run(engine_init_flags *init_flags) {
240240
// Render scene
241241
uint64_t frame_dt = SDL_GetTicks64() - frame_start;
242242
frame_start = SDL_GetTicks64();
243+
//debugf("s:%llu dt:%llu\n", frame_start, frame_dt);
243244
if(!visual_debugger) {
244245
dynamic_wait += frame_dt;
245246
static_wait += frame_dt;

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
@@ -97,7 +97,7 @@ int sd_font_save(const sd_font *font, const char *filename);
9797
* \param ch Character to load. Must be 0 <= ch <= 224.
9898
* \param color Color palette index (0 - 0xFF)
9999
*/
100-
int sd_font_decode(const sd_font *font, sd_vga_image *surface, uint8_t ch, uint8_t color);
100+
int sd_font_decode(const sd_font *font, sd_vga_image *surface, uint8_t ch, uint8_t color, int transparent);
101101

102102
/**
103103
* Same as sd_font_decode, but decodes to an RGBA surface.

src/formats/palette.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,28 @@
2222
extern "C" {
2323
#endif
2424

25+
// All sprites have holes, these holes need to be transparent.
26+
#define SPRITE_TRANSPARENT_INDEX 0
27+
28+
// Backgrounds have no transparent pixels and need all pixels to be rendered.
29+
#define BACKGROUND_TRANSPARENT_INDEX -1
30+
31+
// Force an opaque menu for now.
32+
#define MENU_TRANSPARENT_INDEX -1
33+
34+
// Portraits have a transparancy that needs to offset past other items in the global palette.
35+
#define PORTRAIT_TRANSPARENT_INDEX 0xD0
36+
37+
// Portrait highlights need a special offset for transparency to not conflict with other entries in the global palette.
38+
#define HIGHLIGHT_TRANSPARENT_INDEX 90
39+
40+
// Fonts need a transparent index that does not conflict with the lower 8 colors on the N64 otherwise there will be a combinatorial explosion.
41+
#define FONT_TRANSPARENT_INDEX 0
42+
#define PCX_FONT_TRANSPARENT_INDEX 0
43+
44+
// Gauges in the player select have an opaque background and are not transparent.
45+
#define GAUGE_TRANSPARENT_INDEX -1
46+
2547
/*! \brief Resolves an RGB color to palette index
2648
*
2749
* Attempts to resolve an RGB color to a palette index. The requested RGB color

src/formats/pcx.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <inttypes.h>
66
#include <stdio.h>
77
#include <string.h>
8+
#include <assert.h>
89

910
static unsigned decode_next_bytes(char *dest, sd_reader *reader) {
1011
uint8_t fst_byte = sd_read_ubyte(reader);
@@ -73,6 +74,7 @@ int pcx_load(pcx_file *pcx, const char *filename) {
7374
return ret;
7475
}
7576

77+
pcx->image.transparent = FONT_TRANSPARENT_INDEX;
7678
for(unsigned j = 0; j < 200; ++j) {
7779
for(unsigned i = 0; i < 320;) {
7880
i += decode_next_bytes(&(pcx->image.data)[(320 * j) + i], reader);
@@ -141,19 +143,21 @@ 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, uint8_t transparent) {
145147
if(ch >= font->glyph_count || font == NULL || o == NULL) {
146148
return SD_INVALID_INPUT;
147149
}
148150

151+
assert((transparent >= 0) && (transparent < 256));
152+
149153
int k = 0;
150154
for(int i = font->glyphs[ch].y; i < font->glyphs[ch].y + font->glyph_height; i++) {
151155
int l = 0;
152156
for(int j = font->glyphs[ch].x; j < font->glyphs[ch].x + font->glyphs[ch].width; j++) {
153157
if(font->pcx.image.data[(i * 320) + j]) {
154158
o->data[(k * font->glyphs[ch].width) + l] = palette_offset + (int)font->pcx.image.data[(i * 320) + j];
155159
} else {
156-
o->data[(k * font->glyphs[ch].width) + l] = 0;
160+
o->data[(k * font->glyphs[ch].width) + l] = transparent;
157161
}
158162

159163
l++;

src/formats/sprite.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ int sd_sprite_vga_decode(sd_vga_image *dst, const sd_sprite *src) {
271271
uint16_t c = 0;
272272
uint16_t data = 0;
273273
char op = 0;
274+
int transparent = SPRITE_TRANSPARENT_INDEX;
274275

275276
// Make sure we aren't being fed BS
276277
if(dst == NULL || src == NULL) {
@@ -284,6 +285,8 @@ int sd_sprite_vga_decode(sd_vga_image *dst, const sd_sprite *src) {
284285
sd_vga_image_create(dst, 1, 1);
285286
}
286287

288+
dst->transparent = SPRITE_TRANSPARENT_INDEX;
289+
287290
// XXX CREDITS.BK has a bunch of 0 width sprites, for some unknown reason
288291
if(src->width == 0 || src->height == 0 || src->len == 0) {
289292
return SD_SUCCESS;
@@ -310,6 +313,9 @@ int sd_sprite_vga_decode(sd_vga_image *dst, const sd_sprite *src) {
310313
uint8_t b = src->data[i];
311314
int pos = ((y * src->width) + x);
312315
dst->data[pos] = b;
316+
if (b == transparent) {
317+
assert(false);
318+
}
313319
i++; // we read 1 byte
314320
x++;
315321
data--;
@@ -324,6 +330,8 @@ int sd_sprite_vga_decode(sd_vga_image *dst, const sd_sprite *src) {
324330
}
325331
}
326332

333+
dst->transparent = transparent;
334+
327335
// All done. dst should now contain a valid vga image.
328336
return SD_SUCCESS;
329337
}

src/formats/vga_image.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
1+
#if !defined(N64_BUILD) && !defined(MIN_BUILD)
12
#include <png.h>
3+
#endif
24
#include <stdint.h>
35
#include <stdio.h>
46
#include <stdlib.h>
57
#include <string.h>
8+
#ifdef N64_BUILD
9+
#include <libdragon.h>
10+
#else
11+
#include <assert.h>
12+
#endif
613

714
#include "formats/error.h"
815
#include "formats/vga_image.h"
16+
#include "formats/palette.h"
917
#include "utils/allocator.h"
1018
#include "utils/png_writer.h"
1119

@@ -16,7 +24,15 @@ int sd_vga_image_create(sd_vga_image *img, unsigned int w, unsigned int h) {
1624
img->w = w;
1725
img->h = h;
1826
img->len = w * h;
27+
img->transparent = BACKGROUND_TRANSPARENT_INDEX;
28+
#ifdef N64_BUILD
29+
assertf(w <= 320 && h <= 240, "w:%X h:%X", w, h);
30+
img->data = malloc_uncached_aligned(64, w * h);
31+
memset(img->data, 0, w * h);
32+
assert(img->data != NULL);
33+
#else
1934
img->data = omf_calloc(1, w * h);
35+
#endif
2036
return SD_SUCCESS;
2137
}
2238

@@ -28,6 +44,7 @@ int sd_vga_image_copy(sd_vga_image *dst, const sd_vga_image *src) {
2844
dst->h = src->h;
2945
dst->len = src->len;
3046
dst->data = omf_calloc(src->len, 1);
47+
dst->transparent = src->transparent;
3148
memcpy(dst->data, src->data, src->len);
3249
return SD_SUCCESS;
3350
}
@@ -36,7 +53,11 @@ void sd_vga_image_free(sd_vga_image *img) {
3653
if(img == NULL) {
3754
return;
3855
}
56+
#ifdef N64_BUILD
57+
free_uncached(img->data);
58+
#else
3959
omf_free(img->data);
60+
#endif
4061
}
4162

4263
int sd_vga_image_decode(sd_rgba_image *dst, const sd_vga_image *src, const vga_palette *pal) {
@@ -62,6 +83,7 @@ int sd_vga_image_decode(sd_rgba_image *dst, const sd_vga_image *src, const vga_p
6283
}
6384

6485
int sd_vga_image_from_png(sd_vga_image *img, const char *filename) {
86+
#if !defined(N64_BUILD) && !defined(MIN_BUILD)
6587
png_structp png_ptr;
6688
png_infop info_ptr;
6789
int ret = SD_SUCCESS;
@@ -159,14 +181,22 @@ int sd_vga_image_from_png(sd_vga_image *img, const char *filename) {
159181
fclose(handle);
160182
error_0:
161183
return ret;
184+
#else
185+
return 0;
186+
#endif
187+
162188
}
163189

164190
int sd_vga_image_to_png(const sd_vga_image *img, const vga_palette *pal, const char *filename) {
191+
#if !defined(N64_BUILD) && !defined(MIN_BUILD)
165192
if(img == NULL || filename == NULL) {
166193
return SD_INVALID_INPUT;
167194
}
168195
if(!png_write_paletted(filename, img->w, img->h, pal, (unsigned char *)img->data)) {
169196
return SD_FILE_OPEN_ERROR;
170197
}
171198
return SD_SUCCESS;
199+
#else
200+
return 0;
201+
#endif
172202
}

src/formats/vga_image.h

Lines changed: 1 addition & 0 deletions
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

src/game/gui/gauge.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "utils/miscmath.h"
55
#include "video/surface.h"
66
#include "video/video.h"
7+
#include "formats/palette.h"
78

89
typedef struct {
910
unsigned int width;
@@ -74,7 +75,7 @@ typedef struct {
7475
} gauge;
7576

7677
static void surface_from_pix_img(surface *sur, const pixel_image *pix) {
77-
surface_create_from_data(sur, pix->width, pix->height, pix->data);
78+
surface_create_from_data(sur, pix->width, pix->height, pix->data, GAUGE_TRANSPARENT_INDEX);
7879
}
7980

8081
static void gauge_render(component *c) {

src/game/gui/menu_background.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "game/gui/menu_background.h"
22
#include "video/image.h"
3+
#include "formats/palette.h"
34

45
#define COLOR_MENU_LINE 252
56
#define COLOR_MENU_BORDER 251
@@ -19,7 +20,7 @@ void menu_background_create(surface *s, int w, int h) {
1920
image_line(&img, 0, y, w - 1, y, COLOR_MENU_LINE);
2021
}
2122
image_rect(&img, 0, 0, w - 1, h - 1, COLOR_MENU_BORDER);
22-
surface_create_from_image(s, &img);
23+
surface_create_from_image(s, &img, MENU_TRANSPARENT_INDEX);
2324
image_free(&img);
2425
}
2526

@@ -36,7 +37,7 @@ void menu_background2_create(surface *s, int w, int h) {
3637
}
3738
image_rect(&img, 1, 1, w - 2, h - 2, COLOR_MENU_BORDER2);
3839
image_rect(&img, 0, 0, w - 2, h - 2, COLOR_MENU_BORDER1);
39-
surface_create_from_image(s, &img);
40+
surface_create_from_image(s, &img, MENU_TRANSPARENT_INDEX);
4041
image_free(&img);
4142
}
4243

@@ -46,6 +47,6 @@ void menu_background_border_create(surface *s, int w, int h) {
4647
image_create(&img, w, h);
4748
image_clear(&img, 0);
4849
image_rect(&img, 0, 0, w - 1, h - 1, COLOR_MENU_BORDER);
49-
surface_create_from_image(s, &img);
50+
surface_create_from_image(s, &img, MENU_TRANSPARENT_INDEX);
5051
image_free(&img);
5152
}

0 commit comments

Comments
 (0)