platform-game/Forráskód/modules/saves.c
Andras Schmelczer c9b542eccf
All checks were successful
Build & deploy web version / Build WebAssembly & deploy (push) Successful in 1m8s
Migrate to SDL2 and deploy as WASM
2026-08-09 20:00:56 +01:00

154 lines
5.4 KiB
C

#include "saves.h"
///Megnézi, melyik save slotok foglaltak, ha nem NULL pointert kap, megnézni melyik mentés milyen régi, és hány pontja van benne a játékosnak.
void getExistingSaveFiles(time_t ages[], int points[]) {
int saveID = 0;
char save[50];
FILE* saveFile;
while(saveID < maxNOSaves) {
sprintf(save, "saves/game%d.save", saveID);
saveFile = fopen(save, "r");
if(saveFile != NULL) {
existingSaves[saveID] = true;
if(saveFile != NULL) {
if(ages != NULL) {
long long savedTime = 0;
fscanf(saveFile, "%lld,", &savedTime);
ages[saveID] = (time_t) savedTime;
int i;
for(i = 0; i < 8; i++)
fscanf(saveFile, "%d,", &(points[saveID]));
}
fclose(saveFile);
}
}
else existingSaves[saveID] = false;
saveID++;
};
}
///Mentés törlése (fizikálisan).
void deleteSave(int i) {
char save[50];
sprintf(save, "saves/game%d.save", i);
remove(save);
}
/** \brief Elmenti a jelenlegi játékállást (kivéve a floatereket, de ez nem hiányosság, hanem a játék filozófiájának része).
* A procedúra gyorsítása végett buffert és tömörítést használ. A mentés fájl első pár eleme a beállításokat, és a játékos adatait tartalmazza.
* A mentés időpontja is a fájlban tárolódik. A tömörítés ezután következik: A számok (amik az block enumból jönnek) előtt zárójelben ott van, hogy
* az vízszintesen egymásután hányszor fordul elő. Tehát a (102)1, azt jelenti, hogy egymás után 102 db egyes van. Ez igen jelentősen csökkenti a
* mentések méretét. Gyorsabb lenne, ha nem karakterek formájában menne a fájlba írás, de így is elég gyors, szóval egyelőre jó lesz.
* \param beállítások
* A mentés fájl tartalmazza a pálya dimenzióit, "sortörések" nincsenek a fájlban, ha nem megfelelő formátumú fájlt próbálunk betölteni jó esetben
* szétcsúszik a pálya, roszabban pedig túlírunk a memóriában. Szóval a felhasználó ne nagyon szerkesztgesse a mentéseket.
*/
void saveGame(int currentOptions[]) {
char saveName[50];
getExistingSaveFiles(NULL, NULL);
int i;
for(i = 0; i < maxNOSaves - 1 && existingSaves[i]; i++)
;
sprintf(saveName, "saves/game%d.save", i);
FILE* save = fopen(saveName, "w");
block** map = getMap();
fprintf(save, "%lld,", (long long) time(NULL));
for(i = 0; i < 5; i++)
fprintf(save, "%d,", currentOptions[i]);
renderObject player = getPlayerRenderObject();
fprintf(save, "%d,%d,%d,", (int)(player.position.x * 10), (int)(player.position.y * 10), getPoints());
char* buffer = (char*) malloc(bufferSize);
int bufferIndex = 0;
char temp[20];
int x, y;
int repCount;
for(y = currentOptions[1] - 1; y >= 0; y--) {
for(x = 0; x < currentOptions[0]; x++) {
for(repCount = 1; x + repCount < currentOptions[0] && map[x][y] == map[x + repCount][y]; repCount++)
;
if(repCount > 4) {
x += repCount - 1;
sprintf(temp, "(%d)%d,", repCount, map[x][y]);
strcpy(buffer + bufferIndex, temp);
bufferIndex += strlen(temp);
}
else {
sprintf(temp, "%d,", map[x][y]);
strcpy(buffer + bufferIndex, temp);
bufferIndex += strlen(temp);
}
if(bufferIndex > bufferSize - 20) {
fprintf(save, "%s", buffer);
bufferIndex = 0;
}
}
}
if(bufferIndex != 0)
fprintf(save, "%s", buffer);
free(buffer);
fclose(save);
}
///Fájlból betölti a játékot, a világot is előkészíti. A mentésnél használt tömörítést dekódolja. A betöltött játék beállítások felülírják az eddigieket.
void loadGame(int currentOptions[], int saveID) {
char saveName[50];
sprintf(saveName, "saves/game%d.save", saveID);
FILE* save = fopen(saveName, "r");
long long tmpT;
fscanf(save, "%lld,", &tmpT);
int i;
for(i = 0; i < 5; i++)
fscanf(save, "%d,", &(currentOptions[i]));
int playerX, playerY;
int points;
fscanf(save, "%d,%d,%d,", &playerX, &playerY, &points);
setPlayerStartingPosition(playerX / 10.0, playerY / 10.0);
setPoints(points);
setMapSize(currentOptions[0], currentOptions[1]);
generateColorMap();
g = currentOptions[3] / 10e6;
vector2D maxVelocity;
getPlayerStats(&maxVelocity);
createMap();
block** map = getMap();
int x, y, repCount;
int blockToWrite;
for(y = currentOptions[1] - 1; y >= 0; y--) {
for(x = 0; x < currentOptions[0]; x++) {
if(fscanf(save, "(%d)%d,", &repCount, &blockToWrite) > 0) {
for(i = 0; i < repCount; i++)
map[x + i][y] = blockToWrite;
x += repCount - 1;
}
else {
fscanf(save, "%d,", &blockToWrite);
map[x][y] = blockToWrite;
}
}
}
setParticleMultiplier(currentOptions[2], false);
createParticleList();
freeFloaterList();
fclose(save);
}