Back to Evolution Project page
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 }