From b46aa05b9cc2523d15c7fb25fe9dfd6c67252183 Mon Sep 17 00:00:00 2001 From: rexim Date: Sun, 15 Jul 2018 01:22:38 +0700 Subject: [PATCH] (#234) Implement sprite_font --- CMakeLists.txt | 2 + credits.org | 2 + fonts/charmap-oldschool_black.bmp | Bin 0 -> 24714 bytes fonts/charmap-oldschool_white.bmp | Bin 0 -> 24714 bytes src/game/sprite_font.c | 128 ++++++++++++++++++++++++++++++ src/game/sprite_font.h | 21 +++++ src/main.c | 20 +++++ 7 files changed, 173 insertions(+) create mode 100644 fonts/charmap-oldschool_black.bmp create mode 100644 fonts/charmap-oldschool_white.bmp create mode 100644 src/game/sprite_font.c create mode 100644 src/game/sprite_font.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f550000..87e5add9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/credits.org b/credits.org index 0eb4b754..538cb8a5 100644 --- a/credits.org +++ b/credits.org @@ -2,3 +2,5 @@ - https://freesound.org/people/Unaxete/ - sounds/nothing.mp3 - sounds/something.mp3 +- Fonts: + - https://opengameart.org/content/ascii-bitmap-font-oldschool diff --git a/fonts/charmap-oldschool_black.bmp b/fonts/charmap-oldschool_black.bmp new file mode 100644 index 0000000000000000000000000000000000000000..76d459f9ee97e248883706e9b43e65c6c38c1077 GIT binary patch literal 24714 zcmeI0v5p)>5JcAkApxOf1m6d2;dW+0*N*tM4zau0H$g)vM2c`r_|T zzWeRvk9Ypf=2I_jLe^OuSQ}UySQ}UySQ}UySQ}UySQ}UySQ}UySQ}Uyxc?1||3#wy z8^sKB|F3>j6Y5I!^_u)V`KWeu&tGPKtMkfxe)40BPm4_@-*$$VCT;<|3)Bs0OWZDK zZf}xA2JqyCXExAW-8?xnVrj-3sN0@l#+j?THn29ZHlPjo|4+aH{IDxXXL?xTURQi* zdV+x+ivywnsjI-+6+a_xdc)}a0M|hSZ)&BIDF7EZ8N7~@U_fZVfF8L`eD?zv;NAXR zz#Ob%$I@teS(?&b|FaSwYIgD5c*?IgW}hhfF0TK1vsWlT3USI|Bx2 zV)eSfHByQRjSgf|Mz_~;-d(%M{YHiR?KzJ98DPMS5^)7#_k#e^889GZV1Se0ao5L% zQm2wIfSq=`@F>*+MCmvgQU_etjNOmJQ>EU}55dcn9 zl5+~+4S+}k1CArz#Uq=U>NZ?isc!VhdC(L#bAJsJBSQ1hleRGcxRee z-rAb+YD)E1W-=`qXI#Dar>Iq~4SeJq&@UzZUYrc96#>%55W~9?j7-4AmGQ1{(;j3~ zS;=5XXm%k{3W)Cws+m;}Be6>EUNQoJE1M(&K*$`AOOycDJ9)%(w}Sx$_9nX0F~&p= z%9&QuXv&z3E&_mmok2)yVF%QlWN`tm0FGs8DrwP`acr+H7>r`Pbj-LU3k}CJngJPf0C*?GJL4|LNl6RP3xVIOOoCLB z<1ax2@NTt8hB$y@>0vzTJ(B(^A2FCdX!*lP-b*3?j9)@>dP&pnB*q}c1JXow&p`4d z0p`}Sw)A-CVFUY<-ezz{p_qD){=yqzr*Gj)|%v z?s7{H*CxT0OK`-O1}{&rT8X^WdNE+CmlylDhJ7G&FDkp z$1{UZL&fwowd=|hHE!{wu}s~)b5n?y)vM9X4iYN7wC2^EGDK^NxOcGF5Z?m-> zy!()5S8YErRxqz5*+aq}rQdW#Qtkya`q21MW-tMC*D21AmC5VIaVwNMV_E7RUB)cD zV1Ix}T8PJ>>YF(|GI$+LNfJ35aq$dTL81&BfWUe_g-hQ9*{s;KfGjHahjr$Ls^t{jj literal 0 HcmV?d00001 diff --git a/fonts/charmap-oldschool_white.bmp b/fonts/charmap-oldschool_white.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9e3ec0e6a3de4f6d914df1e1db4230ffd72d5b48 GIT binary patch literal 24714 zcmeH{v5p)>5JcAkApxOEZf3kNcPSdlr9>s=w>{ z`g(ad=-;dA<&*D!{Q23R|9tcGk1sy^^4Gr~Jbv`(;j^o&uODAsef0Z_7axE3$zLCQ z_0w05rCoDbby-@y7-*Oi{X@yQLO#ikPb3NKCE0(dv58_<@xUC?fCkwgaY z-Q6458`vAr2K@gMZ~#B-3euSomUz?^ADWS1V#nfu zC_w5euy)0-h+A(MouA-3XyQ$+R5AtN0w;slaS{v&4Hz&YZxY}9zy)}-|GIJkxPmZ1 zf=A4Ve?9exTuH2&lh)CF^NF&8l!;MFzmswv6Q*N4 z9@2_Oq#Gxhv;y!dVU@~vS;fg)OIcduq~-5%*=5+%z<|gE1I{A-Ri5CyaO!#q7Vz7> z$OvCyJOLwMJps$PAVzTHjgk;BfK~t}!2$fB4-yP$m6K#Qf|DM8G!X&dmP&GN19$@< z(!hYrNO$qbHdEcU)siH8cSP3kb!Ma#fAJm9)*<0Yy!wO;0N;`>u1XjI5}b$BEXvRb z16;6966p4tT)Pt^Vt}8$%55N-#137gxr+!mT~XR$0klNNBr| zCBhu}mQJF}2oeZo)Y?KurRj)qj27q@`yff}{oRqWxqY(I$$|Oi7IsOtf0Pj|d zWQYSemLA5V-XiI*@)48ila@b>5@2pEYfF!J z9!7u==a~rUOvT7fW`>}(Ljq1JlfXwuh{{Ad?}HFSx-z=rk$Eg#Sv+Cmy@B_61MTl6 z76Me_Cw +#include +#include +#include + +#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; +} diff --git a/src/game/sprite_font.h b/src/game/sprite_font.h new file mode 100644 index 00000000..9e454b20 --- /dev/null +++ b/src/game/sprite_font.h @@ -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_ diff --git a/src/main.c b/src/main.c index 934a5e07..1da1fe9f 100644 --- a/src/main.c +++ b/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;