the game lol

This commit is contained in:
gabbagaps 2022-07-09 20:32:22 +01:00
parent 6888621fac
commit 12fa29e391
29 changed files with 764 additions and 0 deletions

36
Makefile Normal file
View File

@ -0,0 +1,36 @@
# A simple Makefile for compiling small SDL projects
# set the compiler
CC := gcc
# set the compiler flags
CFLAGS := `sdl2-config --libs --cflags` -ggdb3 -O2 --std=c99 -Wall -lSDL2_image -lSDL2_mixer -lm
# add header files here
HDRS := *.h
# add source files here
SRCS := *.c
# generate names of object files
OBJS := $(SRCS:.c=.o)
# name of executable
EXEC := minesweeper
# default recipe
all: $(EXEC)
# recipe for building the final executable
$(EXEC): $(OBJS) $(HDRS) Makefile
$(CC) -o $@ $(OBJS) $(CFLAGS)
# recipe for building object files
#$(OBJS): $(@:.o=.c) $(HDRS) Makefile
# $(CC) -o $@ $(@:.o=.c) -c $(CFLAGS)
# recipe to clean the workspace
clean:
rm -f $(EXEC) $(OBJS)
.PHONY: all clean

62
audio.c Normal file
View File

@ -0,0 +1,62 @@
#include "audio.h"
Mix_Chunk * sfx_click = NULL;
Mix_Chunk * sfx_click2 = NULL;
Mix_Chunk * sfx_explosion = NULL;
Mix_Chunk * sfx_win = NULL;
Mix_Chunk * sfx_lose = NULL;
void init_audio()
{
const char* driver_name = SDL_GetCurrentAudioDriver();
if (driver_name) {
printf("Audio subsystem initialized: driver = %s.\n", driver_name);
} else {
printf("Audio subsystem not initialized.\n");
}
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) {
fprintf(stderr, "SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError());
}
sfx_click = Mix_LoadWAV("resources/click.wav");
sfx_click2 = Mix_LoadWAV("resources/click2.wav");
sfx_explosion = Mix_LoadWAV("resources/explosion.wav");
sfx_win = Mix_LoadWAV("resources/win.wav");
sfx_lose = Mix_LoadWAV("resources/lose.wav");
}
void play_audio(int sfx_index)
{
switch (sfx_index) {
/* Since I stopped including the files with the macros I'll just indicate what it was with a comment */
/* case UNCLICKED:*/
case 0:
Mix_PlayChannel(-1, sfx_click, 0);
break;
/* case SHOW_FLAG: */
case 2:
Mix_PlayChannel(-1, sfx_click2, 0);
break;
/* case EXPLOSION: */
case 5:
Mix_PlayChannel(-1, sfx_explosion, 0);
break;
/* case WON: */
case 1:
Mix_PlayChannel(-1, sfx_win, 0);
break;
}
}
void audio_destroy()
{
Mix_FreeChunk(sfx_click);
Mix_FreeChunk(sfx_click2);
Mix_FreeChunk(sfx_explosion);
Mix_FreeChunk(sfx_win);
Mix_FreeChunk(sfx_lose);
Mix_Quit();
}

5
audio.h Normal file
View File

@ -0,0 +1,5 @@
#include "defs.h"
void init_audio();
void play_audio(int);
void audio_destroy();

13
defs.h Normal file
View File

@ -0,0 +1,13 @@
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_timer.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_mixer.h>
#ifndef _GLOBAL_CONSTANTS
#define _GLOBAL_CONSTANTS
#define WINDOW_WIDTH 600
#define WINDOW_HEIGHT 600
#endif

268
graphics.c Normal file
View File

