1
0
mirror of https://github.com/blupi-games/planetblupi synced 2024-12-30 10:15:36 +01:00
planetblupi/src/decio.cpp

490 lines
10 KiB
C++
Raw Normal View History

2017-01-21 17:27:46 +01:00
// DecIO.cpp
//
2017-02-11 21:43:47 +01:00
#include "def.h"
#include "decor.h"
#include "misc.h"
2017-01-21 17:27:46 +01:00
typedef struct
{
Sint16 majRev;
Sint16 minRev;
Sint32 nbDecor;
Sint32 lgDecor;
Sint32 nbBlupi;
Sint32 lgBlupi;
Sint32 nbMove;
Sint32 lgMove;
Sint16 reserve1[100];
2017-01-21 17:27:46 +01:00
POINT celCoin;
Sint16 world;
Sint32 time;
2017-01-21 17:27:46 +01:00
char buttonExist[MAXBUTTON];
Term term;
Sint16 music;
Sint16 region;
Sint32 totalTime;
Sint16 skill;
2017-01-21 17:27:46 +01:00
POINT memoPos[4];
Sint16 reserve2[29];
2017-01-21 17:27:46 +01:00
}
DescFile;
typedef struct
{
Sint32 bExist; // true -> utilisé
Sint32 bHili; // true -> sélectionné
2017-01-21 17:27:46 +01:00
Sint16 perso; // personnage, voir (*)
2017-01-21 17:27:46 +01:00
Sint16 goalAction; // action (Sint32 terme)
Sint16 goalPhase; // phase (Sint32 terme)
POINT goalCel; // cellule visée (Sint32 terme)
2017-01-21 17:27:46 +01:00
POINT passCel; // cellule tranversante
Sint16 energy; // énergie restante
2017-01-21 17:27:46 +01:00
POINT cel; // cellule actuelle
POINT destCel; // cellule destination
Sint16 action; // action en cours
Sint16 aDirect; // direction actuelle
Sint16 sDirect; // direction souhaitée
2017-01-21 17:27:46 +01:00
2017-02-12 00:44:46 +01:00
POINT pos; // position relative à partir de la cellule
Sint16 posZ; // déplacement z
Sint16 channel;
Sint16 lastIcon;
Sint16 icon;
Sint16 phase; // phase dans l'action
Sint16 step; // pas global
Sint16 interrupt; // 0=prioritaire, 1=normal, 2=misc
Sint16 clipLeft;
Sint32 nbUsed; // nb de points déjà visités
2017-01-21 17:27:46 +01:00
char nextRankUsed;
POINT posUsed[MAXUSED];
char rankUsed[MAXUSED];
Sint16 takeChannel; // objet transporté
Sint16 takeIcon;
2017-01-21 17:27:46 +01:00
POINT fix; // point fixe (cultive, pont)
Sint16 jaugePhase;
Sint16 jaugeMax;
Sint16 stop; // 1 -> devra stopper
Sint16 bArrow; // true -> flèche en dessus de blupi
Sint16 bRepeat; // true -> répète l'action
Sint16 nLoop; // nb de boucles pour GOAL_OTHERLOOP
Sint16 cLoop; // boucle en cours
Sint16 vIcon; // icône variable
2017-02-12 00:44:46 +01:00
POINT goalHili; // but visé
Sint16 bMalade; // true -> blupi malade
Sint16 bCache; // true -> caché (pas dessiné)
Sint16 vehicule; // véhicule utilisé par blupi, voir (**)
2017-01-21 17:27:46 +01:00
char busyCount;
char busyDelay;
char clicCount;
char clicDelay;
char reserve2[2];
}
OldBlupi;
2017-02-12 00:44:46 +01:00
// Sauve le décor sur disque.
2017-01-21 17:27:46 +01:00
bool CDecor::Write(Sint32 rank, bool bUser, Sint32 world, Sint32 time, Sint32 total)
2017-01-21 17:27:46 +01:00
{
char filename[MAX_PATH];
2017-02-05 17:54:12 +01:00
FILE* file = nullptr;
DescFile* pBuffer = nullptr;
Sint32 i;
size_t nb;
2017-01-21 17:27:46 +01:00
if ( bUser )
{
2017-02-11 19:31:30 +01:00
sprintf(filename, "data/user%.3d.blp", rank);
2017-01-21 17:27:46 +01:00
AddUserPath(filename);
}
else
{
2017-02-11 19:31:30 +01:00
sprintf(filename, "data/world%.3d.blp", rank);
2017-01-21 17:27:46 +01:00
}
file = fopen(filename, "wb");
2017-02-05 17:54:12 +01:00
if ( file == nullptr ) goto error;
2017-01-21 17:27:46 +01:00
pBuffer = (DescFile*)malloc(sizeof(DescFile));
2017-02-05 17:54:12 +01:00
if ( pBuffer == nullptr ) goto error;
2017-01-21 17:27:46 +01:00
memset(pBuffer, 0, sizeof(DescFile));
pBuffer->majRev = 1;
pBuffer->minRev = 5;
pBuffer->celCoin = m_celCoin;
pBuffer->world = world;
pBuffer->time = time;
pBuffer->totalTime = total;
pBuffer->term = m_term;
pBuffer->music = m_music;
pBuffer->region = m_region;
pBuffer->skill = m_skill;
pBuffer->nbDecor = MAXCELX*MAXCELY;
pBuffer->lgDecor = sizeof(Cellule);
pBuffer->nbBlupi = MAXBLUPI;
pBuffer->lgBlupi = sizeof(Blupi);
pBuffer->nbMove = MAXMOVE;
pBuffer->lgMove = sizeof(Move);
for ( i=0 ; i<MAXBUTTON ; i++ )
{
pBuffer->buttonExist[i] = m_buttonExist[i];
}
for ( i=0 ; i<4 ; i++ )
{
pBuffer->memoPos[i] = m_memoPos[i];
}
nb = fwrite(pBuffer, sizeof(DescFile), 1, file);
if ( nb < 1 ) goto error;
nb = fwrite(m_decor, sizeof(Cellule), MAXCELX*MAXCELY/4, file);
if ( nb < MAXCELX*MAXCELY/4 ) goto error;
nb = fwrite(m_blupi, sizeof(Blupi), MAXBLUPI, file);
if ( nb < MAXBLUPI ) goto error;
nb = fwrite(m_move, sizeof(Move), MAXMOVE, file);
if ( nb < MAXMOVE ) goto error;
nb = fwrite(m_lastDrapeau, sizeof(POINT), MAXLASTDRAPEAU, file);
if ( nb < MAXLASTDRAPEAU ) goto error;
free(pBuffer);
fclose(file);
return true;
2017-01-21 17:27:46 +01:00
error:
2017-02-05 17:54:12 +01:00
if ( pBuffer != nullptr ) free(pBuffer);
if ( file != nullptr ) fclose(file);
return false;
2017-01-21 17:27:46 +01:00
}
2017-02-12 00:44:46 +01:00
// Lit le décor sur disque.
2017-01-21 17:27:46 +01:00
bool CDecor::Read(Sint32 rank, bool bUser, Sint32 &world, Sint32 &time, Sint32 &total)
2017-01-21 17:27:46 +01:00
{
char filename[MAX_PATH];
2017-02-05 17:54:12 +01:00
FILE* file = nullptr;
DescFile* pBuffer = nullptr;
Sint32 majRev, minRev;
Sint32 i, x, y;
size_t nb;
2017-01-21 17:27:46 +01:00
OldBlupi oldBlupi;
Init(-1, -1);
if ( bUser )
{
2017-02-11 19:31:30 +01:00
sprintf(filename, "data/user%.3d.blp", rank);
2017-01-21 17:27:46 +01:00
AddUserPath(filename);
}
else
{
2017-02-11 22:53:03 +01:00
sprintf(filename, (GetBaseDir () + "data/world%.3d.blp").c_str (), rank);
2017-01-21 17:27:46 +01:00
}
file = fopen(filename, "rb");
2017-02-05 17:54:12 +01:00
if ( file == nullptr ) goto error;
2017-01-21 17:27:46 +01:00
pBuffer = (DescFile*)malloc(sizeof(DescFile));
2017-02-05 17:54:12 +01:00
if ( pBuffer == nullptr ) goto error;
2017-01-21 17:27:46 +01:00
nb = fread(pBuffer, sizeof(DescFile), 1, file);
if ( nb < 1 ) goto error;
majRev = pBuffer->majRev;
minRev = pBuffer->minRev;
if ( majRev == 1 && minRev == 0 ) goto error;
if ( majRev == 1 && minRev == 3 )
{
if ( pBuffer->nbDecor != MAXCELX*MAXCELY ||
pBuffer->lgDecor != sizeof(Cellule) ||
pBuffer->nbBlupi != MAXBLUPI ||
pBuffer->lgBlupi != sizeof(OldBlupi)||
pBuffer->nbMove != MAXMOVE ||
pBuffer->lgMove != sizeof(Move) ) goto error;
}
else
{
if ( pBuffer->nbDecor != MAXCELX*MAXCELY ||
pBuffer->lgDecor != sizeof(Cellule) ||
pBuffer->nbBlupi != MAXBLUPI ||
pBuffer->lgBlupi != sizeof(Blupi) ||
pBuffer->nbMove != MAXMOVE ||
pBuffer->lgMove != sizeof(Move) ) goto error;
}
SetCoin(pBuffer->celCoin);
if ( bUser )
{
world = pBuffer->world;
time = pBuffer->time;
total = pBuffer->totalTime;
}
m_celHome = pBuffer->celCoin;
m_term = pBuffer->term;
m_music = pBuffer->music;
m_region = pBuffer->region;
if ( bUser )
{
m_skill = pBuffer->skill;
}
for ( i=0 ; i<MAXBUTTON ; i++ )
{
m_buttonExist[i] = pBuffer->buttonExist[i];
}
for ( i=0 ; i<4 ; i++ )
{
m_memoPos[i] = pBuffer->memoPos[i];
}
nb = fread(m_decor, sizeof(Cellule), MAXCELX*MAXCELY/4, file);
if ( nb < MAXCELX*MAXCELY/4 ) goto error;
if ( majRev == 1 && minRev < 5 )
{
for ( x=0 ; x<MAXCELX/2 ; x++ )
{
for ( y=0 ; y<MAXCELY/2 ; y++ )
{
if ( m_decor[x][y].objectIcon >= 128 &&
m_decor[x][y].objectIcon <= 130 )
{
m_decor[x][y].objectIcon -= 128-17;
}
}
}
}
if ( majRev == 1 && minRev == 3 )
{
memset(m_blupi, 0, sizeof(Blupi)*MAXBLUPI);
for ( i=0 ; i<MAXBLUPI ; i++ )
{
nb = fread(&oldBlupi, sizeof(OldBlupi), 1, file);
if ( nb != 1 ) goto error;
memcpy(m_blupi+i, &oldBlupi, sizeof(OldBlupi));
ListFlush(i);
}
}
else
{
nb = fread(m_blupi, sizeof(Blupi), MAXBLUPI, file);
if ( nb < MAXBLUPI ) goto error;
}
nb = fread(m_move, sizeof(Move), MAXMOVE, file);
if ( nb < MAXMOVE ) goto error;
nb = fread(m_lastDrapeau, sizeof(POINT), MAXLASTDRAPEAU, file);
if ( nb < MAXLASTDRAPEAU )
{
InitDrapeau();
}
2017-02-12 00:44:46 +01:00
BlupiDeselect(); // désélectionne tous les blupi
2017-01-21 17:27:46 +01:00
free(pBuffer);
fclose(file);
return true;
2017-01-21 17:27:46 +01:00
error:
2017-02-05 17:54:12 +01:00
if ( pBuffer != nullptr ) free(pBuffer);
if ( file != nullptr ) fclose(file);
2017-01-21 17:27:46 +01:00
2017-02-12 00:44:46 +01:00
Flush(); // initialise un décor neutre
return false;
2017-01-21 17:27:46 +01:00
}
// Indique si un fichier existe sur disque.
bool CDecor::FileExist(Sint32 rank, bool bUser, Sint32 &world, Sint32 &time, Sint32 &total)
2017-01-21 17:27:46 +01:00
{
char filename[MAX_PATH];
2017-02-05 17:54:12 +01:00
FILE* file = nullptr;
DescFile* pBuffer = nullptr;
Sint32 majRev, minRev;
size_t nb;
2017-01-21 17:27:46 +01:00
if ( bUser )
{
2017-02-11 19:31:30 +01:00
sprintf(filename, "data/user%.3d.blp", rank);
2017-01-21 17:27:46 +01:00
AddUserPath(filename);
}
else
{
2017-02-11 19:31:30 +01:00
sprintf(filename, "data/world%.3d.blp", rank);
2017-01-21 17:27:46 +01:00
}
file = fopen(filename, "rb");
2017-02-05 17:54:12 +01:00
if ( file == nullptr ) goto error;
2017-01-21 17:27:46 +01:00
pBuffer = (DescFile*)malloc(sizeof(DescFile));
2017-02-05 17:54:12 +01:00
if ( pBuffer == nullptr ) goto error;
2017-01-21 17:27:46 +01:00
nb = fread(pBuffer, sizeof(DescFile), 1, file);
if ( nb < 1 ) goto error;
majRev = pBuffer->majRev;
minRev = pBuffer->minRev;
if ( majRev == 1 && minRev == 0 ) goto error;
if ( majRev == 1 && minRev == 3 )
{
if ( pBuffer->nbDecor != MAXCELX*MAXCELY ||
pBuffer->lgDecor != sizeof(Cellule) ||
pBuffer->nbBlupi != MAXBLUPI ||
pBuffer->lgBlupi != sizeof(OldBlupi)||
pBuffer->nbMove != MAXMOVE ||
pBuffer->lgMove != sizeof(Move) ) goto error;
}
else
{
if ( pBuffer->nbDecor != MAXCELX*MAXCELY ||
pBuffer->lgDecor != sizeof(Cellule) ||
pBuffer->nbBlupi != MAXBLUPI ||
pBuffer->lgBlupi != sizeof(Blupi) ||
pBuffer->nbMove != MAXMOVE ||
pBuffer->lgMove != sizeof(Move) ) goto error;
}
world = pBuffer->world;
time = pBuffer->time;
total = pBuffer->totalTime;
free(pBuffer);
fclose(file);
return true;
2017-01-21 17:27:46 +01:00
error:
2017-02-05 17:54:12 +01:00
if ( pBuffer != nullptr ) free(pBuffer);
if ( file != nullptr ) fclose(file);
return false;
2017-01-21 17:27:46 +01:00
}
#define MARG 18
2017-02-12 00:44:46 +01:00
// Initialise un décor neutre.
2017-01-21 17:27:46 +01:00
void CDecor::Flush()
{
Sint32 x, y, i, icon;
2017-01-21 17:27:46 +01:00
Init(-1, -1);
for ( x=0 ; x<MAXCELX ; x+=2 )
{
for ( y=0 ; y<MAXCELY ; y+=2 )
{
if ( x < MARG || x > MAXCELX-MARG ||
y < MARG || y > MAXCELY-MARG )
{
icon = 14; // eau
goto put;
}
if ( x == MARG && y == MARG )
{
icon = 12;
goto put;
}
if ( x == MAXCELX-MARG && y == MARG )
{
icon = 13;
goto put;
}
if ( x == MARG && y == MAXCELY-MARG )
{
icon = 11;
goto put;
}
if ( x == MAXCELX-MARG && y == MAXCELY-MARG )
{
icon = 10;
goto put;
}
if ( x == MARG )
{
icon = 4;
goto put;
}
if ( x == MAXCELX-MARG )
{
icon = 2;
goto put;
}
if ( y == MARG )
{
icon = 5;
goto put;
}
if ( y == MAXCELY-MARG )
{
icon = 3;
goto put;
}
icon = 1; // terre
put:
m_decor[x/2][y/2].floorChannel = CHFLOOR;
m_decor[x/2][y/2].floorIcon = icon;
}
}
for ( i=0 ; i<MAXBLUPI ; i++ )
{
m_blupi[i].bExist = false;
2017-01-21 17:27:46 +01:00
}
BlupiCreate(GetCel(102,100), ACTION_STOP, DIRECT_S, 0, MAXENERGY);
m_decor[98/2][100/2].floorChannel = CHFLOOR;
m_decor[98/2][100/2].floorIcon = 16;
m_decor[98/2][100/2].objectChannel = CHOBJECT;
m_decor[98/2][100/2].objectIcon = 113;
for ( i=0 ; i<MAXBUTTON ; i++ )
{
m_buttonExist[i] = 1;
}
for ( i=0 ; i<4 ; i++ )
{
m_memoPos[i].x = 0;
m_memoPos[i].y = 0;
}
memset(&m_term, 0, sizeof(Term));
m_term.bHomeBlupi = true;
2017-01-21 17:27:46 +01:00
m_term.nbMinBlupi = 1;
m_term.nbMaxBlupi = 1;
m_music = 0;
m_region = 0;
m_celHome.x = 90;
m_celHome.y = 98;
SetCoin(m_celHome);
InitAfterBuild();
LoadImages();
}