Various improvements
- Better score saving with error handling - Added OPK support (yay!) - Improved README
This commit is contained in:
parent
db5163c945
commit
a3f0d66c2b
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
build.ipk
|
||||||
|
build.opk
|
||||||
|
jiljil.dge
|
||||||
|
*.o
|
|
@ -10,11 +10,19 @@ all: $(EXEC)
|
||||||
|
|
||||||
$(EXEC): $(OBJS) $(HDRS) Makefile
|
$(EXEC): $(OBJS) $(HDRS) Makefile
|
||||||
$(CC) -o $@ $(OBJS) $(CFLAGS)
|
$(CC) -o $@ $(OBJS) $(CFLAGS)
|
||||||
cp ./jiljil.dge ./ipk/data/home/retrofw/games/jiljil-c/jiljil.dge
|
|
||||||
|
ipk: all
|
||||||
|
cp $(EXEC) ./ipk/data/home/retrofw/games/jiljil-c/jiljil.dge
|
||||||
cp -r assets ./ipk/data/home/retrofw/games/jiljil-c/assets/
|
cp -r assets ./ipk/data/home/retrofw/games/jiljil-c/assets/
|
||||||
./ipk/create-ipk.sh
|
./ipk/create-ipk.sh
|
||||||
|
|
||||||
|
opk: all
|
||||||
|
cp $(EXEC) ./opk/jiljil.dge
|
||||||
|
cp -r assets ./opk/assets/
|
||||||
|
mksquashfs opk build.opk -noappend -no-xattrs
|
||||||
|
rm -rf ./opk/jiljil.dge ./opk/assets
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(EXEC) $(OBJS)
|
rm -f $(EXEC) $(OBJS) build.ipk build.opk
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
18
README.md
18
README.md
|
@ -8,29 +8,29 @@ JilJil is a simple **arcade-style** score based game, where you control a weird
|
||||||
|
|
||||||
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!
|
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.
|
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.net.
|
||||||
|
|
||||||
## Make-ing
|
## Make-ing
|
||||||
|
|
||||||
### For Linux
|
### On Linux
|
||||||
|
|
||||||
Simply run `make`.
|
Simply run `make`.
|
||||||
You'll need `SDL` development libraries (including SDL Mixer and SDL Image), and the C compiler `gcc`.
|
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!
|
You will get an executable called `2048.dge`, run it and enjoy your 2048 experience!
|
||||||
|
|
||||||
### For RetroFW
|
### On Linux for RetroFW
|
||||||
|
|
||||||
Run `make -f Makefile.RS97`
|
Run `make -f Makefile.rfw ipk` to generate an IPK file, or `make -f Makefile.rfw opk` to generate an OPK (recommended).
|
||||||
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 need the [RetroFW Buildroot](https://github.com/retrofw/buildroot-retrofw-2.3/tree/2021.11.x) to cross-compile. Check out my project [RetroFW Docker Buildroot](https://gitea.massivebox.net/massivebox/retrofw-docker-buildroot) to install the Buildroot in an easier and platform-independent way.
|
||||||
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
|
### On Windows or MacOS for RetroFW
|
||||||
|
|
||||||
I have no idea. Just get Linux :P
|
Run `make -f Makefile.rfw ipk` to generate an IPK file, or `make -f Makefile.rfw opk` to generate an OPK (recommended).
|
||||||
|
Since these platforms don't natively support Buildroot, I recommend you to use the [RetroFW Docker Buildroot](https://gitea.massivebox.net/massivebox/retrofw-docker-buildroot).
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Contributions are always welcome! You can contribute by opening a pull request or an issue.
|
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.
|
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.
|
My mail is hello@massivebox.net.
|
||||||
|
|
||||||
|
|
0
ipk/create-ipk.sh
Normal file → Executable file
0
ipk/create-ipk.sh
Normal file → Executable file
9
opk/default.retrofw.desktop
Normal file
9
opk/default.retrofw.desktop
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=JilJil
|
||||||
|
Comment=Arcade highscore-based game.
|
||||||
|
Exec=jiljil.dge
|
||||||
|
Terminal=false
|
||||||
|
Type=Game
|
||||||
|
StartupNotify=true
|
||||||
|
Icon=jiljil
|
||||||
|
Categories=games;
|
BIN
opk/jiljil.png
Normal file
BIN
opk/jiljil.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 766 B |
|
@ -4,8 +4,11 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
#include <SDL/SDL_image.h>
|
#include <SDL/SDL_image.h>
|
||||||
#include "SDL/SDL_mixer.h"
|
#include "SDL/SDL_mixer.h"
|
||||||
#include "SDL/SDL_sound.h"
|
#include "SDL/SDL_sound.h"
|
||||||
|
|
46
src/logic.c
46
src/logic.c
|
@ -1,15 +1,40 @@
|
||||||
#include "include.h"
|
#include "include.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void get_best_score_path(char* reference) {
|
||||||
|
sprintf(reference, "%s/.jiljil/best_score", getenv("HOME"));
|
||||||
|
}
|
||||||
|
|
||||||
// get_best_score_from_file loads the best saved score from best_score.txt and puts it to best_score
|
// 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) {
|
int get_best_score_from_file(void) {
|
||||||
|
|
||||||
if(access("./best_score.txt", F_OK) != 0) {
|
char best_score_path[64];
|
||||||
|
get_best_score_path(best_score_path);
|
||||||
|
|
||||||
|
if(access(best_score_path, F_OK) != 0) {
|
||||||
|
printf("Couldn't read best score file at %s. This is normal if it's your first play.\n", best_score_path);
|
||||||
|
errno = 0;
|
||||||
|
char dirtomake[64];
|
||||||
|
sprintf(dirtomake, "%s/.jiljil/", getenv("HOME"));
|
||||||
|
if(mkdir(dirtomake, S_IRWXU) == -1) {
|
||||||
|
switch (errno) {
|
||||||
|
case EACCES :
|
||||||
|
printf("The home directory does not to allow write the .jiljil directory\n");
|
||||||
|
case EEXIST:
|
||||||
|
printf("Pathname already exists\n");
|
||||||
|
case ENAMETOOLONG:
|
||||||
|
printf("Pathname is too long\n");
|
||||||
|
default:
|
||||||
|
perror("Error creating directory");
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char buff[10];
|
char buff[10];
|
||||||
fp = fopen("./best_score.txt", "r");
|
fp = fopen(best_score_path, "r");
|
||||||
fscanf(fp, "%s", buff);
|
fscanf(fp, "%s", buff);
|
||||||
int bs;
|
int bs;
|
||||||
sscanf(buff, "%d", &bs);
|
sscanf(buff, "%d", &bs);
|
||||||
|
@ -17,11 +42,21 @@ int get_best_score_from_file(void) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// save_best_score_to_file puts the best score (from global var best_score) to best_score.txt
|
// save_best_score_to_file puts the best score to best_score.txt
|
||||||
void save_best_score_to_file(int score) {
|
void save_best_score_to_file(int score) {
|
||||||
|
|
||||||
|
char best_score_path[64];
|
||||||
|
get_best_score_path(best_score_path);
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
int best_score = score;
|
int best_score = score;
|
||||||
FILE *fp = fopen("./best_score.txt", "w");
|
fp = fopen(best_score_path, "w");
|
||||||
|
|
||||||
|
if(fp == NULL) {
|
||||||
|
perror("Best score has NOT ben saved! Error opening file to save score");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
char snum[5];
|
char snum[5];
|
||||||
sprintf(snum, "%d", best_score);
|
sprintf(snum, "%d", best_score);
|
||||||
fputs(snum, fp);
|
fputs(snum, fp);
|
||||||
|
@ -83,6 +118,7 @@ void lemon_cap(float *speed_x, float *speed_y) {
|
||||||
entity_cap(speed_x, speed_y);
|
entity_cap(speed_x, speed_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// avoid player flickering because the speed is close to zero, but enough to make it move slightly
|
||||||
void player_approximate(float *player_speed_x, float *player_speed_y) {
|
void player_approximate(float *player_speed_x, float *player_speed_y) {
|
||||||
if(*player_speed_x > -0.1 && *player_speed_x < 0.1) {
|
if(*player_speed_x > -0.1 && *player_speed_x < 0.1) {
|
||||||
*player_speed_x = 0;
|
*player_speed_x = 0;
|
||||||
|
@ -132,4 +168,4 @@ int check_player_inside_prints(int tail_x, int tail_y, int paw1_x, int paw1_y, i
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
14
src/match.c
14
src/match.c
|
@ -33,7 +33,6 @@ int pause_game(SDL_Surface *screen) {
|
||||||
case SDLK_BACKSPACE: //R -> reset
|
case SDLK_BACKSPACE: //R -> reset
|
||||||
resume_bgm();
|
resume_bgm();
|
||||||
return 2;
|
return 2;
|
||||||
break;
|
|
||||||
case SDLK_LSHIFT: //Y -> clear best score
|
case SDLK_LSHIFT: //Y -> clear best score
|
||||||
save_best_score_to_file(0);
|
save_best_score_to_file(0);
|
||||||
resume_bgm();
|
resume_bgm();
|
||||||
|
@ -247,8 +246,13 @@ int match(SDL_Surface *screen) {
|
||||||
|
|
||||||
Uint32 end = SDL_GetTicks();
|
Uint32 end = SDL_GetTicks();
|
||||||
float elapsedMS = end - start;
|
float elapsedMS = end - start;
|
||||||
|
float sleepFor = floor(16.666f - elapsedMS);
|
||||||
|
|
||||||
SDL_Delay(floor(16.666f - elapsedMS));
|
if(sleepFor < 0) {
|
||||||
|
sleepFor = 0; // just to be safe
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Delay(sleepFor);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +278,9 @@ int match(SDL_Surface *screen) {
|
||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
switch (event.key.keysym.sym) {
|
switch (event.key.keysym.sym) {
|
||||||
case SDLK_ESCAPE: //select -> pause menu
|
case SDLK_ESCAPE: //select -> pause menu
|
||||||
pause_game(screen);
|
if(pause_game(screen) == 1){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
case SDLK_RETURN: //start -> new game
|
case SDLK_RETURN: //start -> new game
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
|
@ -348,4 +354,4 @@ int boot_animation(SDL_Surface *screen) {
|
||||||
SDL_Delay(100);
|
SDL_Delay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue