Skip to content

Commit

Permalink
Fix windows font path
Browse files Browse the repository at this point in the history
Add CookieClicker example

fenster_cursor redundancy check

vsformat rework
  • Loading branch information
CardealRusso committed Nov 7, 2024
1 parent e5e9fba commit 5acb24e
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 27 deletions.
21 changes: 12 additions & 9 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ jobs:
with:
submodules: 'recursive'

- name: Compile mousebuttons example
run: make -C examples/mousebuttons/
- name: Compile Examples
run: |
mkdir build/
make -C examples/mousebuttons/
make -C examples/shapes/
make -C examples/ttf/
make -C examples/cookieclicker/ DESTDIR=../../build
shell: bash

- name: Compile shapes example
run: make -C examples/shapes/
shell: bash

- name: Compile ttf example
run: make -C examples/ttf/
shell: bash
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: examples-${{ runner.os }}
path: build/
135 changes: 135 additions & 0 deletions examples/cookieclicker/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#include "fenster.h"
#include <math.h>

struct AutoClicker {
const char* name;
__uint128_t cost, cps, owned;
int unlocked, bonus;
};

static struct AutoClicker autoclickers[] = {
{"Cursor", 15, 1, 0, 0, 1},
{"Grandma", 100, 4, 0, 0, 1},
{"Farm", 1100, 8, 0, 0, 1},
{"Mine", 12000, 47, 0, 0, 1},
{"Factory", 130000, 260, 0, 0, 1},
{"Bank", 1400000, 1400, 0, 0, 1},
{"Temple", 20000000, 7800, 0, 0, 1},
{"Wizard Tower", 330000000, 44000, 0, 0, 1},
{"Shipment", 5000000000, 260000, 0, 0, 1}
};

int fs = 0;
uint32_t bonus;

int run() {
struct fenster f = {.title = "Cookie Clicker", .width = 800, .height = 600};
fenster_open(&f);

FensterFontList fonts = fenster_loadfontlist();
FensterFont* font = fenster_loadfont(fonts.paths[0]);

__uint128_t cookies = 0, last_time = 0, cookies_per_sec = 0;
float cookie_size = 60.f, cookie_grow_rate = 1.1f, cookie_max_size = 100.f;
int cookie_growing = 0;
int bonus = 0;

while (fenster_loop(&f) == 0 && f.keys[27] == 0) {
fenster_fill(&f, 0x2A2A2A);

int hovering_cursor = 1;
int cookie_x = f.width / 2, cookie_y = f.height / 2;

if (cookie_growing) {
cookie_size = fminf(cookie_size * cookie_grow_rate, cookie_max_size);
} else {
cookie_size = 60.f;
}
fenster_drawcirc(&f, cookie_x, cookie_y, (int)cookie_size, 0x8B4513);

if (fenster_point_in_circle(f.mpos[0], f.mpos[1], cookie_x, cookie_y, (int)cookie_size)) {
hovering_cursor = 2;
if (f.mclick[0]) {
cookies += 1 + (autoclickers[0].owned * autoclickers[0].bonus);
cookie_growing = 0;
} else {
cookie_growing = 1;
}
} else {
cookie_growing = 0;
}

int64_t current_time = f.lastsync;
if (current_time - last_time >= 1000) {
cookies_per_sec = 0;
for (int i = 0; i < 9; i++) {
cookies_per_sec += autoclickers[i].owned * autoclickers[i].cps * autoclickers[i].bonus;
}
bonus = (int)(sqrt(cookies_per_sec) / 10) > 0 ? (int)(sqrt(cookies_per_sec) / 10) : 1;
cookies += cookies_per_sec * bonus;
last_time = current_time;
}

vsformat("Cookies: %llu \\n Per Second: %llu", (unsigned long long)cookies, (unsigned long long)cookies_per_sec);
if (bonus > 1) {
vsformat_concat("\\c0x3299a8 \\s16 *%d", bonus);
}
fenster_drawtext(&f, font, vsbuff, 10, 30);

int button_w = 200, button_h = 80, start_y = 100;
for (int i = 0; i < 9; i++) {
int x = 10, y = start_y + i * (button_h + 10);
int button_color = 0x404040;

if (cookies >= autoclickers[i].cost && !autoclickers[i].unlocked) {
autoclickers[i].unlocked = 1;
}

if (autoclickers[i].unlocked) {
if (cookies >= autoclickers[i].cost) {
if (fenster_point_in_rect(f.mpos[0], f.mpos[1], x, y, button_w, button_h)) {
button_color = 0x517554;
hovering_cursor = 2;
if (f.mclick[0]) {
cookies -= autoclickers[i].cost;
autoclickers[i].owned++;
autoclickers[i].bonus = (int)(sqrt(autoclickers[i].owned) / 2) > 0 ? (int)(sqrt(autoclickers[i].owned) / 2) : 1;
autoclickers[i].cost = autoclickers[i].cost * 115 / 100;
}
} else {
button_color = 0x475c49;
}
}
fenster_drawrec(&f, x, y, button_w, button_h, button_color);

vsformat("\\c0xA9A9A9 %s", autoclickers[i].name);
if (autoclickers[i].bonus > 1) {
vsformat_concat("\\c0x3299a8 *%d", autoclickers[i].bonus);
}
vsformat_concat("\\n \\c0xFFFFFF Cost: %llu\\n Owned: %llu",
(unsigned long long)autoclickers[i].cost,
(unsigned long long)autoclickers[i].owned);

fenster_drawtext(&f, font, vsbuff, x + 10, y + 10);
}
}

fenster_cursor(&f, hovering_cursor);
fenster_sync(&f, 60);
if (f.keysp[70] == 1) fenster_fullscreen(&f, fs ^= 1);
}

fenster_freefont(font);
fenster_freefontlist(&fonts);
fenster_close(&f);
return 0;
}

