/* Nived: l'éditeur de niveaux de BomberInstinct */ /* Nived: The editor of nives for BomberInstinct */ /* Note: */ /* Meaning of various comments */ //x means, it can be remowed in future //xx means, it shell be removed now //? I don't know, if it might be needed in the future //T a temporary change //L Language notes // !! needs repair // ?? i don't uderstand #include #include #include #include #include /* P.K. */ #include "types.h" #include "common.h" #include "macros.h" /* P.K. */ //? #include "main.h" // will be instead of fakes.h #include "fakes.h" #include "niveaux.h" // P.K. #include "sprites.h" /* P.K. Various languages localization */ #include #include /* P.K. number of objects in the menu */ #define N_CHOIX 8 // P.K. For the menu on the right site /* The legend and all the *.niv files should be in english */ const char legende[]="DESCRIPTION :\n" "_ space\n" "+[index] wall\n" "§[index] hidden passage\n" "# bloc\n" "T[case] teleportation[case between 0 and 240]\n" "O[case] button[idem]\n" "0[case] hidden button[idem]\n" ">[sens] one way[0:up, 1:down, 2:left, 3:right]\n" "=[direction] tunnel[0:, 1:<^>, 2:^v>, 3:<^v, 4:<^, 5:^>, 6:, 8:^v, 9:<>, 10:<^v>]\n" "* fontaine(regeneration)\n"; //?[sens] one way[0:haut, 1:bas, 2:gauche, 3:droite] int NB_PERSO, VITESSE, REGEN, LFLAMMES, NBOMBES, REBOURS; //, BONUSFREQ; P.K. extern float bonus_freq; // P.K. enable even float numbers (in common.h) int pleinecran; // 0 .. window, 1 .. full screen int danslemenu=0; // in the menu ?? Uint32 flags; // SDL flags //x char repertoire[256]; moved to main() char prefixeniv[MAX_STRING_LENGTH], prefixespr[MAX_STRING_LENGTH]; // part of tha paths char niv[MAX_STRING_LENGTH]; // name of the *.niv file //x Case pl[NIVEWIDTH+2][NIVEHEIGHT]; Plan plan; // game plan - dynamic //x Coord persopos[8]; Coord actif; // choosen element Sprite *nived; // sprite containing nived symbols //x Sprite *elemliste[50]; // moved to initliste() //x Sprite *nb[8]; Sprite *nb[MAX_NPERSO]; // players (= citrouilles) char graphtype[MAX_STRING_LENGTH]; // grotte file = motif file int decl; // ?? for color palette ?? SDL_Rect tout, plateau, recdroite; // ?? SDL_Surface *ecran; // ?? Uint8 *clavier; // keyboard //x int compteur; // moved to common.c int encore; // boolean //x Case elemactif; PlateauElement elemactif; // actvive elements //x int *paramsbuf, nparamsbuf; // P.K. Parameter *paramsbuf = NULL; // for yanking parametres (during future calls) int nparamsbuf = 0; // number of yanking parametres //x int dx[4]={ 0, 0,-1, 1}; // four directions - moved to comon.c //x int dy[4]={-1, 1, 0, 0}; int aleat(int max); //x void erreur(char message[200], char param[20]); //x void animsplus(Sprite *sprite, int anim, int vitesse, int duree, int x, int y); //? void rscaseplus(int x, int y); //x void rdplateau(void); void initliste(void); /* Resolution variables */ Resolution resolution; /* void erreur_(char message[200], char param[20]) */ /* { */ /* //x printf ("\nErreur :\n%s", message); */ /* printf (gettext("\nErreur :\n%s"), message); */ /* if (param) printf(" : %s", param); */ /* printf (".\n%s\n", SDL_GetError()); */ /* exit(0); */ /* } */ /*--Initialiser l'écran--*/ int init_sdl_nived(void) { Uint32 params; int ok; char titre[MAX_STRING_LENGTH]; flags=SDL_HWSURFACE|SDL_HWPALETTE; params = pleinecran ? flags|SDL_FULLSCREEN : flags; if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { //x erreur("Impossible d'initialiser SDL", NULL); errormessage(gettext("Impossible d'initialiser SDL"), NULL); //L erreur("Unable to initialize SDL!", NULL); } //x sprintf(titre, "Nived - l'éditeur de niveaux de BomberInstinct - %s - v1.0", niv); sprintf(titre, gettext("Nived - l'éditeur de niveaux de BomberInstinct - %s - v1.0"), niv); SDL_WM_SetCaption(titre, "Nived"); //x ok=SDL_VideoModeOK(640, 480, 8, params); ok=SDL_VideoModeOK(resolution.window_width, resolution.window_height, 8, params); if (ok==0) //x erreur("Le mode vidéo requis n'est pas disponible (640x480)", NULL); errormessage(gettext("Le mode vidéo requis n'est pas disponible (640x480)"), NULL); //x ecran = SDL_SetVideoMode(640, 480, 8, params); ecran = SDL_SetVideoMode(resolution.window_width, resolution.window_height, 8, params); if ( ecran == NULL ) { //x erreur("Impossible d'initialiser l'écran en mode 640*480 8 bits", NULL); errormessage(gettext("Impossible d'initialiser l'écran en mode 640*480 8 bits"), NULL); return 1; } atexit(SDL_Quit); SDL_EnableKeyRepeat(0,0); SDL_ShowCursor(1); return 0; } /* integer random number */ int aleat(int max) { int num; num=(int)(max * ((float)rand()) / ((float)RAND_MAX) ); return num; } void passenpleinecran() { int i, ncoul; SDL_Surface *sauvegarde; SDL_Color *pal; ncoul=ecran->format->palette->ncolors; pal=(SDL_Color *)calloc(ncoul, sizeof(SDL_Color)); for (i=0; iformat->palette->colors[i].r; pal[i].g=ecran->format->palette->colors[i].g; pal[i].b=ecran->format->palette->colors[i].b; } sauvegarde=SDL_DisplayFormat(ecran); SDL_FreeSurface(ecran); if ((ecran->flags & SDL_FULLSCREEN)==SDL_FULLSCREEN) { //x ecran = SDL_SetVideoMode(640, 480, 8, SDL_HWSURFACE|SDL_HWPALETTE); ecran = SDL_SetVideoMode(resolution.window_width, resolution.window_height, 8, SDL_HWSURFACE|SDL_HWPALETTE); } else { //x ecran = SDL_SetVideoMode(640, 480, 8, SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN); ecran = SDL_SetVideoMode(resolution.window_width, resolution.window_height, 8, SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN); } SDL_SetColors(ecran, pal, 0, ncoul); free(pal); SDL_BlitSurface(sauvegarde, NULL, ecran, NULL); SDL_Flip(ecran); SDL_FreeSurface(sauvegarde); return; } int filtr_evt(const SDL_Event *evt) { if (evt->type == SDL_QUIT) exit(0); if (evt->type == SDL_KEYDOWN) { if (evt->key.keysym.sym==SDLK_c) if (evt->key.keysym.mod==KMOD_LCTRL) exit(0); if (evt->key.keysym.sym==SDLK_F10) exit(0); if (evt->key.keysym.sym==SDLK_F1) passenpleinecran(); } return 1; } void videcran(void) { SDL_FillRect(ecran, &tout, 0); SDL_Flip(ecran); return; } /*--Redessine une case (x, y) du plateau--*/ void dessinecase_nived(int x, int y) { int xx=x*32; if (x>(plan.nivewidth-1)) xx+=32; // ?? not necesary ?? if (plan.element[x][y].sol) // space as background blitsprit(sol, 0, 0, xx, y*32); blitsprit(plan.element[x][y].elem, plan.element[x][y].anim, plan.element[x][y].frame, xx, y*32); if (plan.element[x][y].type == SECRETPASSAGE) // secret passage P.K. blitsprit(nived, 0, 4, xx, y*32); // door if (plan.element[x][y].fixe == 1) // one fixed kind of sprite blitsprit(nived, 0, 0, xx, y*32); // anchor = symbol for fixed sprites return; } void rdicones(void) { int x, y; /* here should be the "choix field" used */ //x for (y=0; y < niveheight; y++) x = plan.nivewidth; for (y = 0; y < N_CHOIX; y++) { //x for (x=nivewidth; x < (nivewidth+2); x++) { dessinecase_nived(x, y); } blitsprit(nb[0], 1, 0, (plan.nivewidth+1)*32, (plan.niveheight-1)*32); // citrouille blitsprit(nived, 0, 3, (plan.nivewidth+2)*32, (plan.niveheight-1)*32); // next motif return; } void rdplateau_nived(void) { int x, y; for (y = 0; y < plan.niveheight; y++) for (x = 0; x < plan.nivewidth; x++) { dessinecase_nived(x, y); } rdicones(); return; } void chargeniv_(FILE *fich, int tete) { int x, y, i; char niv, c; if (tete) // whether to read parametres from the fich file { fscanf(fich, "REGEN=%i\n", ®EN); // testing for errors missing! P.K. //x fscanf(fich, "BONUSFREQ=%i\n", &BONUSFREQ); P.K. fscanf(fich, "BONUSFREQ=%g\n", &bonus_freq); fscanf(fich, "NBOMBES=%i\n", &NBOMBES); fscanf(fich, "REBOURS=%i\n", &REBOURS); for (i=0; i0.9*RAND_MAX) if (rand() > SPACE_VARIATIONS*RAND_MAX) // sometimes some variations from anim[1] plan.element[x][y].anim = 1; plan.element[x][y].frame = aleat(sol->anims[plan.element[x][y].anim]->nframes); } else { plan.element[x][y].anim=2; plan.element[x][y].frame=params[0]; plan.element[x][y].fixe=1; } }break; case '#' : // block { plan.element[x][y].elem=bloc; plan.element[x][y].type=DESTRUCTIBLE; plan.element[x][y].anim=0; plan.element[x][y].sol=1; if (!nparams) plan.element[x][y].frame=aleat( bloc->anims[0]->nframes); else { plan.element[x][y].frame=params[0]; plan.element[x][y].fixe=1;} }break; case '+' : // wall { plan.element[x][y].elem=mur; plan.element[x][y].type=INDESTRUCTIBLE; if (!nparams) plan.element[x][y].frame=aleat( mur->anims[0]->nframes); else { plan.element[x][y].frame=params[0]; plan.element[x][y].fixe=1;} }break; // insert the secret passages P.K. case '§' : // hidden pasage { plan.element[x][y].elem=mur; //like an ordinary wall P.K. plan.element[x][y].type=SECRETPASSAGE; // P.K. if (!nparams) plan.element[x][y].frame=aleat( mur->anims[0]->nframes); else { plan.element[x][y].frame=params[0]; plan.element[x][y].fixe=1;} }break; case '=' : // tunnel { plan.element[x][y].elem=tunnel; plan.element[x][y].type=TUNNEL; plan.element[x][y].frame=params[0]; plan.element[x][y].fixe=-1; }break; case '>' : // one-way { plan.element[x][y].type=SENSUNIQUE; plan.element[x][y].elem=fleche; plan.element[x][y].anim=params[0]; plan.element[x][y].sol=1; plan.element[x][y].fixe=-1; }break; case 'T' : // teleport { plan.element[x][y].type=EVENEMENT; plan.element[x][y].sol=1; plan.element[x][y].elem=teleport; plan.element[x][y].fixe=-1; }break; case 'O' : // button { plan.element[x][y].elem=bouton; plan.element[x][y].sol=1; plan.element[x][y].type=EVENEMENT; plan.element[x][y].fixe=-1; // visible }break; case '0' : // invisible button P.K. { plan.element[x][y].elem=bouton; // at first like an ordinary button - to be repaired! P.K. plan.element[x][y].sol=1; //? plan.element[x][y].type=EVENEMENT; plan.element[x][y].fixe=-2; // invisible plan.element[x][y].frame=bouton->anims[0]->nframes-1; }break; case '*' : // fontaine { plan.element[x][y].type=EVENEMENT; plan.element[x][y].sol=1; plan.element[x][y].elem=fontaine; plan.element[x][y].fixe=-1; }break; default : { //x erreur("Ce niveau contient des éléments spéciaux. " //x "Vous ne pouvez pas l'éditer avec nived", NULL); errormessage(gettext("Ce niveau contient des éléments spéciaux. " "Vous ne pouvez pas l'éditer avec nived"), NULL); //L erreur(gettext("Nive contents an invalid element spedification. " //L "The editor nived is unable to handle this file."), NULL); }break; } } do // read till the end of the nive array fread(&niv, 1, 1, fich); while (niv!='}'); return; } void sauveniv(char *nom) { int x, y, i; int ncar; FILE *fich; char *extension = ".spr"; // P.K. //x printf("Sauvegarde du niveau dans: %s...", nom); printf(gettext("Sauvegarde du niveau dans: %s..."), nom); //L printf("Saving the nive: %s...", nom); fich = fopen(nom, "wb"); if (fich == NULL) { //x erreur("Impossible d'ouvrir le fichier en écriture", nom); errormessage(gettext("Impossible d'ouvrir le fichier en écriture"), nom); //L erreur("Unable to open output file", nom); } fprintf(fich, "sol: %s%s\n", sol->nom, extension); fprintf(fich, "bloc: %s%s\n", bloc->nom); fprintf(fich, "mur: %s%s\n", mur->nom); fprintf(fich, "fleche: %s%s\n", fleche->nom); fprintf(fich, "teleport: %s%s\n", teleport->nom); fprintf(fich, "tunnel: %s%s\n", tunnel->nom); fprintf(fich, "bouton: %s%s\n", bouton->nom); fprintf(fich, "fontaine: %s%s\n", fontaine->nom); fputc('\n', fich); fprintf(fich, "REGEN=%i\n", REGEN); //x fprintf(fich, "BONUSFREQ=%i\n", BONUSFREQ); fprintf(fich, "BONUSFREQ=%g\n", bonus_freq); // P.K. enable float number fprintf(fich, "NBOMBES=%i\n", NBOMBES); fprintf(fich, "REBOURS=%i\n", REBOURS); fputc('\n', fich); //#ifdef new_nive_syntax fprintf(fich, "XSIZE=%i\n", plan.nivewidth); // P.K. size of the gameplan fprintf(fich, "YSIZE=%i\n", plan.niveheight); fputc('\n', fich); //#endif // new_nive_syntax for (i=0; i < numperso; i++) { //x fprintf(fich, "perso[%i]:(%i,%i)\n", i, persopos[i].x, persopos[i].y); fprintf(fich, "perso[%i]:(%i,%i)\n", i, perso[i].pos.x, perso[i].pos.y); } fprintf(fich, "\n\n{\n\n"); for(y=0; y < plan.niveheight; y++) { for(x=0; x < plan.nivewidth; x++) { ncar = 6-1; //xx printf("x=%i, y=%i\n", plan.niveheight, plan.nivewidth); switch (plan.element[x][y].type) { case LIBRE : { fputc('_', fich); ncar--; if (plan.element[x][y].fixe) ncar -= fprintf(fich, "[%i]", plan.element[x][y].frame); }break; case DESTRUCTIBLE : { fputc('#', fich); ncar--; if (plan.element[x][y].fixe) ncar -= fprintf(fich, "[%i]", plan.element[x][y].frame); }break; case INDESTRUCTIBLE : { fputc('+', fich); ncar--; if (plan.element[x][y].fixe) ncar -= fprintf(fich, "[%i]", plan.element[x][y].frame); }break; case SECRETPASSAGE : // P.K. { fputc('§', fich); ncar--; if (plan.element[x][y].fixe) ncar -= fprintf(fich, "[%i]", plan.element[x][y].frame); }break; case TUNNEL : { fputc('=', fich); ncar--; ncar -= fprintf(fich, "[%i]", plan.element[x][y].frame); }break; case SENSUNIQUE : { fputc('>', fich); ncar--; ncar -= fprintf(fich, "[%i]", plan.element[x][y].anim); }break; case EVENEMENT : { if (plan.element[x][y].elem==teleport) { fputc('T', fich); ncar--; for (i=0; i < plan.element[x][y].nparams; i++) { // there might be no parametres ncar -= fprintf(fich, "[%i]", plan.element[x][y].params[i]); } /* i=0; do ncar -= fprintf(fich, "[%i]", plan.element[x][y].params[i]); while(++i