@ -0,0 +1,268 @@
#include "main.h"
#include "graphics.h"
SDL_Window * window = NULL;
SDL_Renderer * rend = NULL;
/* lol */
SDL_Texture * block_tex = NULL;
SDL_Texture * flag_tex = NULL;
SDL_Texture * explode_tex = NULL;
SDL_Texture * click_tex = NULL;
SDL_Texture * num1_tex = NULL;
SDL_Texture * num2_tex = NULL;
SDL_Texture * num3_tex = NULL;
SDL_Texture * num4_tex = NULL;
SDL_Texture * num5_tex = NULL;
SDL_Texture * num6_tex = NULL;
SDL_Texture * num7_tex = NULL;
SDL_Texture * num8_tex = NULL;
SDL_Texture * smiley_idle_tex = NULL;
SDL_Texture * smiley_sweat_tex = NULL;
SDL_Texture * smiley_anger_tex = NULL;
SDL_Texture * smiley_happy_tex = NULL;
smile joe;
blks grid;
SDL_Texture * create_tex(SDL_Window * window, SDL_Renderer * rend, const char * file)
{
/* Load image in memory */
SDL_Surface * surface = IMG_Load(file);
if (!surface)
{
fprintf(stderr,
"Couldn't create surface: %s\n", SDL_GetError());
SDL_DestroyRenderer(rend);
SDL_DestroyWindow(window);
SDL_Quit();
exit(1);
}
/* Load image data in vram */
SDL_Texture * tex = SDL_CreateTextureFromSurface(rend, surface);
SDL_FreeSurface(surface);
if (!tex)
{
fprintf(stderr,
"Couldn't create texture: %s\n", SDL_GetError());
SDL_DestroyRenderer(rend);
SDL_DestroyWindow(window);
SDL_Quit();
exit(1);
}
return tex;
}
void init_video()
{
window = SDL_CreateWindow(
"test",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
WINDOW_WIDTH,
WINDOW_HEIGHT,
SDL_WINDOW_MAXIMIZED
);
if (!window)
{
fprintf(stderr,
"Couldn't create window: %s\n", SDL_GetError());
exit(1);
}
Uint32 render_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;
rend = SDL_CreateRenderer(window, -1, render_flags);
/* * *
VERSION THAT ACCOUNTS FOR GAPS, IT DOES NOT WORK PROPERLY AT AROUND 16x16 AND UP
* * *
for (int i = 0; i < GRID_Y; i++) {
for (int j = 0; j < GRID_X; j++) {
grid[i][j].w = (WINDOW_WIDTH * 0.9) / (GRID_X + 1);
grid[i][j].h = (WINDOW_HEIGHT * 0.9) / (GRID_Y + 1);
grid[i][j].x = ((WINDOW_WIDTH - (WINDOW_WIDTH * 0.9)) / 2) + (j * (grid[i][j].w + (((WINDOW_WIDTH * 0.9) / (GRID_X + 1)) / (GRID_X - 1))));
grid[i][j].y = ((WINDOW_HEIGHT - (WINDOW_HEIGHT * 0.9)) / 2) + (i * (grid[i][j].h + (((WINDOW_HEIGHT * 0.9) / (GRID_Y + 1)) / (GRID_Y - 1))));
// drinking game: count the parentheses
}
}
* * */
for (int i = 0; i < GRID_Y; i++) {
for (int j = 0; j < GRID_X; j++) {
grid.block[i][j].w = (WINDOW_WIDTH * 0.75) / GRID_Y;
grid.block[i][j].h = (WINDOW_HEIGHT * 0.75) / GRID_Y;
grid.block[i][j].x = ((WINDOW_WIDTH - (WINDOW_WIDTH * 0.75)) / 2) + (j * (grid.block[i][j].w));
grid.block[i][j].y = ((((WINDOW_HEIGHT + (WINDOW_HEIGHT * 0.3)) - (WINDOW_HEIGHT * 0.9)) / 2) + (i * (grid.block[i][j].h)));
}
}
joe.rect.w = (WINDOW_HEIGHT * 0.2);
joe.rect.h = (WINDOW_HEIGHT * 0.2);
joe.rect.x = (WINDOW_WIDTH - joe.rect.w) / 2;
joe.rect.y = 0;
joe.state = IDLE;
block_tex = create_tex(window, rend, "resources/ground.png");
flag_tex = create_tex(window, rend, "resources/flag.png");
explode_tex = create_tex(window, rend, "resources/bomb.png");
click_tex = create_tex(window, rend, "resources/click.png");
num1_tex = create_tex(window, rend, "resources/num1.png");
num2_tex = create_tex(window, rend, "resources/num2.png");
num3_tex = create_tex(window, rend, "resources/num3.png");
num4_tex = create_tex(window, rend, "resources/num4.png");
num5_tex = create_tex(window, rend, "resources/num5.png");
num6_tex = create_tex(window, rend, "resources/num6.png");
num7_tex = create_tex(window, rend, "resources/num7.png");
num8_tex = create_tex(window, rend, "resources/num8.png");
smiley_idle_tex = create_tex(window, rend, "resources/smiley_idle.png");
smiley_sweat_tex = create_tex(window, rend, "resources/smiley_sweat.png");
smiley_anger_tex = create_tex(window, rend, "resources/smiley_anger.png");
smiley_happy_tex = create_tex(window, rend, "resources/smiley_happy.png");
}
void video_loop()
{
/* Clear the window */
SDL_SetRenderDrawColor(rend, 211, 211, 211, 255);
//SDL_SetRenderDrawColor(rend, 255, 255, 255, 255);
SDL_RenderClear(rend);
//SDL_SetRenderDrawColor(rend, 100, 100, 100, 255);
//SDL_RenderFillRects(rend, grid, GRID_X * GRID_Y);
/* Draw image */
for (int i = 0; i < GRID_Y; i++) for (int j = 0; j < GRID_X; j++)
{
switch (grid.state[i][j]) {
case EXPLOSION:
if (grid.show[i][j] == SHOW_TRUE)
{
SDL_RenderCopy(rend, explode_tex, NULL, &grid.block[i][j]);
break;
}
case NUM1:
if (grid.show[i][j] == SHOW_TRUE)
{
SDL_RenderCopy(rend, num1_tex, NULL, &grid.block[i][j]);
break;
}
case NUM2:
if (grid.show[i][j] == SHOW_TRUE)
{
SDL_RenderCopy(rend, num2_tex, NULL, &grid.block[i][j]);
break;
}
case NUM3:
if (grid.show[i][j] == SHOW_TRUE)
{
SDL_RenderCopy(rend, num3_tex, NULL, &grid.block[i][j]);
break;
}
case NUM4:
if (grid.show[i][j] == SHOW_TRUE)
{
SDL_RenderCopy(rend, num4_tex, NULL, &grid.block[i][j]);
break;
}
case NUM5:
if (grid.show[i][j] == SHOW_TRUE)
{
SDL_RenderCopy(rend, num5_tex, NULL, &grid.block[i][j]);
break;
}
case NUM6:
if (grid.show[i][j] == SHOW_TRUE)
{
SDL_RenderCopy(rend, num6_tex, NULL, &grid.block[i][j]);
break;
}
case NUM7:
if (grid.show[i][j] == SHOW_TRUE)
{
SDL_RenderCopy(rend, num7_tex, NULL, &grid.block[i][j]);
break;
}
case NUM8:
if (grid.show[i][j] == SHOW_TRUE)
{
SDL_RenderCopy(rend, num8_tex, NULL, &grid.block[i][j]);
break;
}
case EMPTY:
if (grid.show[i][j] == SHOW_TRUE)
{
SDL_RenderCopy(rend, click_tex, NULL, &grid.block[i][j]);
break;
}
case UNCLICKED:
if (grid.show[i][j] == SHOW_FLAG) {
SDL_RenderCopy(rend, flag_tex, NULL, &grid.block[i][j]);
break;
}
SDL_RenderCopy(rend, block_tex, NULL, &grid.block[i][j]);
break;
}
switch (joe.state) {
case HAPPY:
SDL_RenderCopy(rend, smiley_happy_tex, NULL, &joe.rect);
break;
case ANGER:
SDL_RenderCopy(rend, smiley_anger_tex, NULL, &joe.rect);
break;
case SWEAT:
SDL_RenderCopy(rend, smiley_sweat_tex, NULL, &joe.rect);
break;
case IDLE:
SDL_RenderCopy(rend, smiley_idle_tex, NULL, &joe.rect);
break;
}
}
SDL_RenderPresent(rend);
}
void video_destroy()
{
SDL_DestroyTexture(block_tex);
SDL_DestroyTexture(explode_tex);
SDL_DestroyTexture(flag_tex);
SDL_DestroyTexture(click_tex);
SDL_DestroyTexture(num1_tex);
SDL_DestroyTexture(num2_tex);
SDL_DestroyTexture(num3_tex);
SDL_DestroyTexture(num4_tex);
SDL_DestroyTexture(num5_tex);
SDL_DestroyTexture(num6_tex);
SDL_DestroyTexture(num7_tex);
SDL_DestroyTexture(num8_tex);
SDL_DestroyTexture(smiley_idle_tex);
SDL_DestroyTexture(smiley_sweat_tex);
SDL_DestroyTexture(smiley_anger_tex);
SDL_DestroyTexture(smiley_happy_tex);
SDL_DestroyRenderer(rend);
SDL_DestroyWindow(window);
IMG_Quit();
}

