summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--counter.c60
-rw-r--r--counter.h10
-rw-r--r--digits.h129
-rw-r--r--main.c1
-rw-r--r--world.c56
-rw-r--r--world.h1
7 files changed, 254 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index 1bf7aae..52d1409 100644
--- a/Makefile
+++ b/Makefile
@@ -3,13 +3,14 @@ SDL_HEADERS=/usr/include/SDL2
CFLAGS=-g -Wall -pedantic -std=c99 $$(sdl2-config --cflags)
LFLAGS=$$(sdl2-config --libs)
-findgame: main.o world.o random.o generator.o save.o die.o
+findgame: main.o world.o random.o generator.o save.o counter.o die.o
$(CC) -o $@ $^ $(LFLAGS)
main.o: world.h random.h save.h
-world.o: world.h random.h generator.h save.h
+world.o: world.h random.h generator.h save.h counter.h
generator.o: world.h random.h
save.o: world.h die.h
+counter.o: digits.h
.SUFFIXES: .c .o
.c.o:
diff --git a/counter.c b/counter.c
new file mode 100644
index 0000000..5a9913c
--- /dev/null
+++ b/counter.c
@@ -0,0 +1,60 @@
+#include <SDL.h>
+
+#include "digits.h"
+
+static SDL_Texture *get_font(SDL_Renderer *rend) {
+ static SDL_Texture *font = NULL;
+ if (!font) {
+ font = SDL_CreateTexture(rend,
+ SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING,
+ FONT_WIDTH, sizeof(digits) / FONT_WIDTH);
+ SDL_SetTextureBlendMode(font, SDL_BLENDMODE_BLEND);
+ SDL_assert(font);
+
+ int pitch;
+ void *out;
+ SDL_assert(SDL_LockTexture(font, NULL, &out, &pitch) >= 0);
+ SDL_Color *pixels = out;
+
+ for (int i = 0; i < sizeof(digits); i++) {
+ pixels[i] =
+ (SDL_Color) {0xFF, 0xFF, 0xFF, digits[i] ? 0xFF : 0x00};
+ }
+
+ SDL_UnlockTexture(font);
+ }
+ return font;
+}
+
+int draw_counter(SDL_Renderer *rend,
+ SDL_Point screen_pos, double size, SDL_Color color,
+ int number, int digits) {
+ double scale = size / FONT_HEIGHT;
+
+ SDL_Texture *font = get_font(rend);
+ SDL_SetTextureColorMod(font, color.r, color.g, color.b);
+
+ if (digits == 0) {
+ for (int n = number; n > 0; n /= DIGIT_BASE)
+ digits += 1;
+ digits = SDL_max(digits, 1);
+ }
+
+ int n = number;
+ for (int i = digits - 1; i >= 0; i--) {
+ int digit = n % DIGIT_BASE;
+
+ int width = SDL_round((double) FONT_WIDTH * scale);
+ int height = SDL_round((double) FONT_HEIGHT * scale);
+ int offset = SDL_round((double) FONT_WIDTH * scale * (double) i);
+ SDL_Rect draw = {screen_pos.x + offset, screen_pos.y, width, height};
+ SDL_Rect digit_rect = {
+ 0, FONT_HEIGHT * digit, FONT_WIDTH, FONT_HEIGHT,
+ };
+ SDL_RenderCopy(rend, font, &digit_rect, &draw);
+
+ n /= DIGIT_BASE;
+ }
+
+ return SDL_round((double) FONT_WIDTH * scale * (double) digits);
+}
diff --git a/counter.h b/counter.h
new file mode 100644
index 0000000..7dcb97c
--- /dev/null
+++ b/counter.h
@@ -0,0 +1,10 @@
+#ifndef COUNTER_H
+#define COUNTER_H
+
+#include <SDL.h>
+
+int draw_counter(SDL_Renderer *rend,
+ SDL_Point screen_pos, double size, SDL_Color color,
+ int number, int digits);
+
+#endif
diff --git a/digits.h b/digits.h
new file mode 100644
index 0000000..a1d5466
--- /dev/null
+++ b/digits.h
@@ -0,0 +1,129 @@
+#ifndef DIGITS_H
+#define DIGITS_H
+
+#include <SDL.h>
+
+static const Uint8 digits[] = {
+ 0, 1, 1, 1, 0, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 1, 1, 0, 0,
+ 0, 1, 1, 1, 0, 0,
+ 0, 0, 1, 1, 0, 0,
+ 0, 0, 1, 1, 0, 0,
+ 0, 0, 1, 1, 0, 0,
+ 0, 0, 1, 1, 0, 0,
+ 0, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+
+ 0, 1, 1, 1, 0, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 0, 1, 1, 0, 0,
+ 0, 1, 1, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+
+ 0, 1, 1, 1, 0, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 0, 1, 1, 0, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 1, 1, 1, 1, 0,
+ 0, 0, 0, 1, 1, 0,
+ 0, 0, 0, 1, 1, 0,
+ 0, 0, 0, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+
+ 1, 1, 1, 1, 1, 0,
+ 1, 1, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0,
+ 0, 1, 1, 1, 0, 0,
+ 0, 0, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+
+ 0, 1, 1, 1, 0, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 0, 0, 0,
+ 1, 1, 1, 1, 0, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+
+ 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 1, 1, 0,
+ 0, 0, 1, 1, 0, 0,
+ 0, 0, 1, 1, 0, 0,
+ 0, 1, 1, 0, 0, 0,
+ 0, 1, 1, 0, 0, 0,
+ 0, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+
+ 0, 1, 1, 1, 0, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 1, 1, 1, 0, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+
+ 0, 1, 1, 1, 0, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 1, 1, 1, 1, 0,
+ 0, 0, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+
+ 0, 1, 1, 1, 0, 0,
+ 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 1, 1, 1, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 1, 1, 1, 0, 0,
+ 1, 1, 0, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+
+ 1, 1, 1, 1, 1, 0,
+ 1, 1, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+};
+
+#define FONT_WIDTH 6
+#define FONT_HEIGHT 8
+#define DIGIT_BASE 12
+
+#endif
diff --git a/main.c b/main.c
index 39eb282..7c573a8 100644
--- a/main.c
+++ b/main.c
@@ -86,6 +86,7 @@ int main(int argc, char *argv[]) {
"error creating renderer: %s", SDL_GetError());
return 1;
}
+ SDL_SetRenderDrawBlendMode(rend, SDL_BLENDMODE_BLEND);
init_world(&game);
while (run());
diff --git a/world.c b/world.c
index 46407c3..a72d1a7 100644
--- a/world.c
+++ b/world.c
@@ -4,6 +4,7 @@
#include "random.h"
#include "generator.h"
#include "save.h"
+#include "counter.h"
SDL_Color tile_colors[] = {
[TILE_RED] = {0xFF, 0x00, 0x00, 0xFF},
@@ -12,6 +13,7 @@ SDL_Color tile_colors[] = {
[TILE_LIGHT] = {0xFF, 0xFF, 0xFF, 0xFF},
[TILE_EMPTY] = {0x00, 0x00, 0x00, 0xFF},
[TILE_WALL] = {0x50, 0x50, 0x50, 0xFF},
+ [TILE_BLOCK_WHITE] = {0x80, 0x80, 0x80, 0xFF},
};
chunk *get_chunk(world *w, SDL_Point chunk_pos) {
@@ -106,7 +108,13 @@ void set_tile(world *w, SDL_Point world_pos, tile t) {
}
SDL_bool is_solid(tile t) {
- return t == TILE_WALL;
+ switch (t) {
+ case TILE_WALL:
+ case TILE_BLOCK_WHITE:
+ return SDL_TRUE;
+ default:
+ return SDL_FALSE;
+ }
}
SDL_bool player_grounded(world *w) {
@@ -160,11 +168,11 @@ void player_place(world *w, int x, int y) {
SDL_Point place = {w->player.pos.x + x, w->player.pos.y + y};
if (!is_solid(get_tile(w, place))) {
player_collect(w, place);
- set_tile(w, place, TILE_WALL);
+ set_tile(w, place, TILE_BLOCK_WHITE);
} else {
SDL_Point push = {w->player.pos.x - x, w->player.pos.y - y};
if (!is_solid(get_tile(w, push))) {
- set_tile(w, w->player.pos, TILE_WALL);
+ set_tile(w, w->player.pos, TILE_BLOCK_WHITE);
w->player.pos = push;
}
}
@@ -190,7 +198,7 @@ void player_destroy(world *w, int x, int y) {
}
}
-void draw_world(world *w, SDL_Window *win, SDL_Renderer *rend) {
+static double get_view_scale(SDL_Window *win) {
int sw, sh;
SDL_GetWindowSize(win, &sw, &sh);
@@ -200,6 +208,40 @@ void draw_world(world *w, SDL_Window *win, SDL_Renderer *rend) {
else
view_scale = (double) sw / (double) VIEW_DIM;
+ return view_scale;
+}
+
+static void draw_ui(world *w, SDL_Window *win, SDL_Renderer *rend) {
+ int sw, sh;
+ SDL_GetWindowSize(win, &sw, &sh);
+ double view_scale = get_view_scale(win);
+
+ double bar_size = 1.5;
+ double padding = 0.16;
+
+ SDL_Rect bar = {
+ 0, sh - view_scale * (bar_size + padding), sw, view_scale * 3,
+ };
+ SDL_SetRenderDrawColor(rend, 0x00, 0x00, 0x00, 0xFF);
+ SDL_RenderFillRect(rend, &bar);
+
+ int x = view_scale * padding;
+ for (int i = 0; i < MAX_COLLECTIBLE; i++) {
+ int score = w->player.scores[i];
+ SDL_Color grey = {0x20, 0x20, 0x10, 0xFF};
+ SDL_Color collectible_color = tile_colors[i];
+ SDL_Color color = score > 0 ? collectible_color : grey;
+ SDL_Point pos = {x, bar.y + view_scale * padding};
+ x += draw_counter(rend, pos, view_scale * bar_size, color, score, 3);
+ x += view_scale * 1;
+ }
+}
+
+void draw_world(world *w, SDL_Window *win, SDL_Renderer *rend) {
+ int sw, sh;
+ SDL_GetWindowSize(win, &sw, &sh);
+ double view_scale = get_view_scale(win);
+
double view_width = (double) sw / view_scale;
double view_height = (double) sh / view_scale;
double view_x = w->view_pos.x - view_width / 2;
@@ -221,8 +263,8 @@ void draw_world(world *w, SDL_Window *win, SDL_Renderer *rend) {
SDL_Point min = chunk_pos_at((SDL_Point) {view_x, view_y});
SDL_Point max = chunk_pos_at(
(SDL_Point) {view_x + view_width, view_y + view_height});
- for (int y = min.y; y <= max.y; y++) {
- for (int x = min.x; x <= max.x; x++) {
+ for (int y = min.y - 1; y <= max.y; y++) {
+ for (int x = min.x - 1; x <= max.x; x++) {
chunk *c = load_chunk(w, (SDL_Point) {x, y});
if (!c) continue;
SDL_Texture *tex = render_chunk(rend, c);
@@ -247,6 +289,8 @@ void draw_world(world *w, SDL_Window *win, SDL_Renderer *rend) {
};
SDL_SetRenderDrawColor(rend, 0xFF, 0x00, 0xFF, 0xFF);
SDL_RenderFillRect(rend, &player_rect);
+
+ draw_ui(w, win, rend);
}
void tick_world(world *w) {
diff --git a/world.h b/world.h
index ad7acd2..33d5984 100644
--- a/world.h
+++ b/world.h
@@ -14,6 +14,7 @@ typedef enum tile {
TILE_EMPTY,
TILE_WALL,
+ TILE_BLOCK_WHITE,
} tile;
extern SDL_Color tile_colors[];