Initial commit
This commit is contained in:
commit
e75581fa78
17
Makefile
Normal file
17
Makefile
Normal file
|
@ -0,0 +1,17 @@
|
|||
CC := gcc
|
||||
CFLAGS := `sdl-config --libs --cflags` -ggdb3 -O0 --std=c99 -Wall -lSDL_image -lSDL_mixer -lm
|
||||
HDRS :=
|
||||
SRCS := src/main.c src/match.c src/graphics.c src/logic.c src/keys.c src/audio.c
|
||||
OBJS := $(SRCS:.c=.o)
|
||||
|
||||
EXEC := jiljil.dge
|
||||
|
||||
all: $(EXEC)
|
||||
|
||||
$(EXEC): $(OBJS) $(HDRS) Makefile
|
||||
$(CC) -o $@ $(OBJS) $(CFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f $(EXEC) $(OBJS)
|
||||
|
||||
.PHONY: all clean
|
20
Makefile.RS97
Normal file
20
Makefile.RS97
Normal file
|
@ -0,0 +1,20 @@
|
|||
CC := mipsel-linux-gcc
|
||||
CFLAGS := `sdl-config --libs --cflags` -ggdb3 -O0 --std=c99 -Wall -lSDL_image -lSDL_mixer -lm
|
||||
HDRS :=
|
||||
SRCS := src/main.c src/match.c src/graphics.c src/logic.c src/keys.c src/audio.c
|
||||
OBJS := $(SRCS:.c=.o)
|
||||
|
||||
EXEC := jiljil.dge
|
||||
|
||||
all: $(EXEC)
|
||||
|
||||
$(EXEC): $(OBJS) $(HDRS) Makefile
|
||||
$(CC) -o $@ $(OBJS) $(CFLAGS)
|
||||
cp ./jiljil.dge ./ipk/data/home/retrofw/games/jiljil-c/jiljil.dge
|
||||
cp -r assets ./ipk/data/home/retrofw/games/jiljil-c/assets/
|
||||
./ipk/create-ipk.sh
|
||||
|
||||
clean:
|
||||
rm -f $(EXEC) $(OBJS)
|
||||
|
||||
.PHONY: all clean
|
36
README.md
Normal file
36
README.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
# RetroFW JilJil
|
||||
|
||||
![1](https://telegra.ph/file/3402cbb5a0065adee1f4f.jpg)![2](https://telegra.ph/file/51443278b9b2e4f8213f5.jpg)![3](https://telegra.ph/file/fc95a25bf190d0b726c1e.jpg)
|
||||
|
||||
This repo contains the source code for my port of [JilJil](https://www.cavestory.org/pixels-works/jil-jil.php) for (hopefully) **RetroFW** compatible devices and **Linux**.
|
||||
|
||||
JilJil is a simple **arcade-style** score based game, where you control a weird **worm** inside an aquarium, and you have to run away from a **cat** that is trying to catch you by the ribbon on your tail. You also have to bounce off of a **lemon** as many times as you can.
|
||||
|
||||
While this game is named as a port of JilJil, the actual source code of JilJil is not publicly available, so I decided to rewrite the game from scratch and I've added some tweaks here and there to spice up the gameplay. The physics are not supposed to be 1:1 to actual JilJil!
|
||||
|
||||
Some of the assets and resources used to create this game are (c) 1997 Studio Pixel. If you represent mr. Daisuke Amaya, Studio Pixel, or any affiliates, please contact me at legal@massivebox.eu.org.
|
||||
|
||||
## Make-ing
|
||||
|
||||
### For Linux
|
||||
|
||||
Simply run `make`.
|
||||
You'll need `SDL` development libraries (including SDL Mixer and SDL Image), and the C compiler `gcc`.
|
||||
You will get an executable called `2048.dge`, run it and enjoy your 2048 experience!
|
||||
|
||||
### For RetroFW
|
||||
|
||||
Run `make -f Makefile.RS97`
|
||||
You'll need a [working buildroot installation](https://github.com/retrofw/retrofw.github.io/wiki/Configuring-a-Toolchain), that includes the SDL development libraries, and `gcc`. Since RetroFW runs on MIPSel devices, instead of the compiler `gcc`, the Makefile will use `mipsel-linux-gcc`, make sure it is a working command on your machine, if it isn't, make sure that the folder where the `mipsel-linux-gcc` binary is stored is in `$PATH`.
|
||||
You will get a file called `build.ipk` that you can [install](https://github.com/retrofw/retrofw.github.io/wiki/Emulators-and-Apps#install-ipk) on RetroFW devices.
|
||||
|
||||
### For Windows
|
||||
|
||||
I have no idea. Just get Linux :P
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are always welcome! You can contribute by opening a pull request or an issue.
|
||||
You can also report me stuff via email if you don't want to sign up to whichever Git server I choose to host this project.
|
||||
My mail is hello@massivebox.eu.org.
|
||||
|
BIN
assets/bgm/game_over
Normal file
BIN
assets/bgm/game_over
Normal file
Binary file not shown.
BIN
assets/bgm/in_game
Normal file
BIN
assets/bgm/in_game
Normal file
Binary file not shown.
BIN
assets/images/BMP_CHARACTOR.png
Normal file
BIN
assets/images/BMP_CHARACTOR.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
BIN
assets/images/JILJIL.png
Normal file
BIN
assets/images/JILJIL.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
BIN
assets/images/fpsfont.png
Normal file
BIN
assets/images/fpsfont.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
assets/images/icon.png
Normal file
BIN
assets/images/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 766 B |
BIN
assets/images/pause.png
Normal file
BIN
assets/images/pause.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 310 KiB |
BIN
assets/sfx/bongo
Normal file
BIN
assets/sfx/bongo
Normal file
Binary file not shown.
BIN
assets/sfx/cat_sound
Normal file
BIN
assets/sfx/cat_sound
Normal file
Binary file not shown.
BIN
assets/sfx/cho
Normal file
BIN
assets/sfx/cho
Normal file
Binary file not shown.
BIN
assets/sfx/clap
Normal file
BIN
assets/sfx/clap
Normal file
Binary file not shown.
BIN
assets/sfx/cough_cough
Normal file
BIN
assets/sfx/cough_cough
Normal file
Binary file not shown.
BIN
assets/sfx/game_start
Normal file
BIN
assets/sfx/game_start
Normal file
Binary file not shown.
BIN
assets/sfx/inhale
Normal file
BIN
assets/sfx/inhale
Normal file
Binary file not shown.
BIN
assets/sfx/reverse
Normal file
BIN
assets/sfx/reverse
Normal file
Binary file not shown.
BIN
assets/sfx/ronf
Normal file
BIN
assets/sfx/ronf
Normal file
Binary file not shown.
BIN
assets/sfx/rumble
Normal file
BIN
assets/sfx/rumble
Normal file
Binary file not shown.
BIN
assets/sfx/sneeze_long
Normal file
BIN
assets/sfx/sneeze_long
Normal file
Binary file not shown.
BIN
assets/sfx/sneeze_short
Normal file
BIN
assets/sfx/sneeze_short
Normal file
Binary file not shown.
11
ipk/control/control
Normal file
11
ipk/control/control
Normal file
|
@ -0,0 +1,11 @@
|
|||
Package: jiljil-c
|
||||
Version: 0.1
|
||||
Description: Arcade highscore-based game.
|
||||
Replaces: jiljil-c
|
||||
Section: games
|
||||
Priority: optional
|
||||
Maintainer: massivebox
|
||||
Architecture: mipsel
|
||||
Homepage: https://codeberg.org/massivebox/retrofw-jiljil-c
|
||||
Depends:
|
||||
Source: https://codeberg.org/massivebox/retrofw-jiljil-c
|
9
ipk/create-ipk.sh
Normal file
9
ipk/create-ipk.sh
Normal file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd ipk
|
||||
cd data && tar cvzf ../data.tar.gz *
|
||||
cd ../control && tar cvzf ../control.tar.gz *
|
||||
cd .. && ar rv build.ipk control.tar.gz data.tar.gz debian-binary
|
||||
rm data.tar.gz control.tar.gz
|
||||
rm -rf ./data/home/retrofw/games/jiljil-c/assets ./data/home/retrofw/games/jiljil-c/jiljil.dge
|
||||
mv build.ipk ..
|
|
@ -0,0 +1,4 @@
|
|||
title=JilJil
|
||||
description=Arcade highscore-based game.
|
||||
exec=/home/retrofw/games/jiljil-c/jiljil.dge
|
||||
clock=600
|
BIN
ipk/data/home/retrofw/games/jiljil-c/jiljil.png
Normal file
BIN
ipk/data/home/retrofw/games/jiljil-c/jiljil.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 766 B |
1
ipk/debian-binary
Normal file
1
ipk/debian-binary
Normal file
|
@ -0,0 +1 @@
|
|||
2.0
|
128
src/audio.c
Normal file
128
src/audio.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
#include "include.h"
|
||||
|
||||
#include "audio.h"
|
||||
|
||||
// sfx
|
||||
Mix_Chunk *bongo;
|
||||
Mix_Chunk *cat_sound;
|
||||
Mix_Chunk *cho;
|
||||
Mix_Chunk *clap;
|
||||
Mix_Chunk *cough_cough;
|
||||
Mix_Chunk *game_start;
|
||||
Mix_Chunk *inhale;
|
||||
Mix_Chunk *reverse;
|
||||
Mix_Chunk *ronf;
|
||||
Mix_Chunk *rumble;
|
||||
Mix_Chunk *sneeze_long;
|
||||
Mix_Chunk *sneeze_short;
|
||||
|
||||
// bgm
|
||||
Mix_Chunk *game_over;
|
||||
Mix_Chunk *in_game;
|
||||
|
||||
int bgm_channel = 0;
|
||||
|
||||
void load_audio(void) {
|
||||
|
||||
bongo = Mix_LoadWAV("assets/sfx/bongo");
|
||||
cat_sound = Mix_LoadWAV("assets/sfx/cat_sound");
|
||||
cho = Mix_LoadWAV("assets/sfx/cho");
|
||||
clap = Mix_LoadWAV("assets/sfx/clap");
|
||||
cough_cough = Mix_LoadWAV("assets/sfx/cough_cough");
|
||||
game_start = Mix_LoadWAV("assets/sfx/game_start");
|
||||
inhale = Mix_LoadWAV("assets/sfx/inhale");
|
||||
reverse = Mix_LoadWAV("assets/sfx/reverse");
|
||||
ronf = Mix_LoadWAV("assets/sfx/ronf");
|
||||
rumble = Mix_LoadWAV("assets/sfx/rumble");
|
||||
sneeze_long = Mix_LoadWAV("assets/sfx/sneeze_long");
|
||||
sneeze_short = Mix_LoadWAV("assets/sfx/sneeze_short");
|
||||
|
||||
game_over = Mix_LoadWAV("assets/bgm/game_over");
|
||||
in_game = Mix_LoadWAV("assets/bgm/in_game");
|
||||
|
||||
}
|
||||
|
||||
void unload_audio(void) {
|
||||
|
||||
Mix_FreeChunk(bongo);
|
||||
Mix_FreeChunk(cat_sound);
|
||||
Mix_FreeChunk(cho);
|
||||
Mix_FreeChunk(clap);
|
||||
Mix_FreeChunk(cough_cough);
|
||||
Mix_FreeChunk(game_start);
|
||||
Mix_FreeChunk(inhale);
|
||||
Mix_FreeChunk(reverse);
|
||||
Mix_FreeChunk(ronf);
|
||||
Mix_FreeChunk(rumble);
|
||||
Mix_FreeChunk(sneeze_long);
|
||||
Mix_FreeChunk(sneeze_short);
|
||||
|
||||
Mix_FreeChunk(game_over);
|
||||
Mix_FreeChunk(in_game);
|
||||
|
||||
}
|
||||
|
||||
int play_sound_internal(char *name, int loop) {
|
||||
|
||||
Mix_Chunk *sound;
|
||||
|
||||
if(!strcmp(name, "bongo")) {
|
||||
sound = bongo;
|
||||
} else if (!strcmp(name, "cat_sound")) {
|
||||
sound = cat_sound;
|
||||
} else if (!strcmp(name, "cho")) {
|
||||
sound = cho;
|
||||
} else if (!strcmp(name, "clap")) {
|
||||
sound = clap;
|
||||
} else if (!strcmp(name, "cough_cough")) {
|
||||
sound = cough_cough;
|
||||
} else if (!strcmp(name, "game_start")) {
|
||||
sound = game_start;
|
||||
} else if (!strcmp(name, "inhale")) {
|
||||
sound = inhale;
|
||||
} else if (!strcmp(name, "reverse")) {
|
||||
sound = reverse;
|
||||
} else if (!strcmp(name, "ronf")) {
|
||||
sound = ronf;
|
||||
} else if (!strcmp(name, "rumble")) {
|
||||
sound = rumble;
|
||||
} else if (!strcmp(name, "sneeze_long")) {
|
||||
sound = sneeze_long;
|
||||
} else if (!strcmp(name, "sneeze_short")) {
|
||||
sound = sneeze_short;
|
||||
} else if (!strcmp(name, "game_over")) {
|
||||
sound = game_over;
|
||||
} else if (!strcmp(name, "in_game")) {
|
||||
sound = in_game;
|
||||
}
|
||||
|
||||
return Mix_PlayChannel(-1, sound, loop);
|
||||
|
||||
}
|
||||
|
||||
void play_sound(char *name) {
|
||||
play_sound_internal(name, 0);
|
||||
}
|
||||
|
||||
void play_sound_and_wait(char *name) {
|
||||
int chan = play_sound_internal(name, 0);
|
||||
int playing = Mix_Playing(chan);
|
||||
while(playing) { // wait for sound to end
|
||||
SDL_Delay(50);
|
||||
playing = Mix_Playing(chan);
|
||||
}
|
||||
SDL_Delay(500);
|
||||
}
|
||||
|
||||
void play_bgm(char *name) {
|
||||
bgm_channel = play_sound_internal(name, -1);
|
||||
}
|
||||
void pause_bgm(void) {
|
||||
Mix_Pause(bgm_channel);
|
||||
}
|
||||
void resume_bgm(void) {
|
||||
Mix_Resume(bgm_channel);
|
||||
}
|
||||
void stop_bgm(void) {
|
||||
Mix_HaltChannel(bgm_channel);
|
||||
}
|
10
src/audio.h
Normal file
10
src/audio.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
void play_sound(char *name);
|
||||
void play_sound_and_wait(char *name);
|
||||
void play_bgm(char *name);
|
||||
|
||||
void pause_bgm(void);
|
||||
void resume_bgm(void);
|
||||
void stop_bgm(void);
|
||||
|
||||
void load_audio(void);
|
||||
void unload_audio(void);
|
77
src/graphics.c
Normal file
77
src/graphics.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include "include.h"
|
||||
|
||||
#include "main.h"
|
||||
|
||||
extern SDL_Surface *tilesIMG;
|
||||
extern SDL_Surface *fpsFontIMG;
|
||||
|
||||
// load_asset is a helper function to reload assets from a file
|
||||
SDL_Surface* load_asset(char path[]) {
|
||||
|
||||
SDL_Surface* _img = IMG_Load(path);
|
||||
SDL_Surface* img = SDL_DisplayFormat(_img);
|
||||
SDL_FreeSurface(_img);
|
||||
|
||||
return img;
|
||||
|
||||
}
|
||||
|
||||
// print_score draws the specified score on the specified screen at the specified coordinates
|
||||
void print_score(int score_x, int score_y, int number, SDL_Surface * screen) {
|
||||
|
||||
int n = log10(number) + 1;
|
||||
int i;
|
||||
int *numberArray = calloc(n, sizeof(int));
|
||||
for ( i = 0; i < n; ++i, number /= 10 )
|
||||
{
|
||||
numberArray[i] = number % 10;
|
||||
}
|
||||
|
||||
SDL_Rect SrcZero = {x: 0, y: 112, w: 8, h: 16};
|
||||
SDL_Rect DstDigitZero = {x: score_x, y: score_y};
|
||||
SDL_Rect DstDigitOne = {x: score_x + 8, y: score_y};
|
||||
SDL_Rect DstDigitTwo = {x: score_x + 16, y: score_y};
|
||||
|
||||
if(n == 1) {
|
||||
SDL_BlitSurface(tilesIMG, &SrcZero, screen, &DstDigitZero);
|
||||
SDL_BlitSurface(tilesIMG, &SrcZero, screen, &DstDigitOne);
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 8 * numberArray[0], y: 112, w: 8, h: 16}, screen, &DstDigitTwo);
|
||||
} else if(n == 2) {
|
||||
SDL_BlitSurface(tilesIMG, &SrcZero, screen, &DstDigitZero);
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 8 * numberArray[0], y: 112, w: 8, h: 16}, screen, &DstDigitTwo);
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 8 * numberArray[1], y: 112, w: 8, h: 16}, screen, &DstDigitOne);
|
||||
} else if(n == 3) {
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 8 * numberArray[0], y: 112, w: 8, h: 16}, screen, &DstDigitTwo);
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 8 * numberArray[1], y: 112, w: 8, h: 16}, screen, &DstDigitOne);
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 8 * numberArray[2], y: 112, w: 8, h: 16}, screen, &DstDigitZero);
|
||||
} else { // for zero digits and more than 3 we just show zeroes lol
|
||||
SDL_BlitSurface(tilesIMG, &SrcZero, screen, &DstDigitTwo);
|
||||
SDL_BlitSurface(tilesIMG, &SrcZero, screen, &DstDigitOne);
|
||||
SDL_BlitSurface(tilesIMG, &SrcZero, screen, &DstDigitZero);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// clear_screen resets the screen
|
||||
void clear_screen(SDL_Surface* screen) {
|
||||
|
||||
SDL_FillRect(screen, NULL, 0);
|
||||
|
||||
int row, col;
|
||||
for (row = 0; row < 2; row++) {
|
||||
for (col = 0; col < 14; col++) {
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 64, y: 64, w: 20, h: 20}, screen, &(SDL_Rect){x: 21 + 20*col, y: row*221});
|
||||
}
|
||||
}
|
||||
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 80, y: 112, w: 17, h: 7}, screen, &(SDL_Rect){x: 208, y: 22}); //Hi
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 80, y: 121, w: 47, h: 7}, screen, &(SDL_Rect){x: 226, y: 22}); //Score
|
||||
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 80, y: 121, w: 47, h: 7}, screen, &(SDL_Rect){x: 226, y: 213}); //Score
|
||||
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 64, y: 95, w: 23, h: 7}, screen, &(SDL_Rect){x: 22, y: 213}); //JpLeft
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 64, y: 84, w: 65, h: 8}, screen, &(SDL_Rect){x: 49, y: 212}); //JpRight
|
||||
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 80, y: 16, w: 48, h: 7}, screen, &(SDL_Rect){x: 141, y: 224}); //exit->esc
|
||||
|
||||
}
|
8
src/graphics.h
Normal file
8
src/graphics.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
void clear_screen(SDL_Surface*);
|
||||
void game_over_animation(SDL_Surface*);
|
||||
void game_won_animation(SDL_Surface*);
|
||||
void print_board(SDL_Surface*);
|
||||
void move_board(int, SDL_Surface*);
|
||||
void print_score(int, int, int, SDL_Surface*);
|
||||
|
||||
SDL_Surface* load_asset(char path[]);
|
11
src/include.h
Normal file
11
src/include.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_image.h>
|
||||
#include "SDL/SDL_mixer.h"
|
||||
#include "SDL/SDL_sound.h"
|
37
src/keys.c
Normal file
37
src/keys.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include "include.h"
|
||||
|
||||
int internal_keycode_from_sdl(int sdl_keycode) {
|
||||
|
||||
/*
|
||||
invalid = -1
|
||||
up = 0
|
||||
right = 1
|
||||
down = 2
|
||||
left = 3
|
||||
start = 4
|
||||
select = 5
|
||||
*/
|
||||
|
||||
|
||||
switch(sdl_keycode) {
|
||||
case SDLK_ESCAPE: //Select
|
||||
return 5;
|
||||
case SDLK_RETURN:
|
||||
return 4;
|
||||
case SDLK_LCTRL: // A button
|
||||
case SDLK_RIGHT: // right
|
||||
return 1;
|
||||
case SDLK_LSHIFT: // Y button
|
||||
case SDLK_LEFT: // left
|
||||
return 3;
|
||||
case SDLK_LALT: // B button
|
||||
case SDLK_DOWN: // down
|
||||
return 2;
|
||||
case SDLK_SPACE: // X button
|
||||
case SDLK_UP: // up
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
1
src/keys.h
Normal file
1
src/keys.h
Normal file
|
@ -0,0 +1 @@
|
|||
int internal_keycode_from_sdl(int);
|
135
src/logic.c
Normal file
135
src/logic.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
#include "include.h"
|
||||
|
||||
// get_best_score_from_file loads the best saved score from best_score.txt and puts it to best_score
|
||||
int get_best_score_from_file(void) {
|
||||
|
||||
if(access("./best_score.txt", F_OK) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *fp;
|
||||
char buff[10];
|
||||
fp = fopen("./best_score.txt", "r");
|
||||
fscanf(fp, "%s", buff);
|
||||
int bs;
|
||||
sscanf(buff, "%d", &bs);
|
||||
return bs;
|
||||
|
||||
}
|
||||
|
||||
// save_best_score_to_file puts the best score (from global var best_score) to best_score.txt
|
||||
void save_best_score_to_file(int score) {
|
||||
|
||||
int best_score = score;
|
||||
FILE *fp = fopen("./best_score.txt", "w");
|
||||
char snum[5];
|
||||
sprintf(snum, "%d", best_score);
|
||||
fputs(snum, fp);
|
||||
fclose(fp);
|
||||
|
||||
}
|
||||
|
||||
float points_distance(int x1, int y1, int x2, int y2) {
|
||||
return sqrt(pow(x2- x1, 2) + pow(y2-y1, 2));
|
||||
}
|
||||
|
||||
int is_player_inside_lemon(int player_x, int player_y, int lemon_x, int lemon_y) {
|
||||
return points_distance(player_x, player_y, lemon_x+32, lemon_y+32) < 32;
|
||||
}
|
||||
|
||||
|
||||
void entity_decelerate(float *speed_x, float *speed_y, float deceleration) {
|
||||
|
||||
if(*speed_x > 0) {
|
||||
*speed_x -= deceleration;
|
||||
}else{
|
||||
*speed_x += deceleration;
|
||||
}
|
||||
if(*speed_y > 0) {
|
||||
*speed_y -= deceleration;
|
||||
}else{
|
||||
*speed_y += deceleration;
|
||||
}
|
||||
|
||||
}
|
||||
void player_decelerate(float *speed_x, float *speed_y) {
|
||||
entity_decelerate(speed_x, speed_y, 0.1);
|
||||
}
|
||||
void lemon_decelerate(float *speed_x, float *speed_y) {
|
||||
entity_decelerate(speed_x, speed_y, 0.005);
|
||||
*speed_y += 0.05;
|
||||
}
|
||||
|
||||
void entity_cap(float *speed_x, float *speed_y) {
|
||||
|
||||
if(*speed_x > 3) {
|
||||
*speed_x = 3;
|
||||
}
|
||||
if(*speed_x < -3) {
|
||||
*speed_x = -3;
|
||||
}
|
||||
if(*speed_y > 3) {
|
||||
*speed_y = 3;
|
||||
}
|
||||
if(*speed_y < -3) {
|
||||
*speed_y = -3;
|
||||
}
|
||||
|
||||
}
|
||||
void player_cap(float *speed_x, float *speed_y) {
|
||||
entity_cap(speed_x, speed_y);
|
||||
}
|
||||
void lemon_cap(float *speed_x, float *speed_y) {
|
||||
entity_cap(speed_x, speed_y);
|
||||
}
|
||||
|
||||
void player_approximate(float *player_speed_x, float *player_speed_y) {
|
||||
if(*player_speed_x > -0.1 && *player_speed_x < 0.1) {
|
||||
*player_speed_x = 0;
|
||||
}
|
||||
if(*player_speed_y > -0.1 && *player_speed_y < 0.1) {
|
||||
*player_speed_y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void avoid_entity_outside_bonds(int *x, int *y, float *speed_x, float *speed_y, int br_x, int br_y) {
|
||||
if(*x < 20 || *x > br_x) {
|
||||
if(*x < 20) {
|
||||
*x = 20;
|
||||
}else{
|
||||
*x = br_x;
|
||||
}
|
||||
*speed_x = -*speed_x;
|
||||
}
|
||||
if(*y < 20 || *y > br_y) {
|
||||
if(*y < 20) {
|
||||
*y = 20;
|
||||
}else{
|
||||
*y = br_y;
|
||||
}
|
||||
*speed_y = -*speed_y;
|
||||
}
|
||||
}
|
||||
void avoid_player_outside_bonds(int *x, int *y, float *speed_x, float *speed_y) {
|
||||
avoid_entity_outside_bonds(x, y, speed_x, speed_y, 284, 204);
|
||||
}
|
||||
void avoid_lemon_outside_bonds(int *x, int *y, float *speed_x, float *speed_y) {
|
||||
avoid_entity_outside_bonds(x, y, speed_x, speed_y, 237, 157);
|
||||
}
|
||||
|
||||
int check_player_inside_prints(int tail_x, int tail_y, int paw1_x, int paw1_y, int paw2_x, int paw2_y) {
|
||||
|
||||
if(tail_x + 5 >= paw1_x && tail_x <= paw1_x + 10) {
|
||||
if(tail_y + 5 >= paw1_y && tail_y <= paw1_y + 10) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if(tail_x + 5 >= paw2_x && tail_x <= paw2_x + 10) {
|
||||
if(tail_y + 5 >= paw2_y && tail_y <= paw2_y + 10) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
15
src/logic.h
Normal file
15
src/logic.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
int get_best_score_from_file(void);
|
||||
void save_best_score_to_file(int);
|
||||
|
||||
int is_player_inside_lemon(int, int, int, int);
|
||||
|
||||
void player_decelerate(float*, float*);
|
||||
void player_cap(float*, float*);
|
||||
void player_approximate(float*, float*);
|
||||
void avoid_player_outside_bonds(int*, int*, float*, float*);
|
||||
|
||||
void lemon_decelerate(float*, float*);
|
||||
void lemon_cap(float*, float*);
|
||||
void avoid_lemon_outside_bonds(int*, int*, float*, float*);
|
||||
|
||||
int check_player_inside_prints(int, int, int, int, int, int);
|
49
src/main.c
Normal file
49
src/main.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include "include.h"
|
||||
|
||||
//#include "main.h"
|
||||
#include "audio.h"
|
||||
#include "match.h"
|
||||
#include "graphics.h"
|
||||
|
||||
SDL_Surface *tilesIMG;
|
||||
SDL_Surface *fpsFontIMG;
|
||||
|
||||
int main(void) {
|
||||
|
||||
// attempt to initialize graphics and timer systema
|
||||
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) != 0) {
|
||||
printf("error initializing SDL: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
atexit(SDL_Quit);
|
||||
|
||||
SDL_Surface * screen = SDL_SetVideoMode(320, 240, 16, SDL_SWSURFACE);
|
||||
if (!screen) {
|
||||
printf("error creating window: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
|
||||
if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096) != 0) {
|
||||
printf("error initializing SDL Mixer: %s\n", Mix_GetError());
|
||||
}
|
||||
load_audio();
|
||||
|
||||
tilesIMG = load_asset("assets/images/JILJIL.png");
|
||||
fpsFontIMG = load_asset("assets/images/fpsfont.png");
|
||||
|
||||
int quit = 0;
|
||||
quit = boot_animation(screen);
|
||||
if(!quit) {
|
||||
while(!quit) {
|
||||
quit = match(screen);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Quit();
|
||||
unload_audio();
|
||||
Mix_Quit();
|
||||
|
||||
}
|
7
src/main.h
Normal file
7
src/main.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef MAINDOTH
|
||||
#define MAINDOTH
|
||||
|
||||
extern SDL_Surface *tilesIMG;
|
||||
extern SDL_Surface *fpsFontIMG;
|
||||
|
||||
#endif
|
351
src/match.c
Normal file
351
src/match.c
Normal file
|
@ -0,0 +1,351 @@
|
|||
#include "include.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "audio.h"
|
||||
#include "logic.h"
|
||||
#include "graphics.h"
|
||||
#include "keys.h"
|
||||
|
||||
int pause_game(SDL_Surface *screen) {
|
||||
|
||||
pause_bgm();
|
||||
//return 1 = quit; return 0 = proceed
|
||||
SDL_Surface *pauseIMG = load_asset("assets/images/pause.png");
|
||||
|
||||
SDL_BlitSurface(pauseIMG, NULL, screen, NULL);
|
||||
SDL_Flip(screen);
|
||||
|
||||
SDL_FreeSurface(pauseIMG);
|
||||
|
||||
SDL_Event event;
|
||||
while (1) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
return 1;
|
||||
case SDL_KEYDOWN:
|
||||
switch (event.key.keysym.sym) {
|
||||
case SDLK_ESCAPE: //select -> exit
|
||||
return 1;
|
||||
case SDLK_RETURN: //start -> continue
|
||||
resume_bgm();
|
||||
return 0;
|
||||
case SDLK_BACKSPACE: //R -> reset
|
||||
resume_bgm();
|
||||
return 2;
|
||||
break;
|
||||
case SDLK_LSHIFT: //Y -> clear best score
|
||||
save_best_score_to_file(0);
|
||||
resume_bgm();
|
||||
return 2;
|
||||
case SDLK_SPACE: //X -> zen mode
|
||||
// to be implemented soon (TM)
|
||||
break;
|
||||
case SDLK_LALT: //B -> hard mode
|
||||
// to be implemented soon (TM)
|
||||
break;
|
||||
case SDLK_LCTRL: //A -> normal
|
||||
// to be implemented soon (TM)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_Delay(100);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int match(SDL_Surface *screen) {
|
||||
|
||||
//return 1 = quit; return 0 = new game
|
||||
|
||||
int game_over = 0;
|
||||
|
||||
int player_x = 155;
|
||||
int player_y = 213;
|
||||
float player_speed_x = 0;
|
||||
float player_speed_y = 0;
|
||||
|
||||
int player_last_x_1 = 0;
|
||||
int player_last_y_1 = 0;
|
||||
int paw1_x = 0;
|
||||
int paw1_y = 0;
|
||||
int player_last_x_2 = 0;
|
||||
int player_last_y_2 = 0;
|
||||
int paw2_x = 0;
|
||||
int paw2_y = 0;
|
||||
|
||||
int lemon_x = 0;
|
||||
int lemon_y = 0;
|
||||
float lemon_speed_x = 2.5;
|
||||
float lemon_speed_y = 2.5;
|
||||
|
||||
int down_keys[6] = {0};
|
||||
int score = 0;
|
||||
int best_score = get_best_score_from_file();
|
||||
|
||||
int player_past_x[40] = {0};
|
||||
int player_past_y[40] = {0};
|
||||
|
||||
long long frame = 0;
|
||||
long long last_point = 0;
|
||||
|
||||
play_sound("game_start");
|
||||
stop_bgm();
|
||||
play_bgm("in_game");
|
||||
while(!game_over) {
|
||||
|
||||
|
||||
frame++;
|
||||
Uint32 start = SDL_GetTicks();
|
||||
SDL_Event event;
|
||||
|
||||
// add or remove keys to the down keys array
|
||||
int key = 0;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
return 1;
|
||||
case SDL_KEYDOWN:
|
||||
key = internal_keycode_from_sdl(event.key.keysym.sym);
|
||||
if(key != -1) {
|
||||
down_keys[key] = 1;
|
||||
}
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
key = internal_keycode_from_sdl(event.key.keysym.sym);
|
||||
if(key != -1) {
|
||||
down_keys[key] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
player_decelerate(&player_speed_x, &player_speed_y);
|
||||
player_cap(&player_speed_x, &player_speed_y);
|
||||
player_approximate(&player_speed_x, &player_speed_y);
|
||||
avoid_player_outside_bonds(&player_x, &player_y, &player_speed_x, &player_speed_y);
|
||||
|
||||
// add speed according to down keys
|
||||
if(down_keys[0]) {
|
||||
player_speed_y -= 0.2;
|
||||
}
|
||||
if(down_keys[1]) {
|
||||
player_speed_x += 0.2;
|
||||
}
|
||||
if(down_keys[2]) {
|
||||
player_speed_y += 0.2;
|
||||
}
|
||||
if(down_keys[3]) {
|
||||
player_speed_x -= 0.2;
|
||||
}
|
||||
|
||||
// add player speed to player position
|
||||
player_x += player_speed_x;
|
||||
player_y += player_speed_y;
|
||||
|
||||
|
||||
lemon_decelerate(&lemon_speed_x, &lemon_speed_y);
|
||||
lemon_cap(&lemon_speed_x, &lemon_speed_y);
|
||||
avoid_lemon_outside_bonds(&lemon_x, &lemon_y, &lemon_speed_x, &lemon_speed_y);
|
||||
|
||||
// add lemon speed to lemon position
|
||||
lemon_x += lemon_speed_x;
|
||||
lemon_y += lemon_speed_y;
|
||||
|
||||
if (is_player_inside_lemon(player_x, player_y, lemon_x, lemon_y)) {
|
||||
lemon_speed_x = lemon_speed_x + player_speed_x;
|
||||
lemon_speed_y = lemon_speed_y + player_speed_y;
|
||||
player_speed_x = -player_speed_x * 0.9;
|
||||
player_speed_y = -player_speed_y * 0.9;
|
||||
if(last_point + 30 < frame) {
|
||||
score++;
|
||||
play_sound("clap");
|
||||
last_point = frame;
|
||||
}
|
||||
}
|
||||
|
||||
clear_screen(screen);
|
||||
|
||||
// update paw prints
|
||||
if(frame % 30 == 0) {
|
||||
if((frame / 30) % 2 == 0) {
|
||||
player_last_x_1 = player_past_x[0];
|
||||
player_last_y_1 = player_past_y[0];
|
||||
paw1_x = player_last_x_2;
|
||||
paw1_y = player_last_y_2;
|
||||
}else{
|
||||
player_last_x_2 = player_past_x[0];
|
||||
player_last_y_2 = player_past_y[0];
|
||||
paw2_x = player_last_x_1;
|
||||
paw2_y = player_last_y_1;
|
||||
}
|
||||
}
|
||||
|
||||
// TEST
|
||||
// SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 31, y: 79, w: 5, h: 5}, screen, &(SDL_Rect){x: player_past_x[5], y: player_past_y[5]});
|
||||
|
||||
if(check_player_inside_prints(player_past_x[5], player_past_y[5], paw1_x, paw1_y, paw2_x, paw2_y)) {
|
||||
if(frame > 180) {
|
||||
game_over = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// draw lemon
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 0, y: 48, w: 64, h: 64}, screen, &(SDL_Rect){x: lemon_x, y: lemon_y});
|
||||
|
||||
// add position to past positions and draw tail pieces
|
||||
int *temp_past_x;
|
||||
temp_past_x = player_past_x;
|
||||
int *temp_past_y;
|
||||
temp_past_y = player_past_y;
|
||||
int i;
|
||||
for(i = 0; i < 39; i++) {
|
||||
player_past_x[i] = temp_past_x[i+1];
|
||||
player_past_y[i] = temp_past_y[i+1];
|
||||
if(i % 5 == 0 && player_past_x[i] != 0 && player_past_y[i] != 0) {
|
||||
// draw player tail pieces
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 128 - i/5 * 16, y: 0, w: 16, h: 16}, screen, &(SDL_Rect){x: player_past_x[i], y: player_past_y[i]});
|
||||
}
|
||||
}
|
||||
player_past_x[39] = player_x;
|
||||
player_past_y[39] = player_y;
|
||||
|
||||
// draw player head
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 0, y: 0, w: 16, h: 16}, screen, &(SDL_Rect){x: player_x, y: player_y});
|
||||
|
||||
// add paw prints
|
||||
if(paw1_x != 0) { // make sure it isn't in the first secs of the game where random prints would appear in top left
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 0, y: 16, w: 32, h: 32}, screen, &(SDL_Rect){x: paw1_x, y: paw1_y});
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 32, y: 16, w: 32, h: 32}, screen, &(SDL_Rect){x: paw2_x, y: paw2_y});
|
||||
}
|
||||
|
||||
// handle pause input
|
||||
int was_paused = 0;
|
||||
if(down_keys[4] || down_keys[5]) {
|
||||
switch(pause_game(screen)) {
|
||||
case 1: // request to exit
|
||||
return 1;
|
||||
case 2: // restart the game
|
||||
return 0;
|
||||
}
|
||||
was_paused = 1;
|
||||
down_keys[4] = 0;
|
||||
down_keys[5] = 0;
|
||||
}
|
||||
|
||||
print_score(276, 204, score, screen); // current score
|
||||
print_score(276, 21, best_score, screen); // best score
|
||||
|
||||
|
||||
SDL_Flip(screen);
|
||||
|
||||
// sleep so that the fps stays at abt 60fps
|
||||
if(!was_paused) {
|
||||
|
||||
Uint32 end = SDL_GetTicks();
|
||||
float elapsedMS = end - start;
|
||||
|
||||
SDL_Delay(floor(16.666f - elapsedMS));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
stop_bgm();
|
||||
play_bgm("game_over");
|
||||
|
||||
if(score > best_score) {
|
||||
save_best_score_to_file(score);
|
||||
}
|
||||
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 64, y: 32, w: 64, h: 16}, screen, &(SDL_Rect){x: 133, y: 206}); // push start
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 64, y: 16, w: 16, h: 16}, screen, &(SDL_Rect){x: player_x, y: player_y}); // caught face
|
||||
SDL_Flip(screen);
|
||||
|
||||
SDL_Event event;
|
||||
while (1) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
return 1;
|
||||
case SDL_KEYDOWN:
|
||||
switch (event.key.keysym.sym) {
|
||||
case SDLK_ESCAPE: //select -> pause menu
|
||||
pause_game(screen);
|
||||
case SDLK_RETURN: //start -> new game
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_Delay(100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int boot_animation(SDL_Surface *screen) {
|
||||
|
||||
//return 1 = quit 0 = continue;
|
||||
|
||||
SDL_Event event;
|
||||
SDL_Flip(screen);
|
||||
|
||||
play_sound_and_wait("inhale");
|
||||
SDL_Rect SrcR = {x: 89, y: 64, w: 35, h: 20};
|
||||
SDL_Rect DestR = {x: 126, y: 51};
|
||||
SDL_BlitSurface(tilesIMG, &SrcR, screen, &DestR); //Jil
|
||||
SDL_Flip(screen);
|
||||
|
||||
DestR.x = 126+35;
|
||||
SDL_BlitSurface(tilesIMG, &SrcR, screen, &DestR); //Jil
|
||||
SDL_Flip(screen);
|
||||
|
||||
play_sound_and_wait("sneeze_long");
|
||||
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 80, y: 25, w: 44, h: 7}, screen, &(SDL_Rect){x: 138, y: 121}); //Date
|
||||
SDL_Flip(screen);
|
||||
|
||||
play_sound_and_wait("sneeze_short");
|
||||
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 64, y: 103, w: 55, h: 9}, screen, &(SDL_Rect){x: 133, y: 141}); //Tortoiseshell
|
||||
SDL_Flip(screen);
|
||||
//SDL_Delay(1000);
|
||||
|
||||
play_sound_and_wait("cough_cough");
|
||||
while (SDL_PollEvent(&event)) {
|
||||
// discard the inputs
|
||||
}
|
||||
|
||||
SDL_BlitSurface(tilesIMG, &(SDL_Rect){x: 66, y: 37, w: 62, h: 10}, screen, &(SDL_Rect){x: 133, y: 166}); //Push start
|
||||
SDL_Flip(screen);
|
||||
|
||||
play_sound("ronf");
|
||||
|
||||
while (1) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
return 1;
|
||||
case SDL_KEYDOWN:
|
||||
switch (event.key.keysym.sym) {
|
||||
case SDLK_ESCAPE: //select -> pause menu
|
||||
if(pause_game(screen)) {
|
||||
return 1;
|
||||
}
|
||||
case SDLK_RETURN: //start -> continue
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_Delay(100);
|
||||
}
|
||||
|
||||
}
|
3
src/match.h
Normal file
3
src/match.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
int match(SDL_Surface *);
|
||||
int pause_game(SDL_Surface *);
|
||||
int boot_animation(SDL_Surface *);
|
Loading…
Reference in a new issue