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 }
1.0.0 written by Dimitri van Heesch,
© 1997-1999