#if defined(_WIN32)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) {
(void)hInstance, (void)hPrevInstance, (void)pCmdLine, (void)nCmdShow;
return run();
}
#else
int main() { return run(); }
#endif
22 changes: 22 additions & 0 deletions examples/cookieclicker/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
CFLAGS ?= -mavx2 -lm -DUSE_FONTS -O3 -flto -Wall -Wextra -std=c99
DESTDIR ?= .

ifeq ($(OS),Windows_NT)
CC = gcc
LDFLAGS = -mwindows -lgdi32
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
LDFLAGS = -framework Cocoa
else
LDFLAGS = -lX11
endif
endif

all: main

main: main.c ../../src/fenster/fenster.h
$(CC) main.c -I../../src/fenster/ -o $(DESTDIR)/$@ $(CFLAGS) $(LDFLAGS)

clean:
rm -f main
10 changes: 6 additions & 4 deletions examples/shapes/lines.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ static int run() {
fenster_drawline(&f, f.width, 0, mouseX, mouseY, GREEN);
fenster_drawline(&f, 0, f.height, mouseX, mouseY, WHITE);
fenster_drawline(&f, f.width, f.height, mouseX, mouseY, WHITE);

fenster_drawtext(&f, font, vsformat("Frame: %d", frame), 10, 10);

fenster_drawtext(&f, font, vsformat("Press F for fullscreen | ESC to exit | Mouse: (%d, %d)", mouseX, mouseY), 10, f.height - 30);

vsformat("Frame: %d", frame);
fenster_drawtext(&f, font, vsbuff, 10, 10);

vsformat("Press F for fullscreen | ESC to exit | Mouse: (%d, %d)", mouseX, mouseY);
fenster_drawtext(&f, font, vsbuff, 10, f.height - 30);

fenster_sync(&f, 60);
if (f.keysp[70] == 1) fenster_fullscreen(&f, fs ^= 1);
Expand Down
9 changes: 6 additions & 3 deletions examples/ttf/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ static int run() {
fenster_fill(&f, 0);
fenster_drawtext(&f, font, "\\c0x526D82 Hello \\s32 \\c0xDDE6ED BIG \\s16 \\c0x526D82 World \\n From FensterB!", 10, 10);

fenster_drawtext(&f, font, vsformat("\\s16 \\c0xFFFFFF Press F to %s Full screen", fs == 0 ? "enter" : "leave"), 0, 200);
fenster_drawtext(&f, font, vsformat("\\c%d To save CPU cycles, we\\n reprint this text only\\n when window is resized.", rand()), 0, 100);
vsformat("\\s16 \\c0xFFFFFF Press F to %s Full screen", fs == 0 ? "enter" : "leave");
fenster_drawtext(&f, font, vsbuff, 0, 200);
vsformat("\\c%d To save CPU cycles, we\\n reprint this text only\\n when window is resized.", rand());
fenster_drawtext(&f, font, vsbuff, 0, 100);
}

fenster_drawtext(&f, font, vsformat("\\b%d \\s16 Frame: %d", rand(), frame), 0, f.height-16);
vsformat("\\b%d \\s16 Frame: %d", rand(), frame);
fenster_drawtext(&f, font, vsbuff, 0, f.height-16);
fenster_sync(&f, 30);

if (f.keysp[70] == 1) fenster_fullscreen(&f, fs ^= 1);
Expand Down
5 changes: 4 additions & 1 deletion src/fenster/fenster_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ static Atom wm_state;
static Atom wm_fullscreen;
static Cursor cursors[6];
static int cursors_initialized = 0;
static int current_cursor_type = 1;
// clang-format on

FENSTER_API int fenster_open(struct fenster *f) {
Expand Down Expand Up @@ -174,6 +175,7 @@ FENSTER_API void fenster_fullscreen(struct fenster *f, int enabled) {
}

FENSTER_API void fenster_cursor(struct fenster *f, int type) {
if (type == current_cursor_type) return;
if (!cursors_initialized) {
cursors[0] = 0; // None/hidden
cursors[1] = XCreateFontCursor(f->dpy, XC_left_ptr); // Normal arrow
Expand All @@ -196,7 +198,8 @@ FENSTER_API void fenster_cursor(struct fenster *f, int type) {
// Set the cursor from our pre-created cursors
XDefineCursor(f->dpy, f->w, cursors[type]);
}


current_cursor_type = type;
XFlush(f->dpy);
}
#endif /* FENSTER_LINUX_H */
3 changes: 3 additions & 0 deletions src/fenster/fenster_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ extern id const NSDefaultRunLoopMode;
extern id const NSApp;
extern id NSCursor;
static id cursors[6];
static int current_cursor_type = 1;

static void fenster_window_resize(id v, SEL s, id note) {
(void)s;
Expand Down Expand Up @@ -223,6 +224,7 @@ FENSTER_API void fenster_fullscreen(struct fenster *f, int enabled) {
}

FENSTER_API void fenster_cursor(struct fenster *f, int type) {
if (type == current_cursor_type) return;
// Initialize cursors on first use
if (!cursors[1]) {
// Hide cursor (NULL represents hidden cursor)
Expand All @@ -248,6 +250,7 @@ FENSTER_API void fenster_cursor(struct fenster *f, int type) {
// Set and push the new cursor
msg(void, cursors[type], "set");
}
current_cursor_type = type;
}

#endif /* FENSTER_MAC_H */
3 changes: 3 additions & 0 deletions src/fenster/fenster_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ static WINDOWPLACEMENT g_wpPrev = {

static HCURSOR cursors[6];
static int cursors_initialized = 0;
static int current_cursor_type = 1;

typedef struct BINFO {
BITMAPINFOHEADER bmiHeader;
Expand Down Expand Up @@ -221,6 +222,7 @@ FENSTER_API void fenster_fullscreen(struct fenster *f, int enabled) {
}

FENSTER_API void fenster_cursor(struct fenster *f, int type) {
if (type == current_cursor_type) return;
// Initialize cursors on first use
if (!cursors_initialized) {
cursors[0] = NULL; // Will be used for hidden cursor
Expand Down Expand Up @@ -253,5 +255,6 @@ FENSTER_API void fenster_cursor(struct fenster *f, int type) {
wc.hCursor = cursors[type];
SetClassLongPtr(f->hwnd, GCLP_HCURSOR, (LONG_PTR)cursors[type]);
}
current_cursor_type = type;
}
#endif /* FENSTER_WINDOWS_H */
31 changes: 26 additions & 5 deletions src/fenster_addons.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,25 @@

#define PI 3.14159265358979323846

const char* vsformat(const char* formato, ...) {
static char buffer[16 * 1024];
#define VSBUFF_SIZE (16 * 1024)

char vsbuff[VSBUFF_SIZE];

void vsformat(const char* fmt, ...) {
va_list args;
va_start(args, formato);
vsnprintf(buffer, sizeof(buffer), formato, args);
va_start(args, fmt);
vsnprintf(vsbuff, VSBUFF_SIZE, fmt, args);
va_end(args);
}

return buffer;
void vsformat_concat(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
size_t len = strlen(vsbuff);
if (len < VSBUFF_SIZE - 1) {
vsnprintf(vsbuff + len, VSBUFF_SIZE - len, fmt, args);
}
va_end(args);
}

static inline void vector_fill(uint32_t* buf, size_t count, uint32_t color) {
Expand Down Expand Up @@ -217,4 +227,15 @@ static inline void fenster_fill(struct fenster *f, uint32_t color) {
vector_fill(f->buf, total_pixels, color);
}

static inline int fenster_point_in_circle(int x, int y, int cx, int cy, int radius) {
int dx = x - cx;
int dy = y - cy;
return dx * dx + dy * dy <= radius * radius;
}

static inline int fenster_point_in_rect(int x, int y, int rect_x, int rect_y, int rect_width, int rect_height) {
return x >= rect_x && x <= rect_x + rect_width &&
y >= rect_y && y <= rect_y + rect_height;
}

#endif /* FENSTER_ADDONS_H */
15 changes: 10 additions & 5 deletions src/fenster_font.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#define FENSTER_FONT_H

#define STB_TRUETYPE_IMPLEMENTATION
#define STB_RECT_PACK_IMPLEMENTATION
#include "stb/stb_rect_pack.h"
#include "stb/stb_truetype.h"
#include "fenster/fenster.h"
#include <stdio.h>
Expand Down Expand Up @@ -152,15 +154,18 @@ FensterFontList fenster_loadfontlist(void) {
}
}
#elif defined(_WIN32)
char path[MAX_PATH];
if (GetEnvironmentVariable("SYSTEMROOT", path, MAX_PATH)) {
strcat(path, "\\Fonts\\*.ttf");
char base_path[MAX_PATH];
if (GetEnvironmentVariable("SYSTEMROOT", base_path, MAX_PATH)) {
strcat(base_path, "\\Fonts");
char search_path[MAX_PATH];
sprintf(search_path, "%s\\*.ttf", base_path);

WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile(path, &fd);
HANDLE h = FindFirstFile(search_path, &fd);
if (h != INVALID_HANDLE_VALUE) {
char full[MAX_PATH];
do {
sprintf(full, "%s\\Fonts\\%s", path, fd.cFileName);
sprintf(full, "%s\\%s", base_path, fd.cFileName);
add_font_path(&fonts, full);
} while (FindNextFile(h, &fd));
FindClose(h);
Expand Down

0 comments on commit 5acb24e

Please sign in to comment.