Created
November 13, 2020 11:14
-
-
Save niansa/d8ace628f925b6348d17c6eaa25b6871 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
#include <string.h> | |
#include <limits.h> | |
#include <MiniFB.h> | |
#define WIDTH 800 | |
#define HEIGHT 600 | |
#define BOTTOM_LINE HEIGHT / 2 | |
#define BUFSIZE WIDTH * HEIGHT | |
#define SPEED 5 | |
#define COORDTYPE unsigned int | |
#define BUFTYPE unsigned int | |
static const BUFTYPE color_bg = MFB_RGB(0, 0, 0); | |
static const BUFTYPE color_fg = MFB_RGB(255, 255, 0); | |
static const BUFTYPE color_ui = MFB_RGB(255, 0, 0); | |
struct program_state { | |
COORDTYPE ppos; | |
COORDTYPE last_ppos; | |
unsigned char points; | |
bool paused; | |
bool gameover; | |
bool rendering; | |
}; | |
void program_state_init(struct program_state *state) { | |
state->ppos = 0; | |
state->last_ppos = 0; | |
state->points = 0; | |
state->paused = true; | |
state->gameover = false; | |
state->rendering = true; | |
} | |
void draw_line_h(BUFTYPE *buf, const BUFTYPE color, const COORDTYPE posx1, const COORDTYPE posy1, const COORDTYPE posx2) { | |
for (COORDTYPE pos = posy1 * WIDTH + posx1; pos != posy1 * WIDTH + posx2; ++pos) { | |
buf[pos] = color; | |
} | |
} | |
void draw_line_v(BUFTYPE *buf, const BUFTYPE color, const COORDTYPE posx1, const COORDTYPE posy1, const COORDTYPE posy2) { | |
for (COORDTYPE posy = posy1; posy != posy2 + 1; ++posy) { | |
buf[posy * WIDTH + posx1] = color; | |
} | |
} | |
void draw_box(BUFTYPE *buf, const BUFTYPE color, const COORDTYPE posx1, const COORDTYPE posy1, const COORDTYPE posx2, const COORDTYPE posy2) { | |
draw_line_h(buf, color, posx1, posy1, posx2); | |
draw_line_h(buf, color, posx1, posy2, posx2); | |
draw_line_v(buf, color, posx1, posy1, posy2); | |
draw_line_v(buf, color, posx2, posy1, posy2); | |
} | |
void update_buffer(BUFTYPE *buf, struct program_state *state) { | |
// Draw bottom line | |
draw_line_h(buf, color_fg, 0, BOTTOM_LINE, WIDTH); | |
// Show gameover or pause screen if neccessary | |
if (state->gameover) { | |
// Count points | |
state->points = 0; | |
for (COORDTYPE pos = (BOTTOM_LINE - 1) * WIDTH; pos != (BOTTOM_LINE - 1) * WIDTH + WIDTH; pos += SPEED) { | |
if (buf[pos] == color_fg) { | |
state->points++; | |
} | |
} | |
// Render dead frog | |
draw_box(buf, color_ui, 10, 10, 100, 100); // Left eye | |
draw_box(buf, color_ui, 150, 10, 240, 100); // Right eye | |
draw_box(buf, color_ui, 10, 110, 240, 130); // Mouth | |
draw_line_h(buf, color_bg, 130, 130, 170); // Partitial mouth line removal for tongue | |
draw_box(buf, color_ui, 130, 120, 170, 200); // Tongue | |
draw_line_v(buf, color_ui, 150, 120, 190); // Tongue line | |
// Stop rendering | |
state->rendering = false; | |
return; | |
} else if (state->paused) { | |
// ... | |
return; | |
} | |
// Draw "player" | |
if (state->ppos - SPEED < WIDTH) { | |
draw_line_v(buf, color_bg, state->ppos - SPEED, BOTTOM_LINE - 10, BOTTOM_LINE + 10); | |
} | |
if (state->ppos == WIDTH) { | |
state->ppos = 0; | |
state->gameover = true; | |
} else { | |
draw_line_v(buf, color_fg, state->ppos, BOTTOM_LINE - 10, BOTTOM_LINE + 10); | |
state->ppos += SPEED; | |
} | |
} | |
static struct program_state prg_state; | |
void cb_keyboard(struct mfb_window *window, mfb_key key, mfb_key_mod mod, bool isPressed) { | |
if (key == KB_KEY_ENTER && isPressed) { | |
if (prg_state.ppos >= prg_state.last_ppos && prg_state.last_ppos != 0) { | |
prg_state.gameover = true; | |
} else { | |
prg_state.points++; | |
} | |
prg_state.last_ppos = prg_state.ppos; | |
prg_state.ppos = 0; | |
prg_state.paused = false; | |
} | |
} | |
int main() { | |
BUFTYPE buffer[BUFSIZE]; | |
struct mfb_window *window = mfb_open_ex("Test!", WIDTH, HEIGHT, 0); | |
if (!window) { | |
perror("Failed to create window"); | |
return EXIT_FAILURE; | |
} | |
memset(buffer, color_bg, BUFSIZE * sizeof(*buffer)); | |
program_state_init(&prg_state); | |
mfb_set_target_fps(60); | |
mfb_set_keyboard_callback(window, cb_keyboard); | |
while (mfb_wait_sync(window)) { | |
printf("Points: %i\r", prg_state.points); | |
if (prg_state.rendering) { | |
update_buffer(buffer, &prg_state); | |
} | |
if (mfb_update(window, buffer) < 0) { | |
break; | |
} | |
} | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment