Various improvements

- Better score saving with error handling
- Added OPK support (yay!)
- Improved README
This commit is contained in:
MassiveBox 2022-08-30 12:13:26 +02:00
parent db5163c945
commit a3f0d66c2b
9 changed files with 87 additions and 21 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
build.ipk
build.opk
jiljil.dge
*.o

View file

@ -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

View file

@ -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
View file

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View file

@ -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"

View file

@ -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;
} }

View file

@ -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);
} }
} }