mirror of
https://github.com/blupi-games/planetblupi
synced 2024-12-30 10:15:36 +01:00
497 lines
13 KiB
C++
497 lines
13 KiB
C++
|
|
#include "def.h"
|
|
#include "decor.h"
|
|
#include "misc.h"
|
|
|
|
typedef struct
|
|
{
|
|
Sint16 majRev;
|
|
Sint16 minRev;
|
|
Sint32 nbDecor;
|
|
Sint32 lgDecor;
|
|
Sint32 nbBlupi;
|
|
Sint32 lgBlupi;
|
|
Sint32 nbMove;
|
|
Sint32 lgMove;
|
|
Sint16 reserve1[100];
|
|
POINT celCoin;
|
|
Sint16 world;
|
|
Sint32 time;
|
|
char buttonExist[MAXBUTTON];
|
|
Term term;
|
|
Sint16 music;
|
|
Sint16 region;
|
|
Sint32 totalTime;
|
|
Sint16 skill;
|
|
POINT memoPos[4];
|
|
Sint16 reserve2[29];
|
|
}
|
|
DescFile;
|
|
|
|
typedef struct
|
|
{
|
|
Sint32 bExist; // true -> utilisé
|
|
Sint32 bHili; // true -> sélectionné
|
|
|
|
Sint16 perso; // personnage, voir (*)
|
|
|
|
Sint16 goalAction; // action (Sint32 terme)
|
|
Sint16 goalPhase; // phase (Sint32 terme)
|
|
POINT goalCel; // cellule visée (Sint32 terme)
|
|
POINT passCel; // cellule tranversante
|
|
|
|
Sint16 energy; // énergie restante
|
|
|
|
POINT cel; // cellule actuelle
|
|
POINT destCel; // cellule destination
|
|
Sint16 action; // action en cours
|
|
Sint16 aDirect; // direction actuelle
|
|
Sint16 sDirect; // direction souhaitée
|
|
|
|
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
|
|
char nextRankUsed;
|
|
POINT posUsed[MAXUSED];
|
|
char rankUsed[MAXUSED];
|
|
|
|
Sint16 takeChannel; // objet transporté
|
|
Sint16 takeIcon;
|
|
|
|
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
|
|
POINT goalHili; // but visé
|
|
Sint16 bMalade; // true -> blupi malade
|
|
Sint16 bCache; // true -> caché (pas dessiné)
|
|
Sint16 vehicule; // véhicule utilisé par blupi, voir (**)
|
|
char busyCount;
|
|
char busyDelay;
|
|
char clicCount;
|
|
char clicDelay;
|
|
char reserve2[2];
|
|
}
|
|
OldBlupi;
|
|
|
|
|
|
// Sauve le décor sur disque.
|
|
|
|
bool CDecor::Write (Sint32 rank, bool bUser, Sint32 world, Sint32 time,
|
|
Sint32 total)
|
|
{
|
|
char filename[MAX_PATH];
|
|
FILE *file = nullptr;
|
|
DescFile *pBuffer = nullptr;
|
|
Sint32 i;
|
|
size_t nb;
|
|
|
|
if (bUser)
|
|
{
|
|
sprintf (filename, "data/user%.3d.blp", rank);
|
|
AddUserPath (filename);
|
|
}
|
|
else
|
|
sprintf (filename, (GetBaseDir () + "data/world%.3d.blp").c_str (), rank);
|
|
|
|
file = fopen (filename, "wb");
|
|
if (file == nullptr)
|
|
goto error;
|
|
|
|
pBuffer = (DescFile *)malloc (sizeof (DescFile));
|
|
if (pBuffer == nullptr)
|
|
goto error;
|
|
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;
|
|
|
|
error:
|
|
if (pBuffer != nullptr)
|
|
free (pBuffer);
|
|
if (file != nullptr)
|
|
fclose (file);
|
|
return false;
|
|
}
|
|
|
|
// Lit le décor sur disque.
|
|
|
|
bool CDecor::Read (Sint32 rank, bool bUser, Sint32 &world, Sint32 &time,
|
|
Sint32 &total)
|
|
{
|
|
char filename[MAX_PATH];
|
|
FILE *file = nullptr;
|
|
DescFile *pBuffer = nullptr;
|
|
Sint32 majRev, minRev;
|
|
Sint32 i, x, y;
|
|
size_t nb;
|
|
OldBlupi oldBlupi;
|
|
|
|
Init (-1, -1);
|
|
|
|
if (bUser)
|
|
{
|
|
sprintf (filename, "data/user%.3d.blp", rank);
|
|
AddUserPath (filename);
|
|
}
|
|
else
|
|
sprintf (filename, (GetBaseDir() + "data/world%.3d.blp").c_str(), rank);
|
|
|
|
file = fopen (filename, "rb");
|
|
if (file == nullptr)
|
|
goto error;
|
|
|
|
pBuffer = (DescFile *)malloc (sizeof (DescFile));
|
|
if (pBuffer == nullptr)
|
|
goto error;
|
|
|
|
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();
|
|
|
|
BlupiDeselect(); // désélectionne tous les blupi
|
|
|
|
free (pBuffer);
|
|
fclose (file);
|
|
return true;
|
|
|
|
error:
|
|
if (pBuffer != nullptr)
|
|
free (pBuffer);
|
|
if (file != nullptr)
|
|
fclose (file);
|
|
|
|
Flush(); // initialise un décor neutre
|
|
return false;
|
|
}
|
|
|
|
// Indique si un fichier existe sur disque.
|
|
|
|
bool CDecor::FileExist (Sint32 rank, bool bUser, Sint32 &world, Sint32 &time,
|
|
Sint32 &total)
|
|
{
|
|
char filename[MAX_PATH];
|
|
FILE *file = nullptr;
|
|
DescFile *pBuffer = nullptr;
|
|
Sint32 majRev, minRev;
|
|
size_t nb;
|
|
|
|
if (bUser)
|
|
{
|
|
sprintf (filename, "data/user%.3d.blp", rank);
|
|
AddUserPath (filename);
|
|
}
|
|
else
|
|
snprintf (filename, sizeof (filename),
|
|
(GetBaseDir () + "data/world%.3d.blp").c_str (), rank);
|
|
|
|
file = fopen (filename, "rb");
|
|
if (file == nullptr)
|
|
goto error;
|
|
|
|
pBuffer = (DescFile *)malloc (sizeof (DescFile));
|
|
if (pBuffer == nullptr)
|
|
goto error;
|
|
|
|
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;
|
|
|
|
error:
|
|
if (pBuffer != nullptr)
|
|
free (pBuffer);
|
|
if (file != nullptr)
|
|
fclose (file);
|
|
return false;
|
|
}
|
|
|
|
|
|
#define MARG 18
|
|
|
|
// Initialise un décor neutre.
|
|
|
|
void CDecor::Flush()
|
|
{
|
|
Sint32 x, y, i, icon;
|
|
|
|
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;
|
|
|
|
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;
|
|
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();
|
|
}
|
|
|