(#234) Implement sprite_font
parent
6f8738fed0
commit
b46aa05b9c
|
@ -35,6 +35,7 @@ set(SOURCE_FILES
|
|||
src/game/level/player/rigid_rect.c
|
||||
src/game/level/solid.c
|
||||
src/game/sound_samples.c
|
||||
src/game/sprite_font.c
|
||||
src/main.c
|
||||
src/math/mat3x3.c
|
||||
src/math/point.c
|
||||
|
@ -65,6 +66,7 @@ set(HEADER_FILES
|
|||
src/game/level/player/rigid_rect.h
|
||||
src/game/level/solid.h
|
||||
src/game/sound_samples.h
|
||||
src/game/sprite_font.h
|
||||
src/math/mat3x3.h
|
||||
src/math/pi.h
|
||||
src/math/point.h
|
||||
|
|
|
@ -2,3 +2,5 @@
|
|||
- https://freesound.org/people/Unaxete/
|
||||
- sounds/nothing.mp3
|
||||
- sounds/something.mp3
|
||||
- Fonts:
|
||||
- https://opengameart.org/content/ascii-bitmap-font-oldschool
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
|
@ -0,0 +1,128 @@
|
|||
#include <SDL2/SDL.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sprite_font.h"
|
||||
#include "system/lt.h"
|
||||
#include "system/error.h"
|
||||
|
||||
#define FONT_ROW_SIZE 18
|
||||
#define CHAR_WIDTH 7
|
||||
#define CHAR_HEIGHT 9
|
||||
|
||||
struct sprite_font_t
|
||||
{
|
||||
lt_t *lt;
|
||||
SDL_Surface *surface;
|
||||
SDL_Texture *texture;
|
||||
};
|
||||
|
||||
sprite_font_t *create_sprite_font_from_file(const char *bmp_file_path,
|
||||
SDL_Renderer *renderer)
|
||||
{
|
||||
assert(bmp_file_path);
|
||||
|
||||
lt_t *lt = create_lt();
|
||||
if (lt == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sprite_font_t *sprite_font = PUSH_LT(lt, malloc(sizeof(sprite_font_t)), free);
|
||||
if (sprite_font == NULL) {
|
||||
throw_error(ERROR_TYPE_LIBC);
|
||||
RETURN_LT(lt, NULL);
|
||||
}
|
||||
|
||||
sprite_font->surface = PUSH_LT(lt, SDL_LoadBMP(bmp_file_path), SDL_FreeSurface);
|
||||
if (sprite_font->surface == NULL) {
|
||||
throw_error(ERROR_TYPE_SDL2);
|
||||
RETURN_LT(lt, NULL);
|
||||
}
|
||||
|
||||
sprite_font->texture = PUSH_LT(
|
||||
lt,
|
||||
SDL_CreateTextureFromSurface(renderer, sprite_font->surface),
|
||||
SDL_DestroyTexture);
|
||||
if (sprite_font->texture == NULL) {
|
||||
throw_error(ERROR_TYPE_SDL2);
|
||||
RETURN_LT(lt, NULL);
|
||||
}
|
||||
|
||||
sprite_font->lt = lt;
|
||||
|
||||
return sprite_font;
|
||||
}
|
||||
|
||||
void destroy_sprite_font(sprite_font_t *sprite_font)
|
||||
{
|
||||
assert(sprite_font);
|
||||
RETURN_LT0(sprite_font->lt);
|
||||
}
|
||||
|
||||
static SDL_Rect sprite_font_char_rect(const sprite_font_t *sprite_font, char x)
|
||||
{
|
||||
assert(sprite_font);
|
||||
|
||||
if (32 <= x && x <= 126) {
|
||||
const SDL_Rect rect = {
|
||||
.x = ((x - 32) % FONT_ROW_SIZE) * CHAR_WIDTH,
|
||||
.y = ((x - 32) / FONT_ROW_SIZE) * CHAR_HEIGHT,
|
||||
.w = CHAR_WIDTH,
|
||||
.h = CHAR_HEIGHT
|
||||
};
|
||||
return rect;
|
||||
} else {
|
||||
return sprite_font_char_rect(sprite_font, '?');
|
||||
}
|
||||
}
|
||||
|
||||
int sprite_font_render_text(const sprite_font_t *sprite_font,
|
||||
SDL_Renderer *renderer,
|
||||
vec_t position,
|
||||
int size,
|
||||
const char *text)
|
||||
{
|
||||
assert(sprite_font);
|
||||
assert(renderer);
|
||||
assert(text);
|
||||
|
||||
const size_t text_size = strlen(text);
|
||||
const int px = (int) roundf(position.x);
|
||||
const int py = (int) roundf(position.y);
|
||||
for (size_t i = 0; i < text_size; ++i) {
|
||||
const SDL_Rect char_rect = sprite_font_char_rect(sprite_font, text[i]);
|
||||
const SDL_Rect dest_rect = {
|
||||
.x = px + CHAR_WIDTH * (int) i * size,
|
||||
.y = py,
|
||||
.w = char_rect.w * size,
|
||||
.h = char_rect.h * size
|
||||
};
|
||||
if (SDL_RenderCopy(renderer, sprite_font->texture, &char_rect, &dest_rect) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sprite_font_debug_render_whole_texture(const sprite_font_t *sprite_font,
|
||||
SDL_Renderer *renderer,
|
||||
vec_t position)
|
||||
{
|
||||
int texW = 0;
|
||||
int texH = 0;
|
||||
|
||||
if (SDL_QueryTexture(sprite_font->texture, NULL, NULL, &texW, &texH) < 0) {
|
||||
throw_error(ERROR_TYPE_SDL2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const SDL_Rect dstrect = { (int) position.x, (int) position.y, texW, texH };
|
||||
|
||||
if (SDL_RenderCopy(renderer, sprite_font->texture, NULL, &dstrect) < 0) {
|
||||
throw_error(ERROR_TYPE_SDL2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef SPRITE_FONT_H_
|
||||
#define SPRITE_FONT_H_
|
||||
|
||||
#include "math/point.h"
|
||||
|
||||
typedef struct sprite_font_t sprite_font_t;
|
||||
|
||||
sprite_font_t *create_sprite_font_from_file(const char *bmp_file_path,
|
||||
SDL_Renderer *renderer);
|
||||
void destroy_sprite_font(sprite_font_t *sprite_font);
|
||||
|
||||
int sprite_font_render_text(const sprite_font_t *sprite_font,
|
||||
SDL_Renderer *renderer,
|
||||
vec_t position,
|
||||
int size,
|
||||
const char *text);
|
||||
int sprite_font_debug_render_whole_texture(const sprite_font_t *sprite_font,
|
||||
SDL_Renderer *renderer,
|
||||
vec_t position);
|
||||
|
||||
#endif // SPRITE_FONT_H_
|
20
src/main.c
20
src/main.c
|
@ -11,6 +11,7 @@
|
|||
#include "game/level/platforms.h"
|
||||
#include "game/level/player.h"
|
||||
#include "game/sound_samples.h"
|
||||
#include "game/sprite_font.h"
|
||||
#include "math/minmax.h"
|
||||
#include "math/point.h"
|
||||
#include "sdl/renderer.h"
|
||||
|
@ -160,6 +161,15 @@ int main(int argc, char *argv[])
|
|||
RETURN_LT(lt, -1);
|
||||
}
|
||||
|
||||
sprite_font_t * const sprite_font =
|
||||
PUSH_LT(lt,
|
||||
create_sprite_font_from_file("fonts/charmap-oldschool_white.bmp", renderer),
|
||||
destroy_sprite_font);
|
||||
if (sprite_font == NULL) {
|
||||
print_current_error_msg("Loading up sprite font");
|
||||
RETURN_LT(lt, -1);
|
||||
}
|
||||
|
||||
const Uint8 *const keyboard_state = SDL_GetKeyboardState(NULL);
|
||||
|
||||
SDL_Event e;
|
||||
|
@ -194,6 +204,16 @@ int main(int argc, char *argv[])
|
|||
print_current_error_msg("Failed rendering the game");
|
||||
RETURN_LT(lt, -1);
|
||||
}
|
||||
|
||||
if (sprite_font_render_text(sprite_font,
|
||||
renderer,
|
||||
vec(0.0f, 0.0f),
|
||||
1,
|
||||
"HELLO, WORLD!!!") < 0) {
|
||||
print_current_error_msg("Failed rendering debug info");
|
||||
RETURN_LT(lt, -1);
|
||||
}
|
||||
|
||||
const int64_t end_frame_time = (int64_t) SDL_GetTicks();
|
||||
|
||||
render_timer -= delta_time;
|
||||
|
|
Loading…
Reference in New Issue