Back to Evolution Project page


Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Header Files   Sources   Compound Members   File Members  

sprite.c

00001 #include "sprite.h"
00002 #include <string.h>
00003 
00004 
00005 #ifdef __cplusplus
00006 extern "C" {
00007 #endif /* __cplusplus */
00008 
00009  
00010 int get_unit_from_pixelx (int pixel) {
00011   return (pixel / UNIT_WIDTH);
00012 }
00013 
00014 int get_unit_from_pixely (int pixel) {
00015   return (pixel / UNIT_HEIGHT);
00016 }
00017 
00018 void read_sprite_from_file(FILE* f, sprite* sp, gchar *sp_dir) {
00019   char buffer[1100];
00020 
00021   fgets(buffer, 300, f);
00022   buffer[strlen(buffer)-1]='\0';
00023   g_strstrip(buffer);
00024   if (0==g_strcasecmp(buffer, SPRITE_TYPE_GROUND_STRING)) 
00025     sp->type = SPRITE_TYPE_GROUND;
00026   else if (0==g_strcasecmp(buffer, SPRITE_TYPE_SPRITE_STRING)) 
00027     sp->type = SPRITE_TYPE_SPRITE;
00028   else 
00029     sp->type = SPRITE_TYPE_NONE;
00030 
00031   fgets(buffer, 300, f);
00032   buffer[strlen(buffer)-1]='\0';
00033   strcpy(sp->name, buffer); 
00034 
00035   g_strchug(sp->name);
00036   g_strchomp(sp->name);
00037 
00038   fgets(buffer, 1000, f);
00039   buffer[strlen(buffer)-1]='\0';
00040   strcpy(sp->description, buffer);
00041   fgets(buffer, 10, f);
00042   sp->sizex = atoi(buffer);
00043   fgets(buffer, 10, f);
00044   sp->sizey = atoi(buffer);
00045  
00046   //Reads the pixmap from file
00047   strcpy(sp->filename, sp_dir);
00048   strcat(sp->filename, "xpm/");
00049   strcat(sp->filename, sp->name);
00050   strcat(sp->filename, ".xpm");
00051   
00052   strcpy(sp->filename_tga, sp_dir);
00053   strcat(sp->filename_tga, "tga/");
00054   strcat(sp->filename_tga, sp->name);
00055   strcat(sp->filename_tga, ".xpm.tga");
00056   
00057   sp->width_pixels  = sp->sizex * UNIT_WIDTH;
00058   sp->height_pixels = sp->sizey * UNIT_HEIGHT;
00059   
00060 
00061   //  printf("'%s'\n", filename);
00062   return;
00063 }
00064 
00065 void print_sprite_info(sprite* sp) {
00066   printf("Sprite name:'%s'\nSprite description:'%s'\nSize:%d %d \nId:%d Type: %d\nImage filename:%s\n\n", sp->name, sp->description, sp->sizex, sp->sizey, sp->id, sp->type, sp->filename);
00067 }
00068 
00069 void read_all_sprites(char* filename, gchar *sp_dir) {
00070   FILE* f;
00071   sprite* sp;
00072   int i, j;
00073   i=g_list_length(sprite_list)+1;   //Start from 1...
00074   j=g_list_length(sprite_list_sp)+1;  //Start from 1...
00075   f = fopen(filename, "r");
00076   while ((!feof(f))) {
00077     sp = (sprite *) malloc(sizeof(sprite)); //Alloc memory for the sprite
00078     read_sprite_from_file(f, sp, sp_dir);
00079     if ((sp->sizex==0) || (sp->sizey==0)) {
00080       free (sp);
00081       break;
00082     }
00083     if (sp->type == SPRITE_TYPE_GROUND) {
00084       sp->id=i;
00085       i++;
00086       sprite_list =  g_list_prepend(sprite_list, sp);
00087     }
00088     else if (sp->type == SPRITE_TYPE_SPRITE) {
00089       sp->id=j;
00090       j++;
00091       sprite_list_sp =  g_list_prepend(sprite_list_sp, sp);
00092     } else {
00093       g_print("Invalid sprite type: %s (type %d)\n", sp->description, sp->type);
00094     }
00095     print_sprite_info(sp);
00096   }
00097   fclose(f);
00098   return;
00099 }
00100 
00101 sprite *get_sprite_from_id(GList *splist, int id) {
00102   GList *last, *current;
00103    
00104   last =    g_list_first(splist);
00105   current = g_list_last (splist);
00106 
00107   if (last) {
00108     do {
00109       if ((((sprite *)(current->data))->id)==id)
00110     return ((sprite *)(current->data));
00111       if (current==last) break;
00112       current = current->prev;
00113     } while (1);    
00114   }
00115   return NULL;
00116 }
00117 
00118 sprite_unit *sprite_unit_add(GList **unit_list, sprite *sp, int x, int y) {
00119   sprite_unit *sp_unit;
00120   
00121   sp_unit = g_malloc0(sizeof(sprite_unit));
00122   sp_unit->sprite = sp;
00123   sp_unit->unitx  = x;
00124   sp_unit->unity  = y;
00125   //  sp_unit->id     = g_list_length(*unit_list);
00126   *unit_list =  g_list_prepend(*unit_list, sp_unit);  
00127   return sp_unit;
00128 }
00129 
00130 rect add_sprite_on_unit(sprite *sp, int x, int y) {
00131   int i, j;
00132   sprite_unit *sp_unit;
00133   unit *unitmap;
00134   GList **unit_list=NULL;
00135   rect r1;
00136   r1.x = 0;
00137   r1.y=0;
00138   r1.sx = 0;
00139   r1.sy = 0;
00140 
00141   if ((x<0) || (y<0) || (x>=level_width) || (y>=level_height) ) {
00142 //    g_print ("There isn't unit (%d,%d)\n ", x, y);
00143     return r1; 
00144   }
00145   if (!sp) {
00146     g_print ("There isn't sprite to place on unit (%d, %d)!!! \n ", x, y);
00147     return r1;
00148   }
00149   if (sp->type==SPRITE_TYPE_SPRITE) {
00150     if (!can_place_sprite_on_unit(sp, x, y))
00151       return r1;
00152   } else 
00153     delete_sprite_on_unit(level, x, y);
00154   
00155     
00156   if (sp->type == SPRITE_TYPE_GROUND) {
00157     unitmap = level;
00158     unit_list = &sp_unit_list;
00159   }
00160   else if (sp->type == SPRITE_TYPE_SPRITE) {
00161     unitmap = levelsp;
00162     unit_list = &sp_unit_list_sp;
00163   } 
00164   else return r1;
00165 
00166   sp_unit = sprite_unit_add(unit_list, sp, x, y);
00167 
00168   for (i=x; i<x+sp->sizex; i++)
00169     for (j=y; j<y+sp->sizey; j++) {
00170       unitmap[(j*level_width)+i].sprite_id = sp->id;
00171       unitmap[(j*level_width)+i].draw_here = 0;
00172       unitmap[(j*level_width)+i].sp_unit = sp_unit;
00173       //      unitmap[(j*level_width)+i].unit_id = sp_unit->id;
00174     }
00175   unitmap[(y*level_width)+x].draw_here = 1;
00176   r1.x = x;
00177   r1.y=y;
00178   r1.sx = x+sp->sizex;
00179   r1.sy = y+sp->sizey;
00180   return r1;
00181 }
00182 
00183 
00184 int can_place_sprite_on_unit(sprite *sp, int x, int y) {
00185   int i, j;
00186   unit *unitmap;
00187 
00188   if (sp->type==SPRITE_TYPE_GROUND)
00189     unitmap = level;
00190   else if (sp->type==SPRITE_TYPE_SPRITE)
00191     unitmap = levelsp;
00192   else 
00193     return 0;
00194   
00195   for (i=x; i<x+sp->sizex; i++)
00196     for (j=y; j<y+sp->sizey; j++)
00197       if (unitmap[(j*level_width)+i].sp_unit) 
00198     return 0;
00199 
00200   return 1;
00201 }
00202 
00203 rect delete_sprite_on_unit(unit *unitmap, int x, int y){
00204   int i, j, x1, y1, sizex, sizey;
00205   sprite_unit *sp_unit;
00206   rect r1;
00207   r1.x = 0;
00208   r1.y=0;
00209   r1.sx = 0;
00210   r1.sy = 0;
00211 
00212   sp_unit = unitmap[(y*level_height)+x].sp_unit;
00213   if (!sp_unit) return r1;
00214 
00215   x1 = sp_unit->unitx;
00216   y1 = sp_unit->unity;
00217   sizex = sp_unit->sprite->sizex;
00218   sizey = sp_unit->sprite->sizey;
00219   for (i=x1; i<x1+sizex; i++)
00220     for (j=y1; j<y1+sizey; j++){
00221       unitmap[(j*level_height)+i].sprite_id = 0;
00222       unitmap[(j*level_height)+i].draw_here = 0;
00223       //      unitmap[(j*level_height)+i].unit_id = 0;
00224       unitmap[(j*level_height)+i].sp_unit = NULL;
00225     }
00226   //  g_print("(%d,%d) (%d,%d)\n", x1, y1, sizex, sizey);
00227   delete_sprite_unit(sp_unit);
00228   r1.x = x1;
00229   r1.y=y1;
00230   r1.sx = x1+sp_unit->sprite->sizex;
00231   r1.sy = y1+sp_unit->sprite->sizey;
00232   return r1;
00233 }
00234 
00235 void delete_sprite_unit(sprite_unit *sp_unit) {
00236   GList **list_of_units;
00237   if (!sp_unit) {
00238     g_print("?!? There isn't sprite_unit to delete....\n");
00239     return;
00240   }
00241   if (sp_unit->sprite->type == SPRITE_TYPE_GROUND)
00242     list_of_units = &sp_unit_list;
00243   else if (sp_unit->sprite->type == SPRITE_TYPE_SPRITE)
00244     list_of_units = &sp_unit_list_sp;
00245   else
00246     return;
00247 
00248   *list_of_units = g_list_remove(*list_of_units, sp_unit);
00249   //  g_print("%p \n", sp_unit);
00250   g_free(sp_unit);
00251 }
00252 
00253 int save_level_to_file(FILE *f){
00254   file_header fh;
00255   GList *last, *current;
00256   sprite_unit *sp_unit=NULL;
00257 
00258   fh.major_version = CURRENT_FILE_MAJORVERSION;
00259   fh.minor_version = CURRENT_FILE_MINORVERSION;
00260   fh.level_width = level_width;
00261   fh.level_height = level_height;
00262   fh.num_sprites_on_screen = g_list_length(sp_unit_list_sp);
00263   fh.num_grounds_on_screen = g_list_length(sp_unit_list);
00264 
00265   g_print("%ld %ld\n", fh.num_grounds_on_screen, fh.num_sprites_on_screen);
00266 
00267   //Writes header
00268   fwrite(&fh, sizeof(fh), 1, f);
00269 
00270   update_list_of_units();
00271 
00272   //Writes grounds map
00273   //  fwrite(level, sizeof(unit), level_width*level_height, f);
00274 
00275   //Writes sprites map
00276   //  fwrite(levelsp, sizeof(unit), level_width*level_height, f);
00277 
00278   //Writes each sprite_unit
00279   //grounds
00280   last = g_list_first(sp_unit_list);
00281   current = g_list_last(sp_unit_list);
00282   if (last) {
00283     do {
00284       sp_unit = (sprite_unit *)(current->data);
00285       fwrite(sp_unit, sizeof(sprite_unit), 1, f);
00286       //      g_print("(%d,%d)\n",  sp_unit->unitx, sp_unit->unity);
00287 
00288       if (current==last) break;
00289       current = current->prev;
00290     } while (1);    
00291   }
00292   //sprites
00293   last = g_list_first(sp_unit_list_sp);
00294   current = g_list_last(sp_unit_list_sp);
00295   if (last) {
00296     do {
00297       sp_unit = (sprite_unit *)(current->data);
00298       fwrite(sp_unit, sizeof(sprite_unit), 1, f);
00299       g_print("spriteid: %d, on (%d, %d)\n", 
00300           levelsp[(sp_unit->unity*level_width)+sp_unit->unitx].sprite_id,
00301           sp_unit->unitx, sp_unit->unity); 
00302 
00303       if (current==last) break;
00304       current = current->prev;
00305     } while (1);    
00306   }
00307   
00308 
00309   return 1;
00310 }
00311 
00312 
00313 int open_level_from_file(FILE *f){
00314   file_header fh;
00315   sprite_unit sp_unit;
00316   int i;
00317 
00318   if (!fread(&fh, sizeof(fh), 1, f)) return 0;
00319   if ((fh.major_version != CURRENT_FILE_MAJORVERSION) || 
00320       (fh.minor_version |= CURRENT_FILE_MINORVERSION)) {
00321     g_print("Warning: Version of file differs from current file version supported!!\n");
00322   }
00323   level_width = fh.level_width;
00324   level_height = fh.level_height;
00325   resize_array_of_units();
00326 
00327   //Reads grounds map
00328   //  if (fread(level, sizeof(unit), level_width*level_height, f)!= (level_width*level_height)) return 0;
00329 
00330   //Reads sprites map
00331   //  if (fread(levelsp, sizeof(unit), level_width*level_height, f)!= (level_width*level_height)) return 0;
00332 
00333 
00334   resize_array_of_units();
00335   
00336   g_print("%ld %ld\n", fh.num_grounds_on_screen, fh.num_sprites_on_screen);
00337 
00338   //Now, read each unit screen
00339   //grounds...
00340   for (i=0; i<fh.num_grounds_on_screen; i++) {
00341     if (!fread(&sp_unit, sizeof(sprite_unit), 1, f)) return 0;   
00342     add_sprite_on_unit(
00343                get_sprite_from_id(sprite_list, 
00344                       sp_unit.sprite_id),
00345                sp_unit.unitx, sp_unit.unity); 
00346   }
00347   //sprites...
00348   for (i=0; i<fh.num_sprites_on_screen; i++) {
00349     if (!fread(&sp_unit, sizeof(sprite_unit), 1, f)) return 0;   
00350     add_sprite_on_unit(
00351                get_sprite_from_id(sprite_list_sp, 
00352                       sp_unit.sprite_id),
00353                sp_unit.unitx, sp_unit.unity); 
00354   }
00355 
00356   //  g_print("%p %d , %p %d\n", sp_unit_list, g_list_length(sp_unit_list), sp_unit_list_sp, g_list_length(sp_unit_list_sp));
00357   return 1;
00358 }
00359 
00360 void resize_array_of_units(void) {
00361   int i, j;
00362   GList *last, *current, *next;
00363   //Initialize array of units...
00364   if (level) g_free (level);
00365   level = g_malloc0(level_width * level_height * sizeof(unit));
00366   if (levelsp) g_free (levelsp);
00367   levelsp = g_malloc0(level_width * level_height * sizeof(unit));
00368 
00369 
00370   if (sp_unit_list) {
00371     //Clear all items of list and, after, free the list...
00372     last = g_list_first(sp_unit_list);
00373     current = g_list_last(sp_unit_list);
00374     if (last) {
00375       do {
00376     if (sp_unit_list==NULL) break;
00377     next = current->prev;
00378     sp_unit_list = g_list_remove(sp_unit_list, current->data);
00379     g_free(current->data);
00380     current=next;
00381       } while (1);    
00382     }    
00383     g_list_free(sp_unit_list);
00384     sp_unit_list = NULL;
00385   }
00386   if (sp_unit_list_sp) {
00387     //Clear all items of list and, after, free the list...
00388     last = g_list_first(sp_unit_list_sp);
00389     current = g_list_last(sp_unit_list_sp);
00390     if (last) {
00391       do {
00392     if (sp_unit_list_sp==NULL) break;
00393     next = current->prev;
00394     sp_unit_list_sp = g_list_remove(sp_unit_list_sp, current->data);
00395     g_free(current->data);
00396     current=next;
00397       } while (1);    
00398     }    
00399     g_list_free(sp_unit_list_sp);
00400     sp_unit_list_sp = NULL;
00401   }
00402   //Initialize unit map
00403   for (i=0; i<level_width; i++)
00404     for (j=0; j<level_height; j++) {
00405       level[(j*level_width)+i].sprite_id = 1; //First ground
00406       level[(j*level_width)+i].draw_here = 1; 
00407       level[(j*level_width)+i].sp_unit = sprite_unit_add( &sp_unit_list,
00408                               get_sprite_from_id(sprite_list, 1) ,
00409                               i, j);
00410       //      level[(j*level_width)+i].unit_id = level[(j*level_width)+i].sp_unit->id;
00411       levelsp[(j*level_width)+i].sprite_id = 0;
00412       levelsp[(j*level_width)+i].draw_here = 0;
00413       levelsp[(j*level_width)+i].sp_unit = NULL;
00414       //      levelsp[(j*level_width)+i].unit_id = 0;
00415     }  
00416 }
00417 
00418 void update_list_of_units(void) {
00419   //Updates the list of unit on the screen...
00420   GList *last, *current;
00421   sprite_unit *sp_unit;
00422   int i, j;
00423   
00424   //On grounds
00425   last = g_list_first(sp_unit_list);
00426   current = g_list_last(sp_unit_list);
00427   i = 0; //Ids init with 0...
00428   if (last) {
00429     do {
00430       sp_unit = (sprite_unit *)(current->data);
00431       //      sp_unit->id = i++;
00432       
00433       if (current==last) break;
00434       current = current->prev;
00435     } while (1);    
00436   }
00437 
00438   for (i=0; i<level_width; i++)
00439     for (j=0; j<level_height; j++)
00440       if (level[(j*level_height)+i].sp_unit) {
00441     //  level[(j*level_height)+i].unit_id = level[(j*level_height)+i].sp_unit->id;
00442     level[(j*level_height)+i].sp_unit->sprite_id = level[(j*level_height)+i].sp_unit->sprite->id;
00443       } else {
00444     //  level[(j*level_height)+i].unit_id = -1;
00445       }
00446 
00447   //On sprites...
00448   last = g_list_first(sp_unit_list_sp);
00449   current = g_list_last(sp_unit_list_sp);
00450   i = 0; //Ids init with 0...
00451   if (last) {
00452     do {
00453       sp_unit = (sprite_unit *)(current->data);
00454       //      sp_unit->id = i++;
00455       
00456       if (current==last) break;
00457       current = current->prev;
00458     } while (1);    
00459   }
00460   
00461   for (i=0; i<level_width; i++)
00462     for (j=0; j<level_height; j++)
00463       if (levelsp[(j*level_height)+i].sp_unit) {
00464     //  levelsp[(j*level_height)+i].unit_id = levelsp[(j*level_height)+i].sp_unit->id;
00465     levelsp[(j*level_height)+i].sp_unit->sprite_id = levelsp[(j*level_height)+i].sp_unit->sprite->id;
00466       } else {
00467     //  levelsp[(j*level_height)+i].unit_id = -1;
00468       }
00469 }
00470 
00471 
00472 int file_exists(gchar *fn) { //Returns 1 if the current file exists...
00473   FILE *f;
00474   f=fopen(fn, "rb");
00475   if ( f) {
00476     fclose(f);
00477     return 1;
00478   }
00479   return 0;
00480 }
00481 
00482 void read_config(void) {
00483   FILE *f;
00484   gchar rcfile[1000];
00485   //Read the configfile
00486   f = fopen(CONFIG_FILENAME, "r");
00487   fgets(sprites_dir, 900, f);
00488   fclose(f);
00489   sprites_dir[strlen(sprites_dir)-1]='\0';
00490   if (sprites_dir[strlen(sprites_dir)-1]!='/')
00491     strcat(sprites_dir, "/");
00492 
00493   strcpy(sprites_dir_home, getenv("HOME"));
00494   sprites_dir_home[strlen(sprites_dir_home)]='\0';
00495   if (sprites_dir_home[strlen(sprites_dir_home)-1]!='/')
00496     strcat(sprites_dir_home, "/");
00497   strcat(sprites_dir_home, ".evolution/");
00498   
00499   strcpy(rcfile, sprites_dir);
00500   strcat(rcfile, LEVELEDITORFILE);
00501   printf("resource file:'%s'\n\n", rcfile);
00502     // Read all sprites from rcfile
00503   if (file_exists(rcfile)) read_all_sprites(rcfile, sprites_dir);
00504 
00505   strcpy(rcfile, sprites_dir_home);
00506   strcat(rcfile, LEVELEDITORFILE);
00507   printf("resource file on home directory:'%s'\n\n", rcfile);
00508   // Read all sprites from rcfile
00509   if (file_exists(rcfile)) read_all_sprites(rcfile, sprites_dir_home);  
00510 
00511 }
00512 
00513 
00514 
00515 #ifdef __cplusplus
00516 }
00517 #endif /* __cplusplus */
00518 
00519 void init_variables(void) {
00520   level=NULL;
00521   level_width = level_height = 0;
00522   sprite_list = sprite_list_sp = NULL;
00523   sp_unit_list = NULL;
00524   sp_unit_list_sp = NULL;
00525 }

Generated at Mon Nov 6 22:47:06 2000 for TheGameofEvolution by doxygen 1.0.0 written by Dimitri van Heesch, © 1997-1999