summaryrefslogtreecommitdiff
path: root/gfx-iso/app/checkerboard.c
blob: 8b394c4b0611d66a9c3f6a967e243d597564e3fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "isogfx-demo.h"

#include <gfx/gfx_app.h>
#include <isogfx/isogfx.h>

#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

static const int TILE_WIDTH   = 64;
static const int TILE_HEIGHT  = TILE_WIDTH / 2;
static const int WORLD_WIDTH  = 20;
static const int WORLD_HEIGHT = 20;

static const TileDesc tile_set[] = {
    {.type   = TileFromColour,
     .width  = TILE_WIDTH,
     .height = TILE_HEIGHT,
     .colour = (Pixel){.r = 0x38, .g = 0x3b, .b = 0x46, .a = 0xff}},
    {.type   = TileFromColour,
     .width  = TILE_WIDTH,
     .height = TILE_HEIGHT,
     .colour = (Pixel){.r = 0xA5, .g = 0xb3, .b = 0xc0, .a = 0xff}},
    {.type   = TileFromColour,
     .width  = TILE_WIDTH,
     .height = TILE_HEIGHT,
     .colour = (Pixel){.r = 0xdc, .g = 0x76, .b = 0x84, .a = 0xff}},
};

typedef enum Colour {
  Black,
  White,
  Red,
} Colour;

typedef struct State {
  Tile red;
  int  xpick;
  int  ypick;
} State;

static void make_checkerboard(IsoGfx* iso, Tile black, Tile white) {
  assert(iso);
  for (int y = 0; y < isogfx_world_height(iso); ++y) {
    for (int x = 0; x < isogfx_world_width(iso); ++x) {
      const int  odd_col = x & 1;
      const int  odd_row = y & 1;
      const Tile value   = (odd_row ^ odd_col) == 0 ? black : white;
      isogfx_set_tile(iso, x, y, value);
    }
  }
}

static void shutdown(IsoGfx* iso, void* app_state) {
  assert(iso);
  if (app_state) {
    free(app_state);
  }
}

static void update(IsoGfx* iso, void* app_state, double t, double dt) {
  assert(iso);
  assert(app_state);
  State* state = (State*)(app_state);

  double mouse_x, mouse_y;
  gfx_app_get_mouse_position(&mouse_x, &mouse_y);

  isogfx_pick_tile(iso, mouse_x, mouse_y, &state->xpick, &state->ypick);

  printf("Picked tile: (%d, %d)\n", state->xpick, state->ypick);
}

static void render(IsoGfx* iso, void* app_state) {
  assert(iso);
  assert(app_state);
  State* state = (State*)(app_state);

  isogfx_render(iso);
  if ((state->xpick != -1) && (state->ypick != -1)) {
    isogfx_draw_tile(iso, state->xpick, state->ypick, state->red);
  }
}

bool make_checkerboard_app(IsoGfx* iso, IsoGfxApp* app) {
  assert(iso);
  assert(app);

  State* state = calloc(1, sizeof(State));
  if (!state) {
    return false;
  }

  if (!isogfx_make_world(
          iso, &(WorldDesc){
                   .tile_width   = TILE_WIDTH,
                   .tile_height  = TILE_HEIGHT,
                   .world_width  = WORLD_WIDTH,
                   .world_height = WORLD_HEIGHT})) {
    goto cleanup;
  }

  const Tile black = isogfx_make_tile(iso, &tile_set[Black]);
  const Tile white = isogfx_make_tile(iso, &tile_set[White]);
  state->red       = isogfx_make_tile(iso, &tile_set[Red]);
  make_checkerboard(iso, black, white);
  isogfx_render(iso);

  app->state    = state;
  app->shutdown = shutdown;
  app->update   = update;
  app->render   = render;

  return true;

cleanup:
  free(state);
  return false;
}