Back to shtanton's homepage
summaryrefslogtreecommitdiff
path: root/src/all.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/all.c')
-rw-r--r--src/all.c280
1 files changed, 135 insertions, 145 deletions
diff --git a/src/all.c b/src/all.c
index 8e5170c..372690f 100644
--- a/src/all.c
+++ b/src/all.c
@@ -1,114 +1,94 @@
+#ifndef INCLUDE_ALL_C
+#define INCLUDE_ALL_C
+
#include <stddef.h>
#include <stdint.h>
-#if SDL
-#include <string.h>
-#define xmemcpy memcpy
-#else
-#define xmemcpy __builtin_memcpy
-#endif
-
-typedef struct {
- unsigned char r, g, b, a;
-} Color;
-
-typedef enum {
- BUTTON_STATE_IDLE,
- BUTTON_STATE_HOVERED,
- BUTTON_STATE_PRESSED
-} ButtonState;
-
-typedef struct {
- int x, y, w, h;
- Color fill;
- Color border;
-} DrawElement;
-
-typedef struct {
- DrawElement bg;
-} SidePanel;
-
-typedef struct {
- int len;
- DrawElement els[512];
-} DrawList;
-
-#define MEM_SIZE (1<<16)
-#define GRIDWIDTH 16
-#define GRIDHEIGHT 16
-#define TICK_LENGTH 1000
-#define GRID_OFFSET_X 256
-
-typedef struct {
- char *start;
- char *end;
-} Arena;
-
-#define new(a, c, t) ((t *) alloc(a, c, sizeof(t), _Alignof(t)))
-#define affirm(c) while (!(c)) *(volatile int *)0 = 0
-
-static void *alloc(Arena *a, ptrdiff_t count, ptrdiff_t size, ptrdiff_t align) {
- ptrdiff_t pad = -(size_t) a->start & (align - 1);
- affirm(count < (a->end - a->start - pad) / size);
- char *r = a->start + pad;
- a->start += pad + size * count;
- for (ptrdiff_t i = 0; i < count * size; i++) {
- r[i] = 0;
- }
-
- return r;
-}
-
-typedef struct {
- int width, height;
-} UI;
-
-enum {
- BUTTON_RETRY,
- BUTTON_BACK,
- N_BUTTONS,
+#include "types.c"
+#include "levels.c"
+#include "tick.c"
+
+static const Color colors[N_COLORS][4] = {
+ {
+ {255, 255, 255, 255},
+ {255, 255, 255, 255},
+ {255, 255, 255, 255},
+ {255, 255, 255, 255},
+ },
+ {
+ {0, 0, 0, 255},
+ {0, 0, 0, 255},
+ {0, 0, 0, 255},
+ {0, 0, 0, 255},
+ },
+ {
+ {255, 0, 0, 255},
+ {255, 0, 0, 255},
+ {255, 0, 0, 255},
+ {255, 0, 0, 255},
+ },
+ {
+ {255, 255, 0, 255},
+ {255, 255, 0, 255},
+ {255, 255, 0, 255},
+ {255, 255, 0, 255},
+ },
+ {
+ {255, 0, 0, 255},
+ {255, 0, 0, 255},
+ {255, 255, 0, 255},
+ {255, 255, 0, 255},
+ },
+ {
+ {255, 255, 0, 255},
+ {255, 255, 0, 255},
+ {255, 0, 0, 255},
+ {255, 0, 0, 255},
+ },
+ {
+ {255, 0, 0, 255},
+ {255, 255, 0, 255},
+ {255, 0, 0, 255},
+ {255, 255, 0, 255},
+ },
+ {
+ {255, 255, 0, 255},
+ {255, 0, 0, 255},
+ {255, 255, 0, 255},
+ {255, 0, 0, 255},
+ },
+ {
+ {0, 0, 255, 255},
+ {0, 0, 255, 255},
+ {0, 0, 255, 255},
+ {0, 0, 255, 255},
+ },
+ {
+ {0, 0, 255, 255},
+ {0, 0, 255, 255},
+ {255, 255, 255, 255},
+ {255, 255, 255, 255},
+ },
+ {
+ {255, 255, 255, 255},
+ {255, 255, 255, 255},
+ {0, 0, 255, 255},
+ {0, 0, 255, 255},
+ },
+ {
+ {0, 0, 255, 255},
+ {255, 255, 255, 255},
+ {0, 0, 255, 255},
+ {255, 255, 255, 255},
+ },
+ {
+ {255, 255, 255, 255},
+ {0, 0, 255, 255},
+ {255, 255, 255, 255},
+ {0, 0, 255, 255},
+ },
};
-typedef struct {
- uint64_t lastTick;
- char playing;
- int grid[GRIDWIDTH * GRIDHEIGHT];
- ButtonState buttonStates[N_BUTTONS];
-} State;
-
-// Mirror these in src/index.html.in
-enum {
- INPUT_NONE,
- INPUT_CLICK,
- INPUT_PAUSE_PLAY,
-};
-
-typedef struct {
- State state;
- UI ui;
- int input;
- int mousex, mousey;
-} Game;
-
-enum {
- EMPTY,
- BLACK,
- RED,
- YELLOW,
- N_COLORS,
-};
-
-static const Color colors[N_COLORS] = {
- {255, 255, 255, 255},
- {0, 0, 0, 255},
- {255, 0, 0, 255},
- {255, 255, 0, 255}
-};
-
-typedef struct {
- int x, y, w, h;
-} Button;
-
static const Button buttons[N_BUTTONS] = {
[BUTTON_RETRY] = {.x = 16, .y = 16, .w = 128, .h = 32},
[BUTTON_BACK] = {.x = 16, .y = 48, .w = 128, .h = 32},
@@ -129,32 +109,53 @@ static DrawList *render(State *state, UI *ui, Arena *a) {
.y = cellHeight * y,
.w = cellWidth,
.h = cellHeight,
- .fill = colors[state->grid[x + GRIDWIDTH * y]],
+ .fill = {0, 0, 0, 0},
.border = {0, 0, 0, 255},
};
+ for (int subx = 0; subx < 2; subx++) {
+ for (int suby = 0; suby < 2; suby++) {
+ drawList->els[drawList->len++] = (DrawElement) {
+ .x = cellWidth * x + subx * cellWidth / 2,
+ .y = cellHeight * y + suby * cellHeight / 2,
+ .w = cellWidth / 2,
+ .h = cellHeight / 2,
+ .fill = colors[state->grid[x + GRIDWIDTH * y]][subx + 2 * suby],
+ .border = {0, 0, 0, 0},
+ };
+ }
+ }
}
}
drawList->els[drawList->len++] = (DrawElement) {
+ .x = cellWidth * state->goalx,
+ .y = cellHeight * state->goaly,
+ .w = cellWidth,
+ .h = cellHeight,
+ .fill = {255, 0, 0, 63},
+ .border = {255, 0, 0, 255},
+ };
+
+ drawList->els[drawList->len++] = (DrawElement) {
.x = 0,
.y = 0,
.w = GRID_OFFSET_X,
.h = ui->height,
- .fill = colors[YELLOW],
- .border = {0, 0, 0, 255}
+ .fill = {255, 255, 0, 255},
+ .border = {0, 0, 0, 255},
};
for (int i = 0; i < N_BUTTONS; i++) {
- int colour = BLACK;
+ Color colour = {0, 0, 0, 255};
switch (state->buttonStates[i]) {
case BUTTON_STATE_IDLE:
- colour = BLACK;
+ colour = (Color) {0, 0, 0, 255};
break;
case BUTTON_STATE_HOVERED:
- colour = YELLOW;
+ colour = (Color) {255, 255, 0, 255};
break;
case BUTTON_STATE_PRESSED:
- colour = RED;
+ colour = (Color) {255, 0, 0, 255};
break;
}
drawList->els[drawList->len++] = (DrawElement) {
@@ -162,7 +163,7 @@ static DrawList *render(State *state, UI *ui, Arena *a) {
.y = buttons[i].y,
.w = buttons[i].w,
.h = buttons[i].h,
- .fill = colors[colour],
+ .fill = colour,
.border = {0, 0, 0, 255}
};
}
@@ -189,6 +190,11 @@ static void update(Game *game, uint64_t now, Arena a) {
}
}
break;
+ case INPUT_RCLICK:
+ x = game->mousex * GRIDWIDTH / game->ui.width;
+ y = game->mousey * GRIDHEIGHT / game->ui.height;
+ game->state.grid[x + y * GRIDWIDTH] = EMPTY;
+ break;
case INPUT_PAUSE_PLAY:
game->state.playing = !game->state.playing;
break;
@@ -198,31 +204,8 @@ static void update(Game *game, uint64_t now, Arena a) {
if (game->state.playing && game->state.lastTick + TICK_LENGTH <= now) {
game->state.lastTick = now;
- State *lastState = new(&a, 1, State);
- xmemcpy(lastState, game, sizeof(State));
-
- for (int x = 0; x < GRIDWIDTH; x++) {
- for (int y = 0; y < GRIDHEIGHT; y++) {
- if (
- lastState->grid[x + y * GRIDWIDTH] == BLACK && (
- (x > 0 && lastState->grid[x - 1 + y * GRIDWIDTH] == RED) ||
- (x < GRIDWIDTH - 1 && lastState->grid[x + 1 + y * GRIDWIDTH] == RED) ||
- (y > 0 && lastState->grid[x + (y - 1) * GRIDWIDTH] == RED) ||
- (y < GRIDHEIGHT - 1 && lastState->grid[x + (y + 1) * GRIDWIDTH] == RED)
- )
- ) {
- game->state.grid[x + y * GRIDWIDTH] = RED;
- }
-
- if (lastState->grid[x + y * GRIDWIDTH] == RED) {
- game->state.grid[x + y * GRIDWIDTH] = YELLOW;
- }
- if (lastState->grid[x + y * GRIDWIDTH] == YELLOW) {
- game->state.grid[x + y * GRIDWIDTH] = BLACK;
- }
- }
- }
+ tick(game, a);
}
}
@@ -241,7 +224,9 @@ int main(int argc, char **argv) {
};
Game *game = new(&a, 1, Game);
- game->state.grid[0] = 0;
+ xmemcpy(&game->state.grid, &levels[0].grid, sizeof(game->state.grid));
+ game->state.goalx = levels[0].goalx;
+ game->state.goaly = levels[0].goaly;
game->state.playing = 0;
game->ui = (UI) {
.width = 640,
@@ -263,7 +248,8 @@ int main(int argc, char **argv) {
SDL_SetNumberProperty(renderProps, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER, 1);
SDL_Renderer *r = SDL_CreateRendererWithProperties(renderProps);
SDL_DestroyProperties(renderProps);
-
+ SDL_SetRenderDrawBlendMode(r, SDL_BLENDMODE_BLEND);
+
for (;;) {
uint64_t now = SDL_GetTicks();
game->input = INPUT_NONE;
@@ -273,9 +259,13 @@ int main(int argc, char **argv) {
case SDL_EVENT_QUIT:
return 0;
case SDL_EVENT_MOUSE_BUTTON_DOWN:
- game->input = INPUT_CLICK;
game->mousex = (int) e.button.x;
game->mousey = (int) e.button.y;
+ if (e.button.button == 1) {
+ game->input = INPUT_CLICK;
+ } else if (e.button.button == 3) {
+ game->input = INPUT_RCLICK;
+ }
break;
case SDL_EVENT_KEY_DOWN:
switch (e.key.key) {
@@ -290,8 +280,6 @@ int main(int argc, char **argv) {
}
}
- SDL_Log("Button 1 state: %d", game->state.buttonStates[0]);
-
Arena scratch = a;
DrawList *drawList = render(&game->state, &game->ui, &scratch);
SDL_SetRenderDrawColor(r, 0, 0, 0, 255);
@@ -355,11 +343,13 @@ DrawList *game_render(int width, int height) {
}
__attribute((export_name("game_update")))
-void game_update(int input, int mousex, int mousey) {
+void game_update(int input, int mousex, int mousey, int now) {
game->input = input;
game->mousex = mousex;
game->mousey = mousey;
- update(game, perm);
+ update(game, now, perm);
}
#endif
+
+#endif