Skip to content

Instantly share code, notes, and snippets.

@niansa
Created Nov 13, 2020
Embed
What would you like to do?
#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