/* world.c * * Represents a map. * * (c) 2006, Joseph Curtis */ #include #include #include #include "display.h" #include "world.h" #include "player.h" #include "input.h" #ifndef x86 #include //#define printf pspDebugScreenPrintf #endif /* The default world */ struct world *default_world; struct world *create_world() { struct world *w; printf("create_world:\n"); w = calloc(1, sizeof(struct world)); #ifndef x86 w->graphics = loadImage("images/SCENERYC.png"); if(w->graphics == NULL) printf("Failed to load scenery.\n"); w->army_graphics = loadImage("images/ARMIESC.png"); if(w->army_graphics == NULL) printf("Failed to load army graphics.\n"); w->font = loadImage("images/FANTS.png"); if (w->font == NULL) printf("Failed to load font graphics.\n"); w->graphics2 = loadImage("images/avatars.png"); if (w->graphics2 == NULL) printf("Failed to load more graphics.\n"); #endif #ifdef x86 SDL_Surface *tmp; tmp = IMG_Load("images/SCENERYC.png"); w->graphics = SDL_DisplayFormat(tmp); SDL_FreeSurface(tmp); tmp = IMG_Load("images/ARMIESC.png"); w->army_graphics = SDL_DisplayFormat(tmp); SDL_FreeSurface(tmp); tmp = IMG_Load("images/FANTS.png"); w->font = SDL_DisplayFormat(tmp); SDL_FreeSurface(tmp); tmp = IMG_Load("images/avatars.png"); w->graphics2 = SDL_DisplayFormat(tmp); SDL_FreeSurface(tmp); #endif w->num_players = NUM_PLAYERS; return w; } int destroy_world(struct world *w) { free(w->map); free(w->towns); free(w->armies); #ifndef x86 free(w->graphics); free(w->army_graphics); free(w->font); #endif free(w); return 1; } // TODO: error checking here and below int save_world(struct world *w, char * file) { FILE *f; f = fopen(file, "w"); if(f == NULL) return (int)NULL; /* write the eight ints */ fwrite(w, sizeof(int), 8, f); /* write the command */ fwrite(w->command, sizeof(char), 1, f); /* write the name */ fwrite(w->name, sizeof(char), WORLD_NAME_LENGTH, f); /* write the cells */ fwrite(w->map, sizeof(struct cell), w->width*w->height, f); /* write the towns */ fwrite(w->towns, sizeof(struct town), w->num_towns, f); /* write the armies */ fwrite(w->armies, sizeof(struct army_group), w->num_armies, f); /* write the players */ fwrite(w->players, sizeof(struct player), w->num_players, f); return 1; } int load_world(struct world *w, char *file) { FILE *f; f = fopen(file, "r"); if(f == NULL) return NULL; w = realloc(w, sizeof(struct world)); printf("realloc'ed world\n"); /* read the eight ints */ fread(w, sizeof(int), 8, f); printf("read six ints, %d, %d, %d, %d, %d, %d\n", w->width, w->height, w->num_towns, w->num_armies, w->vis_x, w->vis_y); /* read the command */ fread(w->command, sizeof(char), 1, f); /* read the name */ fread(w->name, sizeof(char), WORLD_NAME_LENGTH, f); printf("read the name: %s\n", w->name); w->map = realloc(w->map, sizeof(struct cell) * w->width * w->height); printf("realloc'ed map\n"); /* read the cells */ printf("read %d cells\n", fread(w->map, sizeof(struct cell), w->width*w->height, f)); w->towns = realloc(w->towns, sizeof(struct town) * w->num_towns); // printf("realloc'ed the towns\n"); /* read the towns */ printf("read %d towns\n", fread(w->towns, sizeof(struct town), w->num_towns, f)); w->armies = realloc(w->armies, sizeof(struct army_group) * w->num_armies); // printf("realloc'ed the armies\n"); /* read the armies */ printf("read %d armies\n", fread(w->armies, sizeof(struct army_group), w->num_armies, f)); w->players = realloc(w->players, sizeof(struct player) * w->num_players); /* read the players */ fread(w->players, sizeof(struct player), w->num_players, f); return 1; } int load_world_text(struct world *w, char *file) { FILE *f; int i, j; printf("load_world_text:\n"); f = fopen(file, "r"); if (f == NULL) return (int)NULL; w = realloc(w, sizeof(struct world)); /* read the first line */ fscanf(f, "%d %d %d %d %d %d %d %d %d %s\n", &(w->width), &(w->height), &(w->num_towns), &(w->num_armies), &(w->num_players), &(w->vis_x), &(w->vis_y), &(w->turn), &(w->command), w->name); printf("Read first line\n"); w->map = realloc(w->map, sizeof(struct cell) * w->width * w->height); w->towns = realloc(w->towns, sizeof(struct town) * w->num_towns); w->armies = realloc(w->armies, sizeof(struct army_group) * w->num_armies); w->players = realloc(w->players, sizeof(struct player) * w->num_players); printf("Realloced\n"); for (j=0;jheight;j++) { for (i=0;iwidth;i++) { fscanf(f, "%d ", &(w->map[I(i, j, w->width)].image)); } } printf("Read cells\n"); for (i=0;inum_towns;i++) { printf("About to read town %d\n", i); fscanf(f, "%s %d %d %d %d %d %d %d\n", w->towns[i].name, &(w->towns[i].x), &(w->towns[i].y), &(w->towns[i].image), &(w->towns[i].defence), &(w->towns[i].owner), &(w->towns[i].income), &(w->towns[i].num_production)); /*fscanf(f, "%s %d %d %d\n", w->towns[i].name, &(w->towns[i].x), &(w->towns[i].y), &(w->towns[i].image));*/ printf("Finished reading town %d\n", i); for (j=0;jtowns[i].num_production;j++) { fscanf(f, "%d %d %d\n", &(w->towns[i].production[j].type), &(w->towns[i].production[j].time), &(w->towns[i].production[j].cost)); } printf("Finished town %d's production info\n", i); w->towns[i].current_production = -1; printf("Read town %d\n", i); } w->selected_army = -1; printf("Read towns\n"); //fclose(file); return 1; } int setup_default_world() { int i, j; default_world = create_world(); default_world->width = 11; default_world->height = 19; strcpy(default_world->name, "Defaultia"); default_world->map = malloc(sizeof(struct cell)*default_world->width*default_world->height); for(i=0;i<(default_world->height)*(default_world->width);i++) default_world->map[i].image = 9; for (i=0;iwidth;i++) default_world->map[i].image = 8; for (i=0;iwidth;i++) default_world->map[I(i, (default_world->height-1), default_world->width)].image = 8; for(i=0;iheight;i++) default_world->map[I(0, i, default_world->width)].image = 8; for(i=0;iheight;i++) default_world->map[I((default_world->width-1), i, default_world->width)].image = 8; for (i=0;iwidth;i++) default_world->map[I(i, (default_world->height/2), default_world->width)].image = 8; for (i=0;iheight;i++) default_world->map[I((default_world->width/2), i, default_world->width)].image = 8; // default_world->vis_x = ((default_world->width*CELL_WIDTH) / 2) - ((VIS_WIDTH * CELL_WIDTH) / 2); VISX_SET(default_world->vis_x, ((default_world->width*CELL_WIDTH) / 2) - ((VIS_WIDTH * CELL_WIDTH) / 2)); // default_world->vis_y = ((default_world->height*CELL_HEIGHT) / 2) - ((VIS_HEIGHT * CELL_HEIGHT) / 2); VISY_SET(default_world->vis_y, ((default_world->height*CELL_HEIGHT) / 2) - ((VIS_HEIGHT * CELL_HEIGHT) / 2)); #ifndef x86 default_world->graphics = loadImage("images/SCENERY.png"); if(!default_world->graphics) { printf("Image load failed!\n"); } else { printf("After show_world\n"); } #endif return 1; } void print_world(struct world *w) { int i, j; printf("Name: %s\n", w->name); printf("width: %d, height: %d\n", w->width, w->height); printf("num_towns: %d, num_armies: %d\n", w->num_towns, w->num_armies); printf("vis_x: %d, vis_y: %d\n\n", w->vis_x, w->vis_y); for (j=0;jheight;j++) { for(i=0;iwidth;i++) { printf("%3d ", w->map[I(i, j, w->width)].image); } printf("\n"); } for(i=0;inum_towns;i++) { printf("%s: %d, %d, %d\n", w->towns[i].name, w->towns[i].x, w->towns[i].y, w->towns[i].image); } } void create_test_army(struct world *w) { printf("create_test_army:\n"); w->num_armies = 1; w->armies = realloc(w->armies, sizeof(struct army_group) * w->num_armies); w->armies[0].num_armies = 1; w->armies[0].on_top = 0; w->armies[0].a[0].type = light_infantry; strcpy(w->armies[0].a[0].name, "Jo's Magnificent!"); w->armies[0].a[0].moves_left = light_infantry.max_moves; w->armies[0].a[0].x = 5; w->armies[0].a[0].y = 5; // print_army(w->armies[0].a[0]); } // TODO: All this in a file void create_test_player(struct world *w) { printf("create_test_player:\n"); w->num_players = 8; w->players = realloc(w->players, sizeof(struct player) * w->num_players); memset(w->players, 0, sizeof(struct player) * w->num_players); printf("realloced players\n"); w->num_armies = 0; /*w->armies = realloc(w->armies, sizeof(struct army_group) * w->num_armies); memset(w->armies, 0, sizeof(struct army_group) * w->num_armies); */ strcpy(w->players[0].name, "Sirians"); w->players[0].team = SIRIANS; w->players[0].num_cities = 1; w->players[0].income = 50; w->players[0].upkeep = 0; w->players[0].gold = 100; w->players[0].type = HUMAN; w->players[0].capital = 0; /* w->armies[0].num_armies = 5; w->armies[0].a[0].type = hero; strcpy(w->armies[0].a[0].name, "Leofsunu"); w->armies[0].a[0].moves_left = hero.max_moves; w->armies[0].a[0].x = w->towns[w->players[0].capital].x; w->armies[0].a[0].y = w->towns[w->players[0].capital].y; w->armies[0].a[0].team = SIRIANS;*/ // w->armies[0].selected = SELECT_GROUP; strcpy(w->players[1].name, "Storm Giants"); w->players[1].team = STORM_GIANTS; w->players[1].num_cities = 1; w->players[1].income = 50; w->players[1].upkeep = 0; w->players[1].gold = 100; w->players[1].type = WARLORD; w->players[1].capital = 1; /*w->armies[1].num_armies = 7; w->armies[1].a[0].type = hero; strcpy(w->armies[1].a[0].name, "Sir Gareth"); w->armies[1].a[0].moves_left = hero.max_moves; w->armies[1].a[0].x = w->towns[w->players[1].capital].x; w->armies[1].a[0].y = w->towns[w->players[1].capital].y; w->armies[1].a[0].team = STORM_GIANTS;*/ //w->armies[1].selected = SELECT_GROUP; strcpy(w->players[2].name, "Grey Dwarves"); w->players[2].team = GREY_DWARVES; w->players[2].num_cities = 1; w->players[2].income = 50; w->players[2].upkeep = 0; w->players[2].gold = 100; w->players[2].type = HUMAN; w->players[2].capital = 2; /*w->armies[2].num_armies = 1; w->armies[2].a[0].type = hero; strcpy(w->armies[2].a[0].name, "Byrthnoth"); w->armies[2].a[0].moves_left = hero.max_moves; w->armies[2].a[0].x = w->towns[w->players[2].capital].x; w->armies[2].a[0].y = w->towns[w->players[2].capital].y; w->armies[2].a[0].team = GREY_DWARVES; */ strcpy(w->players[3].name, "Orcs of Kor"); w->players[3].team = ORCS_OF_KOR; w->players[3].num_cities = 1; w->players[3].income = 50; w->players[3].upkeep = 0; w->players[3].gold = 100; w->players[3].type = HUMAN; w->players[3].capital = 3; /* w->armies[3].num_armies = 1; w->armies[3].a[0].type = hero; strcpy(w->armies[3].a[0].name, "Lord Falkner"); w->armies[3].a[0].moves_left = hero.max_moves; w->armies[3].a[0].x = w->towns[w->players[3].capital].x; w->armies[3].a[0].y = w->towns[w->players[3].capital].y; w->armies[3].a[0].team = ORCS_OF_KOR; */ strcpy(w->players[4].name, "Elvallie"); w->players[4].team = ELVALLIE; w->players[4].num_cities = 1; w->players[4].income = 50; w->players[4].upkeep = 0; w->players[4].gold = 100; w->players[4].type = HUMAN; w->players[4].capital = 4; /* w->armies[4].num_armies = 1; w->armies[4].a[0].type = hero; strcpy(w->armies[4].a[0].name, "Duke Tintagel"); w->armies[4].a[0].moves_left = hero.max_moves; w->armies[4].a[0].x = w->towns[w->players[4].capital].x; w->armies[4].a[0].y = w->towns[w->players[4].capital].y; w->armies[4].a[0].team = ELVALLIE; */ strcpy(w->players[5].name, "Selentines"); w->players[5].team = SELENTINES; w->players[5].num_cities = 1; w->players[5].income = 50; w->players[5].upkeep = 0; w->players[5].gold = 100; w->players[5].type = HUMAN; w->players[5].capital = 5; /* w->armies[5].num_armies = 1; w->armies[5].a[0].type = hero; strcpy(w->armies[5].a[0].name, "Ladie Lai"); w->armies[5].a[0].moves_left = hero.max_moves; w->armies[5].a[0].x = w->towns[w->players[5].capital].x; w->armies[5].a[0].y = w->towns[w->players[5].capital].y; w->armies[5].a[0].team = SELENTINES; */ strcpy(w->players[6].name, "Horse Lords"); w->players[6].team = HORSE_LORDS; w->players[6].num_cities = 1; w->players[6].income = 50; w->players[6].upkeep = 0; w->players[6].gold = 100; w->players[6].type = HUMAN; w->players[6].capital = 6; /* w->armies[6].num_armies = 1; w->armies[6].a[0].type = hero; strcpy(w->armies[6].a[0].name, "Leofsunu"); w->armies[6].a[0].moves_left = hero.max_moves; w->armies[6].a[0].x = w->towns[w->players[6].capital].x; w->armies[6].a[0].y = w->towns[w->players[6].capital].y; w->armies[6].a[0].team = HORSE_LORDS; */ strcpy(w->players[7].name, "Lord Bane"); w->players[7].team = LORD_BANE; w->players[7].num_cities = 1; w->players[7].income = 50; w->players[7].upkeep = 0; w->players[7].gold = 100; w->players[7].type = HUMAN; w->players[7].capital = 7; /* w->armies[7].num_armies = 1; w->armies[7].a[0].type = hero; strcpy(w->armies[7].a[0].name, "Leofsunu"); w->armies[7].a[0].moves_left = hero.max_moves; w->armies[7].a[0].x = w->towns[w->players[7].capital].x; w->armies[7].a[0].y = w->towns[w->players[7].capital].y; w->armies[7].a[0].team = LORD_BANE;*/ // w->armies[7].selected = SELECT_GROUP; return; } /** * TODO: Calculate productions */ void start_turn(struct world *w, struct display *d) { w->turn++; struct player p = w->players[w->turn%w->num_players]; w->command = CMD_DIALOGUE; /* centre on capital */ // VISX_SET(w->vis_x, (((w->towns[p.capital].x+1) * CELL_WIDTH) - (SCREEN_WIDTH/2))); // VISY_SET(w->vis_y, (((w->towns[p.capital].y+1) * CELL_HEIGHT) - (SCREEN_HEIGHT/2))); w->vis_x = ((w->towns[p.capital].x+1) * CELL_WIDTH) - (SCREEN_WIDTH/2); w->vis_y = ((w->towns[p.capital].y+1) * CELL_HEIGHT) - (SCREEN_HEIGHT/2); if(w->vis_y>(w->height*CELL_HEIGHT)-SCREEN_HEIGHT-1) w->vis_y=w->height*CELL_HEIGHT-SCREEN_HEIGHT-1; if(w->vis_y<0) w->vis_y=0; if(w->vis_x>(w->width*CELL_WIDTH)-SCREEN_WIDTH-1) w->vis_x=w->width*CELL_WIDTH-SCREEN_WIDTH-1; if(w->vis_x<0) w->vis_x=0; sprintf(d->status_bar_text, "%s: Press X when ready!", p.name); update(d, w); wait_on_x(); /* change selected town to player's capital */ w->selected_town = p.capital; if (w->turn < 8) { /* emerge a hero! */ sprintf(d->status_bar_text, "In %s, a hero emerges!", w->towns[p.capital].name); update(d, w); wait_on_x(); emerge_hero(w); /* now default to the production panel */ production(w, d); } else { w->command = CMD_NONE; } /* decrement production forwarding moves */ /* production forwarding report in conjunction with above */ /* decrement all productions */ /* production report in conjunction with above */ update(d, w); } void emerge_hero(struct world *w) { w->num_armies++; w->armies = realloc(w->armies, sizeof(struct army_group) * w->num_armies); // memset(w->armies[w->num_armies], 0, sizeof(struct army_group)); // fprintf(stderr, "Armies: %d\n", w->num_armies); /* w->armies[w->num_armies-1].num_armies = 1; w->armies[0].a[0].type = hero; strcpy(w->armies[0].a[0].name, "Leofsunu"); w->armies[0].a[0].moves_left = hero.max_moves; w->armies[0].a[0].x = w->towns[w->players[0].capital].x; w->armies[0].a[0].y = w->towns[w->players[0].capital].y; w->armies[0].a[0].team = SIRIANS; */ w->armies[w->num_armies-1].num_armies = 1; w->armies[w->num_armies-1].a[0].type = hero; strcpy(w->armies[w->num_armies-1].a[0].name, hero_name()); w->armies[w->num_armies-1].a[0].moves_left = hero.max_moves; w->armies[w->num_armies-1].a[0].x = w->towns[w->players[w->turn%w->num_players].capital].x; w->armies[w->num_armies-1].a[0].y = w->towns[w->players[w->turn%w->num_players].capital].y; w->armies[w->num_armies-1].a[0].team = w->turn%w->num_players; w->armies[w->num_armies-1].selected = SELECT_NONE; } char * hero_name() { return "Leofsunu"; } void production(struct world *w, struct display *d) { int done = 0; int selected = w->towns[w->selected_town].current_production; struct player p = w->players[w->turn%w->num_players]; w->command = CMD_PROD; w->selected_town = p.capital; update(d, w); // if (w->command == CMD_PROD) { // if(w->towns[w->selected_town].num_production > 0) { // w->towns[w->selected_town].current_production = 0; // } // } // TODO: Button switch here. Annoying that it breaks down the // abstraction but I cannot easily see another way to do it :-( Make // a generic wait function in input.c which returns which button was // pressed. while (!done) { switch(wait_on_input()) { case PSP_CTRL_CROSS: if(w->towns[w->selected_town].num_production > 0) selected = 0; break; case PSP_CTRL_CIRCLE: if(w->towns[w->selected_town].num_production > 1) selected = 1; break; case PSP_CTRL_TRIANGLE: if(w->towns[w->selected_town].num_production > 2) selected = 2; break; case PSP_CTRL_SQUARE: if(w->towns[w->selected_town].num_production > 3) selected = 3; break; case PSP_CTRL_START: done = 1; break; case PSP_CTRL_SELECT: selected = -1; } w->towns[w->selected_town].current_production = selected; w->towns[w->selected_town].current_production_turns = w->towns[w->selected_town].production[selected].time; update(d, w); } // wait_on_x(); w->command = CMD_NONE; } void select_next_army(struct world *w) { if (w->selected_army < w->num_armies-1) w->selected_army++; else w->selected_army = 0; } void select_prev_army(struct world *w) { if(w->selected_army > 0) w->selected_army--; else w->selected_army = w->num_armies-1; }