// DecIO.cpp // #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, "data/world%.3d.blp", 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 ; ibuttonExist[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 ; ibuttonExist[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= 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 ; imajRev; 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-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