diff options
| author | Paul Duncan <pabs@pablotron.org> | 2019-01-14 00:26:18 -0500 | 
|---|---|---|
| committer | Paul Duncan <pabs@pablotron.org> | 2019-01-14 00:26:18 -0500 | 
| commit | 55d22c6e36b6b575a971202cb62e53a3a6fb54cb (patch) | |
| tree | 738b7e8ad43417187c72ca8a034efa167ea6e95a | |
| parent | 5d63ee685c19e2e696a99cce6f0b9fc8cf8ff7de (diff) | |
| download | sok-55d22c6e36b6b575a971202cb62e53a3a6fb54cb.tar.xz sok-55d22c6e36b6b575a971202cb62e53a3a6fb54cb.zip  | |
add moves and header text, won bg animation, window title
| -rw-r--r-- | assets/roboto.ttf | bin | 0 -> 171676 bytes | |||
| -rw-r--r-- | meson.build | 1 | ||||
| -rw-r--r-- | src/sdl/color.c | 2 | ||||
| -rw-r--r-- | src/sdl/draw.c | 140 | ||||
| -rw-r--r-- | src/sdl/draw.h | 2 | ||||
| -rw-r--r-- | src/sdl/main.c | 75 | 
6 files changed, 198 insertions, 22 deletions
diff --git a/assets/roboto.ttf b/assets/roboto.ttf Binary files differnew file mode 100644 index 0000000..2c97eea --- /dev/null +++ b/assets/roboto.ttf diff --git a/meson.build b/meson.build index 4c241e7..5c826a7 100644 --- a/meson.build +++ b/meson.build @@ -31,6 +31,7 @@ executable('sok-sdl', sources + [    'src/sdl/main.c',  ], dependencies: [    dependency('SDL2'), +  dependency('SDL2_ttf'),    libm,  ]) diff --git a/src/sdl/color.c b/src/sdl/color.c index cb94095..16c7cfd 100644 --- a/src/sdl/color.c +++ b/src/sdl/color.c @@ -5,7 +5,7 @@  static const SDL_Color  PALETTE[] = {    { .r = 0x00, .g = 0x00, .b = 0x00, .a = 0xFF }, // COLOR_BG -  { .r = 0x00, .g = 0xFF, .b = 0x00, .a = 0xFF }, // COLOR_BG_WON +  { .r = 0x00, .g = 0x66, .b = 0x00, .a = 0xFF }, // COLOR_BG_WON    { .r = 0x66, .g = 0x66, .b = 0x66, .a = 0xFF }, // COLOR_WALL    { .r = 0x00, .g = 0xFF, .b = 0x00, .a = 0xFF }, // COLOR_GOAL    { .r = 0xFF, .g = 0x00, .b = 0x00, .a = 0xFF }, // COLOR_HOME diff --git a/src/sdl/draw.c b/src/sdl/draw.c index 4449b52..aa16bca 100644 --- a/src/sdl/draw.c +++ b/src/sdl/draw.c @@ -1,4 +1,5 @@  #include <stdbool.h> // bool +#include <math.h> // sinf()  #include "util.h" // warn()/die()  #include "color.h" // set_color()  #include "draw.h" @@ -251,17 +252,154 @@ DRAW_CBS = {  };  #endif /* DRAW_SPRITES */ +static const SDL_Color +TEXT_COLORS[] = { +  { 0xff, 0xff, 0xff, 0xff }, // fg +  { 0x00, 0x00, 0x00, 0xff }, // bg +}; + +static void +draw_text( +  draw_ctx_t * const draw_ctx, +  const char * const buf, +  const SDL_Rect * const rect +) { +  // create surface +  SDL_Surface *surface = TTF_RenderText_Shaded( +    draw_ctx->font, +    buf, +    TEXT_COLORS[0], +    TEXT_COLORS[1] +  ); + +  // check for error +  if (!surface) { +    die("TTF_RenderText_Blended(): %s", TTF_GetError()); +  } + +  // create texture +  SDL_Texture *texture = SDL_CreateTextureFromSurface(draw_ctx->renderer, surface); +  if (!texture) { +    die("SDL_CreateTextureFromSurface(): %s", SDL_GetError()); +  } + +  // free surface +  SDL_FreeSurface(surface); + +  // render text +  if (SDL_RenderCopy(draw_ctx->renderer, texture, NULL, rect)) { +    die("SDL_RenderCopy(): %s", SDL_GetError()); +  } + +  // free texture +  SDL_DestroyTexture(texture); +} + +static void +draw_level_text( +  draw_ctx_t * const draw_ctx +) { +  // build text +  char buf[256]; +  snprintf( +    buf, sizeof(buf), +    "%s: %s (#%zu)", +    draw_ctx->level->pack, +    draw_ctx->level->name, +    *draw_ctx->level_num +  ); + +  // get renderer width +  int renderer_w; +  if (SDL_GetRendererOutputSize(draw_ctx->renderer, &renderer_w, NULL)) { +    die("SDL_GetRendererOutputSize(): %s", SDL_GetError()); +  } + +  // get text size +  int text_w, text_h; +  if (TTF_SizeText(draw_ctx->font, buf, &text_w, &text_h)) { +    die("TTF_SizeText(): %s", TTF_GetError()); +  } + +  // build rect +  const SDL_Rect rect = { (renderer_w - text_w) / 2, 10, text_w, text_h }; + +  // draw text +  draw_text(draw_ctx, buf, &rect); +} + +static void +draw_moves_text( +  draw_ctx_t * const draw_ctx +) { +  // build text +  char buf[256]; +  snprintf(buf, sizeof(buf), "Moves: %zu", draw_ctx->ctx->num_moves); + +  // get renderer height +  int renderer_h; +  if (SDL_GetRendererOutputSize(draw_ctx->renderer, NULL, &renderer_h)) { +    die("SDL_GetRendererOutputSize(): %s", SDL_GetError()); +  } + +  // get text size +  int text_w, text_h; +  if (TTF_SizeText(draw_ctx->font, buf, &text_w, &text_h)) { +    die("TTF_SizeText(): %s", TTF_GetError()); +  } + +  // build rect +  const SDL_Rect rect = { 10, renderer_h - text_h - 10, text_w, text_h }; + +  // draw text +  draw_text(draw_ctx, buf, &rect); +} + +static void +set_bg_won_color( +  draw_ctx_t * const draw_ctx +) { +  const Uint32 ticks = SDL_GetTicks(); + +  // gen color +  const SDL_Color c = { +    .r = 0x66 + 0x33 * sinf((1000 + ticks) * 2.0 * 3.14159 / 2000.0), +    .g = 0x66 + 0x33 * sinf((3000 + ticks) * 2.0 * 3.14159 / 5000.0), +    .b = 0x66 + 0x33 * sinf((5000 + ticks) * 2.0 * 3.14159 / 7000.0), +    .a = 0xFF, +  }; + +  // set color +  if (SDL_SetRenderDrawColor(draw_ctx->renderer, c.r, c.g, c.b, c.a)) { +    die("SDL_SetRenderDrawColor(): %s", SDL_GetError()); +  } +} +  void  draw(    draw_ctx_t * const draw_ctx  ) { +  const bool is_done = sok_ctx_is_done(draw_ctx->ctx); + +  // set bg color +  if (sok_ctx_is_done(draw_ctx->ctx)) { +    // set bg won color +    set_bg_won_color(draw_ctx); +  } else { +    // set normal bg color +    set_color(draw_ctx->renderer, is_done ? COLOR_BG_WON : COLOR_BG); +  } +    // clear background -  set_color(draw_ctx->renderer, sok_ctx_is_done(draw_ctx->ctx) ? COLOR_BG_WON : COLOR_BG);    SDL_RenderClear(draw_ctx->renderer);    // render    sok_ctx_walk(draw_ctx->ctx, &DRAW_CBS, draw_ctx); +  // render text +  draw_level_text(draw_ctx); +  draw_moves_text(draw_ctx); +      // flip    SDL_RenderPresent(draw_ctx->renderer);  } diff --git a/src/sdl/draw.h b/src/sdl/draw.h index 873287a..b8aeed4 100644 --- a/src/sdl/draw.h +++ b/src/sdl/draw.h @@ -3,6 +3,7 @@  #include <stddef.h> // size_t  #include <SDL.h> +#include <SDL_ttf.h>  #include "../libsok/sok.h"   #include "../text/levels.h" @@ -12,6 +13,7 @@  typedef struct {    SDL_Renderer * const renderer;    SDL_Texture *sprites[MAX_SPRITES]; +  TTF_Font *font;    const sok_ctx_t * const ctx;    const size_t * const level_num; diff --git a/src/sdl/main.c b/src/sdl/main.c index 9341f4a..5eca49c 100644 --- a/src/sdl/main.c +++ b/src/sdl/main.c @@ -94,11 +94,40 @@ solve_on_error(    die("Error solving level: %s", err);  } +static void +set_level( +  SDL_Window * const win, +  draw_ctx_t * const draw_ctx, +  sok_ctx_t * const ctx, +  const size_t level_num +) { +  // get level data +  draw_ctx->level = levels_get_level(level_num); + +  // load level +  if (!sok_ctx_set_level(ctx, draw_ctx->level->data)) { +    die("Couldn't load level %zu", level_num); +  } + +  // build title +  char buf[1024]; +  snprintf( +    buf, sizeof(buf), +    "Sokoban: %s: %s (#%zu)", +    draw_ctx->level->pack, +    draw_ctx->level->name, +    level_num +  ); + +  // set window title +  SDL_SetWindowTitle(win, buf); +} +  int main(int argc, char *argv[]) {    size_t level_num = (argc > 1) ? atoi(argv[1]) : 0,           zoom = 0; -  const level_t *level = levels_get_level(level_num);    const char *sprites_png_path = "../assets/sprites.png"; +  const char *font_path = "../assets/roboto.ttf";    // init warp buffer    warp_buf_t warp_buf; @@ -108,10 +137,6 @@ int main(int argc, char *argv[]) {    sok_ctx_t ctx;    sok_ctx_init(&ctx, NULL); -  if (!sok_ctx_set_level(&ctx, level->data)) { -    die("Couldn't load level %zu", level_num); -  } -    // init sdl    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {      die("SDL_Init(): %s", SDL_GetError()); @@ -119,7 +144,18 @@ int main(int argc, char *argv[]) {    // register exit handler    if (atexit(SDL_Quit)) { -    die("atexit(): %s", strerror(errno)); +    die("atexit(SDL_Init): %s", strerror(errno)); +    exit(EXIT_FAILURE); +  } + +  // init SDL_TTF +  if (TTF_Init()) { +    die("TTF_Init(): %s", TTF_GetError()); +  } + +  // register exit handler +  if (atexit(TTF_Quit)) { +    die("atexit(TTF_Quit): %s", strerror(errno));      exit(EXIT_FAILURE);    } @@ -135,15 +171,23 @@ int main(int argc, char *argv[]) {    // init draw context    draw_ctx_t draw_ctx = {      .level_num  = &level_num, -    .level      = level,      .ctx        = &ctx,      .renderer   = renderer,      .zoom       = &zoom,    }; +  // set level +  set_level(win, &draw_ctx, &ctx, level_num); +    // init sprites    sprites_init(renderer, sprites_png_path, draw_ctx.sprites); +  // load font +  draw_ctx.font = TTF_OpenFontIndex(font_path, 16, 0); +  if (!draw_ctx.font) { +    die("TTF_OpenFontIndex(): %s", TTF_GetError()); +  } +    bool done = false;    SDL_Event ev;    while (!done) { @@ -176,13 +220,9 @@ int main(int argc, char *argv[]) {          if (sok_ctx_is_done(&ctx)) {            // advance level            level_num++; -          level = levels_get_level(level_num); -          draw_ctx.level = level; -          // load next level -          if (!sok_ctx_set_level(&ctx, level->data)) { -            die("Couldn't load level %zu", level_num); -          } +          // set level +          set_level(win, &draw_ctx, &ctx, level_num);          } else {            warn("cannot advance to next level");          } @@ -190,20 +230,15 @@ int main(int argc, char *argv[]) {          break;        case ACTION_RESET:          // reset level -        if (!sok_ctx_set_level(&ctx, level->data)) { +        if (!sok_ctx_set_level(&ctx, draw_ctx.level->data)) {            die("Couldn't load level %zu", level_num);          }          break;        case ACTION_WARP:          if (warp_buf_get(&warp_buf, &level_num)) { -          level = levels_get_level(level_num); -          draw_ctx.level = level; -            // load level -          if (!sok_ctx_set_level(&ctx, level->data)) { -            die("Couldn't load level %zu", level_num); -          } +          set_level(win, &draw_ctx, &ctx, level_num);            // clear warp buf            warp_buf_clear(&warp_buf);  | 