48
graphics.h Normal file
View File

@ -0,0 +1,48 @@
#include "defs.h"
#define UNCLICKED 0
#define EMPTY 1
//#define UNUSED 2
//#define UNUSED 3
//#define UNUSED 4
#define EXPLOSION 5
#define NUM1 6
#define NUM2 7
#define NUM3 8
#define NUM4 9
#define NUM5 10
#define NUM6 11
#define NUM7 12
#define NUM8 13
#define DONT_SHOW 0
#define SHOW_TRUE 1
#define SHOW_FLAG 2
#define HAPPY 1
#define ANGER 2
#define SWEAT 3
#define IDLE 4
typedef struct blocks {
SDL_Rect block[GRID_Y][GRID_X];
int state[GRID_Y][GRID_X];
int show[GRID_Y][GRID_X];
int bomb[GRID_Y][GRID_X];
} blks;
typedef struct smiley {
SDL_Rect rect;
int state;
} smile;
extern SDL_Window * window;
extern SDL_Renderer * rend;
extern blks grid;
extern smile joe;
SDL_Texture * create_tex(SDL_Window *, SDL_Renderer *, const char *);
void init_video();
void video_loop();
void video_destroy();

316
main.c Normal file
View File

@ -0,0 +1,316 @@
#include "main.h"
#include "graphics.h"
#include "audio.h"
#include <stdlib.h>
#include <time.h>
SDL_Rect player;
int pause = 0;
int main(void)
{
srand(time(NULL));
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) < 0)
{
fprintf(stderr,
"Couldn't initialize SDL: %s\n", SDL_GetError());
exit(1);
return 1;
}
init_video();
init_audio();
player.w = 1;
player.h = 1;
tick();
video_destroy();
audio_destroy();
SDL_Quit();
return 0;
}
void tick()
{
int close_requested = 0;
SDL_Event event;
int r_mouse = 0;
int l_mouse = 0;
srand(time(NULL));
int player_bombs = NUM_OF_BOMBS;
int player_unclicked = GRID_X * GRID_Y;
populate();
/* Check the board and give all blocks their proper values */
for (int i = 0; i < GRID_Y; i++) for (int j = 0; j < GRID_X; j++)
{
int bombs_block = check_adjacent(i, j); /* Store value to not check twice */
if (bombs_block > 0 && bombs_block < 9) {
grid.state[i][j] = bombs_block + 5; /* In the DEFINE macros the numerical blocks start at 6 */
} else if (bombs_block == 9) {
grid.state[i][j] = EXPLOSION;
}
}
while(!close_requested)
{
while (SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
{
close_requested = 1;
break;
}
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_RIGHT) r_mouse = 1;
if (event.button.button == SDL_BUTTON_LEFT) l_mouse = 1;
break;
}
}
if (!pause)
{
if (player_bombs == 0) {
for (int i = 0; i < GRID_Y; i++) for (int j = 0; j < GRID_X; j++)
if (grid.show[i][j] == SHOW_FLAG && grid.state[i][j] == EXPLOSION) player_bombs++;
if (player_bombs == NUM_OF_BOMBS)
game_over(WON);
}
/* This is probably inneficient, a last minute add because I forgot this is also a win condition of minesweeper */
player_unclicked = GRID_X * GRID_Y;
for (int i = 0; i < GRID_Y; i++) for (int j = 0; j < GRID_X; j++)
{
if (grid.show[i][j] == SHOW_TRUE) player_unclicked--;
}
if (player_unclicked == NUM_OF_BOMBS) game_over(WON);
if (player_bombs == 1) {
joe.state = SWEAT;
}
else if (joe.state == SWEAT) {
joe.state = IDLE;
}
int mouse_x, mouse_y;
SDL_GetMouseState(&mouse_x, &mouse_y);
/* Update position */
player.x = mouse_x;
player.y = mouse_y;
for (int i = 0; i < GRID_Y; i++) for (int j = 0; j < GRID_X; j++)
{
if (check_collision(&player, &grid.block[i][j])) {
if (r_mouse == 1) {
r_mouse = 0; /* Reset the mouse the moment a single collision happened to ensure only a single block is clicked */
if (!grid.show[i][j] && player_bombs != 0) {
play_audio(SHOW_FLAG);
grid.show[i][j] = SHOW_FLAG;
player_bombs--;
break;
}
if (grid.show[i][j] == SHOW_FLAG) {
play_audio(SHOW_FLAG);
grid.show[i][j] = DONT_SHOW;
player_bombs++;
break;
}
break; /* No need to keep checking since the mouse is reset */
}
if (l_mouse == 1) {
l_mouse = 0;
reveal(i, j);
break;
}
}
}
}
video_loop();
SDL_Delay(1000/60);
}
return;
}
void game_over(int winstate)
{
for (int i = 0; i < GRID_Y; i++) for (int j = 0; j < GRID_X; j++) {
grid.show[i][j] = SHOW_TRUE;
if (grid.state[i][j] == UNCLICKED) grid.state[i][j] = EMPTY;
}
if (winstate == LOST) {
joe.state = ANGER;
/* play_audio(LOST); the explosion sound is enough and avoids conflict with explosion sound */
}
if (winstate == WON) {
joe.state = HAPPY;
play_audio(WON);
}
pause = 1;
}
int check_adjacent(int i, int j) /* Got too used to dealing with i and j with the for loops I guess */
{
int bombs = 0; /* This value stores the amount of bombs around a block not the amount of bombs on the whole grid */
/* check middle */
if (grid.bomb[i][j]) return 9; /* Since there can never be more than 8 bombs, this is a safe value to use */
/* check upper left */
if (i - 1 >= 0 && j - 1 >= 0) {
if (grid.bomb[i - 1][j - 1]) bombs++;
}
/* check upper middle */
if (i - 1 >= 0) {
if (grid.bomb[i - 1][j]) bombs++;
}
/* check upper right */
if (i - 1 >= 0 && j + 1 < GRID_X ) {
if (grid.bomb[i - 1][j + 1]) bombs++;
}
/* check middle left */
if (j - 1 >= 0) {
if (grid.bomb[i][j - 1]) bombs++;
}
/* check middle right */
if (j + 1 < GRID_X ) {
if (grid.bomb[i][j + 1]) bombs++;
}
/* check lower left */
if (i + 1 < GRID_Y && j - 1 >= 0) {
if (grid.bomb[i + 1][j - 1]) bombs++;
}
/* check lower middle */
if (i + 1 < GRID_Y) {
if (grid.bomb[i + 1][j]) bombs++;
}
/* check lower right */
if (i + 1 < GRID_Y && j + 1 < GRID_X) {
if (grid.bomb[i + 1][j + 1]) bombs++;
}
return bombs;
}
void reveal(int i, int j)
{
if (!grid.show[i][j]) {
grid.show[i][j] = SHOW_TRUE;
if (grid.state[i][j] == EXPLOSION) {
play_audio(EXPLOSION);
game_over(LOST);
} else {
play_audio(UNCLICKED);
}
if (grid.state[i][j] == UNCLICKED) {
grid.state[i][j] = EMPTY;
}
}
if (grid.state[i][j] == EMPTY) {
/* check upper middle */
if (i - 1 >= 0) {
if (grid.state[i - 1][j] == UNCLICKED)
{
grid.state[i - 1][j] = EMPTY;
grid.show[i - 1][j] = SHOW_TRUE;
reveal(i - 1, j);
} else {
grid.show[i - 1][j] = SHOW_TRUE;
}
}
/* check middle left */
if (j - 1 >= 0) {
if (grid.state[i][j - 1] == UNCLICKED)
{
grid.state[i][j - 1] = EMPTY;
grid.show[i][j - 1] = SHOW_TRUE;
reveal(i, j - 1);
} else {
grid.show[i][j - 1] = SHOW_TRUE;
}
}
/* check middle right */
if (j + 1 < GRID_X ) {
if (grid.state[i][j + 1] == UNCLICKED)
{
grid.state[i][j + 1] = EMPTY;
grid.show[i][j + 1] = SHOW_TRUE;
reveal(i, j + 1);
} else {
grid.show[i][j + 1] = SHOW_TRUE;
}
}
/* check lower middle */
if (i + 1 < GRID_Y) {
if (grid.state[i + 1][j] == UNCLICKED)
{
grid.state[i + 1][j] = EMPTY;
grid.show[i + 1][j] = SHOW_TRUE;
reveal(i + 1, j);
} else {
grid.show[i + 1][j] = SHOW_TRUE;
}
}
}
}
/* Populate grid with bombs */
void populate()
{
for (int i = 0; i < NUM_OF_BOMBS; i++) {
int rand_x = rand() % GRID_X;
int rand_y = rand() % GRID_Y;
if (!grid.bomb[rand_y][rand_x]) {
grid.bomb[rand_y][rand_x] = 1;
} else {
--i;
}
}
}
int check_collision(SDL_Rect * obj1, SDL_Rect * obj2)
{
if (obj1->x < obj2->x + obj2->w && obj1->x + obj1->w > obj2->x) {
if ( obj1->y < obj2->y + obj2->h && obj1->y + obj1->h > obj2->y) {
/* collision happened */
return 1;
}
}
return 0;
}

16
main.h Normal file
View File

@ -0,0 +1,16 @@
#include "defs.h"
#define LOST 0
#define WON 1
#define GRID_X 8
#define GRID_Y 8
#define NUM_OF_BOMBS 5
int check_collision(SDL_Rect *, SDL_Rect *);
void tick();
void game_over(int);
void populate();
int check_adjacent(int, int);
void reveal(int, int);

BIN
resources/bomb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

BIN
resources/click.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

BIN
resources/click.wav Normal file

Binary file not shown.

BIN
resources/click2.wav Normal file

Binary file not shown.

BIN
resources/explosion.wav Normal file

Binary file not shown.

BIN
resources/flag.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

BIN
resources/ground.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

BIN
resources/lose.wav Normal file

Binary file not shown.

BIN
resources/num1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

BIN
resources/num2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

BIN
resources/num3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

BIN
resources/num4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

BIN
resources/num5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

BIN
resources/num6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

BIN
resources/num7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

BIN
resources/num8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

BIN
resources/smiley_anger.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

BIN
resources/smiley_happy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

BIN
resources/smiley_idle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

BIN
resources/smiley_sweat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

BIN
resources/win.wav Normal file

Binary file not shown.