ENTRYPOINT void init_fire(ModeInfo * mi) { firestruct *fs; /* allocate the main fire table if needed */ if (fire == NULL) { if ((fire = (firestruct *) calloc(MI_NUM_SCREENS(mi), sizeof(firestruct))) == NULL) return; } /* initialise the per screen fire structure */ fs = &fire[MI_SCREEN(mi)]; fs->np = MI_COUNT(mi); fs->fog = do_fog; fs->shadows = do_shadows; /* initialise fire particles if any */ if ((fs->np)&&(fs->p == NULL)) { if ((fs->p = (part *) calloc(fs->np, sizeof(part))) == NULL) { free_fire(fs); return; } } else if (fs->r == NULL) { /* initialise rain particles if no fire particles */ if ((fs->r = (rain *) calloc(NUMPART, sizeof(part))) == NULL) { free_fire(fs); return; } } /* check tree number */ if (do_texture) fs->num_trees = (num_trees<MAX_TREES)?num_trees:MAX_TREES; else fs->num_trees = 0; fs->trackball = gltrackball_init (); /* xlock GL stuff */ if ((fs->glx_context = init_GL(mi)) != NULL) { #ifndef STANDALONE Reshape(mi); /* xlock mode */ #else reshape_fire(mi,MI_WIDTH(mi),MI_HEIGHT(mi)); /* xscreensaver mode */ #endif glDrawBuffer(GL_BACK); if (!Init(mi)) { free_fire(fs); return; } } else { MI_CLEARWINDOW(mi); } }
void uninit_fire(void) { int i; for (i = 0; i < MAX_FIRES; i++) free_fire(i); num_fires = 0; }
void release_fire(ModeInfo * mi) { if (fire != NULL) { int screen; for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) free_fire(&fire[screen]); free(fire); fire = (firestruct *) NULL; } if (mode_font != None) { /* only free-ed when there are no more screens used */ XFreeFont(MI_DISPLAY(mi), mode_font); mode_font = None; } FreeAllGL(mi); }
/* updates positions of fires and also checks for collisions */ void update_fire(void) { int i, j; /* first loop to update all fires */ for (i = 0; i < MAX_FIRES; i++) { if (fires[i].surface) { /* if the laser has expired, free the surface and set it as off, otherwise, update its information */ if (current_time > fires[i].expire_time) { /* fire has expired */ free_fire(i); } else { float factor = (((float)loop_length / 1000.0f) * (float)fires[i].velocity); fires[i].world_x += get_cos(fires[i].angle) * factor; fires[i].world_y += get_neg_sin(fires[i].angle) * factor; /* update the fire, hasnt expired yet */ fires[i].screen_x = (short int)((int)fires[i].world_x - camera_x); fires[i].screen_y = (short int)((int)fires[i].world_y - camera_y); } } } /* second loop to check for collisions */ for (i = 0; i < MAX_FIRES; i++) { if (fires[i].surface) { for (j = 0; j < MAX_SHIPS; j++) { if (ships[j]) { if ((current_time >= ships[j]->creation_delay) && (!ships[j]->landed) && (ships[j]->hull_strength > 0)) { if (fires[i].owner != ships[j]) { if (get_distance_sqrd(fires[i].world_x, fires[i].world_y, ships[j]->world_x, ships[j]->world_y) < (ships[j]->model->radius * ships[j]->model->radius)) { /* collision has occured */ damage_ship(ships[j], &fires[i]); free_fire(i); /* do a check, it's possible the ship was destroyed and freed (and now null) in damage_ship() */ if (ships[j]) ship_was_fired_upon(ships[j]); j = num_ships; /* dont need to continue checking for more collisions, one is enough */ } } } } } } /* need to recheck as a destroyed fire could have occured and 'i' may have been incremented */ if (fires[i].surface) { for (j = 0; j < MAX_ASTEROIDS; j++) { if (asteroids[j].on) { if (get_distance_sqrd(fires[i].world_x, fires[i].world_y, asteroids[j].x, asteroids[j].y) < 2500) { /* collision has occured */ damage_asteroid(j, fires[i].weapon->strength); free_fire(i); j = MAX_SHIPS; /* dont need to continue checking for more collisions, one is enough */ } } } } /* need to recheck as a destroyed fire could have occured and 'i' may have been incremented */ if (fires[i].surface) { if (fires[i].owner != player.ship) { if (get_distance_from_player_sqrd(fires[i].world_x, fires[i].world_y) < (player.ship->model->radius * player.ship->model->radius)) { damage_ship(player.ship, &fires[i]); free_fire(i); } } } } }