/** * @brief Frees the factions. */ void factions_free (void) { int i; /* free factions */ for (i=0; i<faction_nstack; i++) { free(faction_stack[i].name); if (faction_stack[i].longname != NULL) free(faction_stack[i].longname); if (faction_stack[i].displayname != NULL) free(faction_stack[i].displayname); if (faction_stack[i].logo_small != NULL) gl_freeTexture(faction_stack[i].logo_small); if (faction_stack[i].logo_tiny != NULL) gl_freeTexture(faction_stack[i].logo_tiny); if (faction_stack[i].nallies > 0) free(faction_stack[i].allies); if (faction_stack[i].nenemies > 0) free(faction_stack[i].enemies); if (faction_stack[i].sched_state != NULL) lua_close( faction_stack[i].sched_state ); if (faction_stack[i].state != NULL) lua_close( faction_stack[i].state ); } free(faction_stack); faction_stack = NULL; faction_nstack = 0; }
/** * @brief Frees the outfit stack. */ void outfit_free (void) { int i; Outfit *o; for (i=0; i < outfit_nstack; i++) { o = &outfit_stack[i]; /* free graphics */ if (outfit_gfx(&outfit_stack[i])) gl_freeTexture(outfit_gfx(&outfit_stack[i])); /* Type specific. */ if (outfit_isLauncher(o) && o->u.lau.ammo_name) free(o->u.lau.ammo_name); if (outfit_isFighterBay(o) && o->u.bay.ammo_name) free(o->u.bay.ammo_name); if (outfit_isFighter(o) && o->u.fig.ship) free(o->u.fig.ship); /* strings */ if (o->description) free(o->description); if (o->gfx_store) gl_freeTexture(o->gfx_store); if (o->license) free(o->license); free(o->name); } free(outfit_stack); }
/** * @brief Frees the loading screen. */ static void loadscreen_unload (void) { /* Free the textures */ if (loading != NULL) gl_freeTexture(loading); loading = NULL; }
/** @brief Sets map_zoom to zoom and recreats the faction disk texture. */ void map_setZoom(double zoom) { map_zoom = zoom; if (gl_faction_disk != NULL) gl_freeTexture( gl_faction_disk ); gl_faction_disk = gl_genFactionDisk( 50 * zoom ); }
/** * @brief Cleans up some land-related variables. */ void land_cleanup (void) { int i; /* Clean up default stuff. */ land_regen = 0; land_planet = NULL; landed = 0; land_visited = 0; /* Destroy window. */ if (land_wid > 0) window_destroy(land_wid); land_wid = 0; /* Clean up possible stray graphic. */ if (gfx_exterior != NULL) gl_freeTexture( gfx_exterior ); gfx_exterior = NULL; /* Clean up mission computer. */ for (i=0; i<mission_ncomputer; i++) mission_cleanup( &mission_computer[i] ); if (mission_computer != NULL) free(mission_computer); mission_computer = NULL; mission_ncomputer = 0; /* Clean up bar missions. */ npc_freeAll(); }
/** * @brief Frees a single npc. */ static void npc_free( NPC_t *npc ) { /* Common free stuff. */ free(npc->name); gl_freeTexture(npc->portrait); free(npc->desc); /* Type-specific free stuff. */ switch (npc->type) { case NPC_TYPE_GIVER: mission_cleanup(&npc->u.g); break; case NPC_TYPE_MISSION: free(npc->u.m.func); break; case NPC_TYPE_EVENT: free(npc->u.e.func); break; default: WARN("Freeing NPC of invalid type."); return; } }
/** * @brief Cleans up the OpenGL rendering routines. */ void gl_exitRender (void) { /* Destroy the VBO. */ gl_vboDestroy( gl_renderVBO ); gl_renderVBO = NULL; /* Destroy the circles. */ gl_freeTexture(gl_circle); gl_circle = NULL; }
/** * @brief Frees a SPFX_Base. * * @param effect SPFX_Base to free. */ static void spfx_base_free( SPFX_Base *effect ) { if (effect->name != NULL) { free(effect->name); effect->name = NULL; } if (effect->gfx != NULL) { gl_freeTexture(effect->gfx); effect->gfx = NULL; } }
/** * @brief Frees the texture. * * @luaparam t Texture to free. * @luafunc __gc( t ) */ static int texL_close( lua_State *L ) { LuaTex *lt; /* Get texture. */ lt = luaL_checktex( L, 1 ); /* Free texture. */ gl_freeTexture( lt->tex ); lt->tex = NULL; return 0; }
/** * @brief Function to clean up the background window. * @param wid Window to clean. * @param str Unused. */ static void menu_main_cleanBG( unsigned int wid, char* str ) { (void) str; /* * Ugly hack to prevent player.c from segfaulting due to the fact * that game will attempt to render while waiting for the quit event * pushed by exit_game() to be handled without actually having a player * nor anything of the likes (nor toolkit to stop rendering) while * not leaking any texture. */ gl_freeTexture( window_getImage(wid, "imgLogo") ); window_modifyImage( wid, "imgLogo", NULL ); }
/** * @brief Cleans up a mission. * * @param misn Mission to clean up. */ void mission_cleanup( Mission* misn ) { int i, ret; /* Hooks and missions. */ if (misn->id != 0) { hook_rmMisnParent( misn->id ); /* remove existing hooks */ npc_rm_parentMission( misn ); /* remove existing npc */ } /* Cargo. */ if (misn->cargo != NULL) { for (i=0; i<misn->ncargo; i++) { /* must unlink all the cargo */ if (player.p != NULL) { /* Only remove if player exists. */ ret = pilot_rmMissionCargo( player.p, misn->cargo[i], 0 ); if (ret) WARN("Failed to remove mission cargo '%d' for mission '%s'.", misn->cargo[i], misn->title); } } free(misn->cargo); } if (misn->osd > 0) osd_destroy(misn->osd); if (misn->L) lua_close(misn->L); /* Data. */ if (misn->title != NULL) free(misn->title); if (misn->desc != NULL) free(misn->desc); if (misn->reward != NULL) free(misn->reward); if (misn->portrait != NULL) gl_freeTexture(misn->portrait); if (misn->npc != NULL) free(misn->npc); /* Markers. */ if (misn->markers != NULL) array_free( misn->markers ); /* Claims. */ if (misn->claims != NULL) claim_destroy( misn->claims ); /* Clear the memory. */ memset( misn, 0, sizeof(Mission) ); }
/** * @brief Closes the mission computer window. * @param wid Window to close. * @param name Unused. */ static void bar_close( unsigned int wid, char *name ) { (void) wid; (void) name; /* Must not be regenerating. */ if (land_regen) { land_regen--; return; } if (mission_portrait != NULL) gl_freeTexture(mission_portrait); mission_portrait = NULL; }
/** * @brief Clears a background image array. * * @param arr Array to clear. */ static void background_clearImgArr( background_image_t **arr ) { int i; background_image_t *bkg; /* Must have an image array created. */ if (*arr == NULL) return; for (i=0; i<array_size(*arr); i++) { bkg = &((*arr)[i]); gl_freeTexture( bkg->image ); } /* Erase it all. */ array_erase( arr, &(*arr)[0], &(*arr)[ array_size(*arr) ] ); }
/** * @brief Cleans up the land window. * * @param wid Window closing. * @param name Unused. */ static void land_cleanupWindow( unsigned int wid, char *name ) { (void) wid; (void) name; /* Must not be regenerating. */ if (land_regen) { land_regen--; return; } /* Clean up possible stray graphic. */ if (gfx_exterior != NULL) { gl_freeTexture( gfx_exterior ); gfx_exterior = NULL; } }
/** * @brief Frees the factions. */ void factions_free (void) { int i; /* free factions */ for (i=0; i<faction_nstack; i++) { free(faction_stack[i].name); if (faction_stack[i].longname != NULL) free(faction_stack[i].longname); if (faction_stack[i].logo_small != NULL) gl_freeTexture(faction_stack[i].logo_small); if (faction_stack[i].nallies > 0) free(faction_stack[i].allies); if (faction_stack[i].nenemies > 0) free(faction_stack[i].enemies); } free(faction_stack); faction_stack = NULL; faction_nstack = 0; }
/** * @brief Cleans up the nebu subsystem. */ void nebu_exit (void) { int i; /* Free the Nebula BG. */ glDeleteTextures( NEBULA_Z, nebu_textures ); /* Free the puffs. */ for (i=0; i<NEBULA_PUFFS; i++) gl_freeTexture( nebu_pufftexs[i] ); /* Free the VBO. */ if (nebu_vboBG != NULL) { gl_vboDestroy( nebu_vboBG ); nebu_vboBG = NULL; } if (nebu_vboOverlay != NULL) { gl_vboDestroy( nebu_vboOverlay ); nebu_vboOverlay= NULL; } }
/** * @brief Fade an image in. * * @brief side Present image being displayed. * @brief transition Image in transition or on deck. * @brief img_file Path to the PNG on disk. */ static void intro_fade_image_in( intro_img_t *side, intro_img_t *transition, const char *img_file ) { if (NULL == side->tex) { /* Simple fade-in. */ side->tex = gl_newImage( img_file, 0 ); side->y = (double)SCREEN_H / 2.0 - (side->tex->h / 2.0); side->c.a = 0.0; side->fade_rate = 0.1; } else { /* * Transition or on-deck. The difference is whether one image is * replacing the other (transition), or whether the first must fade out * completely before the second comes in (on-deck). * * We can determine which is the case by seeing whether [fadeout] has been * called. I.e., is side->fade_rate < 0? */ if (NULL != transition->tex) { /* Scrolling is happening faster than fading... */ WARN( "Intro scrolling too fast!" ); gl_freeTexture( transition->tex ); } transition->tex = gl_newImage( img_file, 0 ); transition->y = (double)SCREEN_H / 2.0 - (transition->tex->h / 2.0); transition->c.a = 0.0; if (side->fade_rate < 0.0) transition->fade_rate = 0.0; /* put an image on deck. */ else { /* transition. */ transition->fade_rate = 0.1; side->fade_rate = -0.1; /* begin fading out. */ side->c.a = 0.99; } } }
/** * @brief Sets the current mission NPC. * * This is used in bar missions where you talk to a person. The portraits are * the ones found in gfx/portraits without the png extension. So for * gfx/portraits/none.png you would just use "none". * * @usage misn.setNPC( "Invisible Man", "none" ) * * @luaparam name Name of the NPC. * @luaparam portrait Name of the portrait to use for the NPC. * @luafunc setNPC( name, portrait ) */ static int misn_setNPC( lua_State *L ) { char buf[PATH_MAX]; const char *name, *str; Mission *cur_mission; cur_mission = misn_getFromLua(L); /* Free if portrait is already set. */ if (cur_mission->portrait != NULL) { gl_freeTexture(cur_mission->portrait); cur_mission->portrait = NULL; } /* Free NPC name. */ if (cur_mission->npc != NULL) { free(cur_mission->npc); cur_mission->npc = NULL; } /* For no parameters just leave having freed NPC. */ if (lua_gettop(L) == 0) return 0; /* Get parameters. */ name = luaL_checkstring(L,1); str = luaL_checkstring(L,2); /* Set NPC name. */ cur_mission->npc = strdup(name); /* Set portrait. */ nsnprintf( buf, PATH_MAX, "gfx/portraits/%s.png", str ); cur_mission->portrait = gl_newImage( buf, 0 ); return 0; }
/** * @brief Displays the introduction sequence. * * @brief text Path of text file to use. * @brief mus Type of music to use (run through music.lua). * @return 0 on success. */ int intro_display( const char *text, const char *mus ) { double offset; /* distance from bottom of the top line. */ double line_height; /* # pixels per line. */ int lines_per_screen; /* max appearing lines on the screen. */ scroll_buf_t *sb_arr; /* array of lines to render. */ scroll_buf_t *sb_list; /* list " " " " */ double vel = 16.; /* velocity: speed of text. */ int stop = 0; /* stop the intro. */ unsigned int tcur, tlast; /* timers. */ double delta; /* time diff from last render to this one. */ int line_index = 0; /* index into the big list of intro lines. */ intro_img_t side_image; /* image to go along with the text. */ intro_img_t transition; /* image for transitioning. */ /* Load the introduction. */ if (intro_load(text) < 0) return -1; /* Change music to intro music. */ if (mus != NULL) music_choose(mus); /* We need to clear key repeat to avoid infinite loops. */ toolkit_clearKey(); /* Enable keyrepeat just for the intro. */ SDL_EnableKeyRepeat( conf.repeat_delay, conf.repeat_freq ); /* Do a few calculations to figure out how many lines can be present on the screen at any given time. */ line_height = (double)intro_font.h * 1.3; lines_per_screen = (int)(SCREEN_H / line_height + 1.5); /* round up + 1 */ sb_arr = (scroll_buf_t*)malloc( sizeof(scroll_buf_t) * lines_per_screen ); /* Force the first line to be loaded immediately. */ offset = line_height; /* Create a cycle of lines. */ sb_list = arrange_scroll_buf( sb_arr, lines_per_screen ); /* Unset the side image. */ initialize_image( &side_image ); initialize_image( &transition ); tlast = SDL_GetTicks(); while (!stop) { tcur = SDL_GetTicks(); delta = (double)(tcur - tlast) / 1000.; tlast = tcur; /* Increment position. */ offset += vel * delta; while (! (offset < line_height)) { /* One line has scrolled off, and another one on. */ if (line_index < intro_nlines) { switch (intro_lines[line_index][0]) { case 't': /* plain ol' text. */ sb_list->text = &intro_lines[line_index][1]; offset -= line_height; sb_list = sb_list->next; break; case 'i': /* fade in image. */ intro_fade_image_in( &side_image, &transition, &intro_lines[line_index][1] ); break; case 'o': /* fade out image. */ if (NULL == side_image.tex) { WARN("Tried to fade out without an image." ); break; } side_image.fade_rate = -0.1; side_image.c.a = 0.99; break; default: /* unknown. */ break; } ++line_index; } else { sb_list->text = NULL; offset -= line_height; sb_list = sb_list->next; } } /* while (offset > line_height) */ /* Fade the side image. */ if (side_image.tex != NULL && side_image.c.a < 1.0) { side_image.c.a += delta * vel * side_image.fade_rate; if (transition.tex != NULL && transition.fade_rate > 0.0) { transition.c.a += delta * vel * transition.fade_rate; } if (side_image.c.a > 1.0) { /* Faded in... */ side_image.c.a = 1.0; side_image.fade_rate = 0.0; } else if (side_image.c.a < 0.0) { /* Faded out... */ gl_freeTexture( side_image.tex ); if (transition.tex != NULL) { side_image.tex = transition.tex; side_image.c.a = transition.c.a; side_image.y = transition.y; side_image.fade_rate = 0.1; transition.tex = NULL; transition.c.a = 1.0; } else { side_image.c.a = 1.0; side_image.tex = NULL; side_image.fade_rate = 0.0; } } } /* Clear stuff. */ glClear(GL_COLOR_BUFFER_BIT); /* Only thing we actually care about updating is music. */ music_update( 0. ); /* Draw text. */ stop = intro_draw_text( sb_list, offset, line_height ); if (NULL != side_image.tex) { /* Draw the image next to the text. */ gl_blitScale( side_image.tex, side_image.x, side_image.y, side_image.tex->w, side_image.tex->h, &side_image.c ); } if (NULL != transition.tex && transition.c.a > 0.0) { /* Draw the image in transition. */ gl_blitScale( transition.tex, transition.x, transition.y, transition.tex->w, transition.tex->h, &transition.c ); } /* Display stuff. */ SDL_GL_SwapBuffers(); SDL_Delay(10); /* No need to burn CPU. */ /* Handle user events. */ intro_event_handler( &stop, &offset, &vel ); } /* while (!stop) */ /* free malloc'd memory. */ free( sb_arr ); if (NULL != side_image.tex) { gl_freeTexture( side_image.tex ); } if (NULL != transition.tex) { gl_freeTexture( transition.tex ); } /* Disable intro's key repeat. */ SDL_EnableKeyRepeat( 0, 0 ); /* Stop music, normal music will start shortly after. */ music_stop(); /* Clean up after the introduction. */ intro_cleanup(); return 0; }