commit
						fc80c1c69f
					
				
							
								
								
									
										440
									
								
								src/ai.c
									
									
									
									
									
								
							
							
						
						
									
										440
									
								
								src/ai.c
									
									
									
									
									
								
							| @ -20,139 +20,139 @@ | ||||
| #include "lluadef.h" | ||||
| #include "ai.h" | ||||
| 
 | ||||
| // == AI ======================================================
 | ||||
| //
 | ||||
| // -- Goal (Task) based AI with additional optimization.
 | ||||
| // AI uses the goal (task) based AI approach with tasks scripted
 | ||||
| // in lua. Additionally there is a task that is hardcoded and
 | ||||
| // obligatory in any AI script. The 'control' task, whose only
 | ||||
| // purpose is to assign tasks if there is none, and optimize
 | ||||
| // or change tasks if there are.
 | ||||
| //
 | ||||
| // Eg.. Pilot A is attacking Pilot B. Pilot C then comes along
 | ||||
| // the same system and is of the same faction as Pilot B. and
 | ||||
| // therefor attacks Pilot A. Pilot A would keep fighting pilot
 | ||||
| // B and until the control task comes in. Then the pilot could
 | ||||
| // run if it deems fit that Pilot C and Pilot B together are
 | ||||
| // both too strong for A. Or.. Attack C as it is an easy target
 | ||||
| // to finish.
 | ||||
| // Basically, there is many possibilities, and it's down to the
 | ||||
| // Lua fanatics to decide what to do.
 | ||||
| //
 | ||||
| // -- AI will follow basic tasks defined from Lua AI scripts.
 | ||||
| //  -- If task is NULL, AI will run "control" task.
 | ||||
| //  -- Task is continued every frame.
 | ||||
| //  -- "control" task is a special task that *must* exist in
 | ||||
| //      any given Pilot AI (missiles, and suck will use "seek".
 | ||||
| //    -- "control" task is not permanent, but transitory.
 | ||||
| //    -- "control" task sets another task.
 | ||||
| //  -- "control" task is also run at a set rate (depending on
 | ||||
| //      Lua global "control_rate") to choose optimal behaviour
 | ||||
| //      (task).
 | ||||
| // ============================================================
 | ||||
| /* == AI ====================================================== */ | ||||
| /* */ | ||||
| /* -- Goal (Task) based AI with additional optimization. */ | ||||
| /* AI uses the goal (task) based AI approach with tasks scripted */ | ||||
| /* in lua. Additionally there is a task that is hardcoded and */ | ||||
| /* obligatory in any AI script. The 'control' task, whose only */ | ||||
| /* purpose is to assign tasks if there is none, and optimize */ | ||||
| /* or change tasks if there are. */ | ||||
| /* */ | ||||
| /* Eg.. Pilot A is attacking Pilot B. Pilot C then comes along */ | ||||
| /* the same system and is of the same faction as Pilot B. and */ | ||||
| /* therefor attacks Pilot A. Pilot A would keep fighting pilot */ | ||||
| /* B and until the control task comes in. Then the pilot could */ | ||||
| /* run if it deems fit that Pilot C and Pilot B together are */ | ||||
| /* both too strong for A. Or.. Attack C as it is an easy target */ | ||||
| /* to finish. */ | ||||
| /* Basically, there is many possibilities, and it's down to the */ | ||||
| /* Lua fanatics to decide what to do. */ | ||||
| /* */ | ||||
| /* -- AI will follow basic tasks defined from Lua AI scripts. */ | ||||
| /*  -- If task is NULL, AI will run "control" task. */ | ||||
| /*  -- Task is continued every frame. */ | ||||
| /*  -- "control" task is a special task that *must* exist in */ | ||||
| /*      any given Pilot AI (missiles, and suck will use "seek". */ | ||||
| /*    -- "control" task is not permanent, but transitory. */ | ||||
| /*    -- "control" task sets another task. */ | ||||
| /*  -- "control" task is also run at a set rate (depending on */ | ||||
| /*      Lua global "control_rate") to choose optimal behaviour */ | ||||
| /*      (task). */ | ||||
| /* ============================================================ */ | ||||
| 
 | ||||
| // Register a number constant n to name s (syntax is just like lua_regfunc).
 | ||||
| /* Register a number constant n to name s (syntax is just like lua_regfunc). */ | ||||
| #define lua_regnumber(l,s,n)  (lua_pushnumber(l,n), lua_setglobal(l,s)) | ||||
| 
 | ||||
| // Ai flags.
 | ||||
| /* Ai flags. */ | ||||
| #define ai_setFlag(f) (pilot_flags |= f) | ||||
| #define ai_isFlag(f)  (pilot_flags  & f) | ||||
| // Flags.
 | ||||
| #define AI_PRIMARY    (1<<0)  // Firing primary weapon.
 | ||||
| #define AI_SECONDARY  (1<<1)  // Firing secondary weapon.
 | ||||
| /* Flags. */ | ||||
| #define AI_PRIMARY    (1<<0)  /* Firing primary weapon. */ | ||||
| #define AI_SECONDARY  (1<<1)  /* Firing secondary weapon. */ | ||||
| 
 | ||||
| // file info.
 | ||||
| /* file info. */ | ||||
| #define AI_PREFIX  "../scripts/ai/" | ||||
| #define AI_SUFFIX   ".lua" | ||||
| 
 | ||||
| // AI profiles.
 | ||||
| /* AI profiles. */ | ||||
| static AI_Profile* profiles = NULL; | ||||
| static int nprofiles = 0; | ||||
| // Current AI Lua interpreter.
 | ||||
| /* Current AI Lua interpreter. */ | ||||
| static lua_State* L = NULL; | ||||
| 
 | ||||
| // Extern pilot hacks.
 | ||||
| /* Extern pilot hacks. */ | ||||
| extern Pilot** pilot_stack; | ||||
| extern int pilots; | ||||
| 
 | ||||
| static int ai_minbrakedist(lua_State* L); // Minimal breaking distance.
 | ||||
| static int ai_accel(lua_State* L); // Accelerate.
 | ||||
| static int ai_minbrakedist(lua_State* L); /* Minimal breaking distance. */ | ||||
| static int ai_accel(lua_State* L); /* Accelerate. */ | ||||
| 
 | ||||
| // Internal C routines.
 | ||||
| /* Internal C routines. */ | ||||
| static void ai_run(const char* funcname); | ||||
| static int ai_loadProfile(char* filename); | ||||
| static void ai_freetask(Task* t); | ||||
| // External C routines.
 | ||||
| void ai_attacked(Pilot* attacked, const unsigned int attacker); // weapon.c
 | ||||
| /* External C routines. */ | ||||
| void ai_attacked(Pilot* attacked, const unsigned int attacker); /* weapon.c */ | ||||
| void ai_create(Pilot* pilot); | ||||
| // C routines made external.
 | ||||
| /* C routines made external. */ | ||||
| void ai_destroy(Pilot* p); | ||||
| void ai_think(Pilot* pilot); | ||||
| 
 | ||||
| // Ai routines for Lua.
 | ||||
| // Tasks.
 | ||||
| static int ai_pushtask(lua_State* L);           // pushtask(string, number/pointer, number)
 | ||||
| static int ai_poptask(lua_State* L);            // poptask()
 | ||||
| static int ai_taskname(lua_State* L);           // Number taskname.
 | ||||
| // Consult values.
 | ||||
| static int ai_gettarget(lua_State* L);          // Pointer gettarget()
 | ||||
| static int ai_gettargetid(lua_State* L);        // Number gettargetis()
 | ||||
| static int ai_getrndpilot(lua_State* L);        // Number getrndpilot()
 | ||||
| static int ai_armour(lua_State* L);             // armour()
 | ||||
| static int ai_shield(lua_State* L);             // shield()
 | ||||
| static int ai_parmour(lua_State* L);            // parmour()
 | ||||
| static int ai_pshield(lua_State* L);            // pshield()
 | ||||
| static int ai_getdistance(lua_State* L);        // Number getdist(Vec2)
 | ||||
| static int ai_getpos(lua_State* L);             // getpos(number)
 | ||||
| static int ai_minbrakedist(lua_State* L);       // Number minbrakedist()
 | ||||
| static int ai_cargofree(lua_State* L);          // Number cargofree().
 | ||||
| // Boolean expressions.
 | ||||
| static int ai_exists(lua_State* L);             // boolean exists
 | ||||
| static int ai_ismaxvel(lua_State* L);           // Boolean ismaxvel()
 | ||||
| static int ai_isstopped(lua_State* L);          // Boolean isstopped()
 | ||||
| static int ai_isenemy(lua_State* L);            // boolean isenemy(number).
 | ||||
| static int ai_isally(lua_State* L);             // boolean isally(number).
 | ||||
| static int ai_incombat(lua_State* L);           // boolean incombat([number])
 | ||||
| // Movement.
 | ||||
| static int ai_accel(lua_State* L);              // accel(number); nuimber <= 1.
 | ||||
| static int ai_turn(lua_State* L);               // turn(number); abs(number) <= 1.
 | ||||
| static int ai_face(lua_State* L);               // face(number/pointer)
 | ||||
| static int ai_brake(lua_State* L);              // Brake()
 | ||||
| static int ai_getnearestplanet(lua_State* L);   // pointer getnearestplanet()
 | ||||
| static int ai_getrndplanet(lua_State* L);       // pointer getrndplanet()
 | ||||
| static int ai_hyperspace(lua_State* L);         // [number] hyperspace()
 | ||||
| static int ai_stop(lua_State* L);               // stop()
 | ||||
| // Combat.
 | ||||
| static int ai_combat(lua_State* L);             // combat(number)
 | ||||
| static int ai_settarget(lua_State* L);          // settarget(number)
 | ||||
| static int ai_secondary(lua_State* L);          // string secondary()
 | ||||
| static int ai_hasturrets(lua_State* L);         // bool hasturrets()
 | ||||
| static int ai_shoot(lua_State* L);              // shoot(number) number = 1,2,3.
 | ||||
| static int ai_getenemy(lua_State* L);           // number getenemy().
 | ||||
| static int ai_hostile(lua_State* L);            // hostile(number).
 | ||||
| // Timers.
 | ||||
| static int ai_settimer(lua_State* L);           // settimer(number, number)
 | ||||
| static int ai_timeup(lua_State* L);             // boolean timeup(number)
 | ||||
| // Messages.
 | ||||
| static int ai_comm(lua_State* L);               // comm(string)
 | ||||
| static int ai_broadcast(lua_State* L);          // broadcast(string)
 | ||||
| // Loot.
 | ||||
| static int ai_credits(lua_State* L);            // credits(number).
 | ||||
| static int ai_cargo(lua_State* L);              // cargo(name, quantity).
 | ||||
| static int ai_shipprice(lua_State* L);          // shipprice().
 | ||||
| /* Ai routines for Lua. */ | ||||
| /* Tasks. */ | ||||
| static int ai_pushtask(lua_State* L);           /* pushtask(string, number/pointer, number) */ | ||||
| static int ai_poptask(lua_State* L);            /* poptask() */ | ||||
| static int ai_taskname(lua_State* L);           /* Number taskname. */ | ||||
| /* Consult values. */ | ||||
| static int ai_gettarget(lua_State* L);          /* Pointer gettarget() */ | ||||
| static int ai_gettargetid(lua_State* L);        /* Number gettargetis() */ | ||||
| static int ai_getrndpilot(lua_State* L);        /* Number getrndpilot() */ | ||||
| static int ai_armour(lua_State* L);             /* armour() */ | ||||
| static int ai_shield(lua_State* L);             /* shield() */ | ||||
| static int ai_parmour(lua_State* L);            /* parmour() */ | ||||
| static int ai_pshield(lua_State* L);            /* pshield() */ | ||||
| static int ai_getdistance(lua_State* L);        /* Number getdist(Vec2) */ | ||||
| static int ai_getpos(lua_State* L);             /* getpos(number) */ | ||||
| static int ai_minbrakedist(lua_State* L);       /* Number minbrakedist() */ | ||||
| static int ai_cargofree(lua_State* L);          /* Number cargofree(). */ | ||||
| /* Boolean expressions. */ | ||||
| static int ai_exists(lua_State* L);             /* boolean exists */ | ||||
| static int ai_ismaxvel(lua_State* L);           /* Boolean ismaxvel() */ | ||||
| static int ai_isstopped(lua_State* L);          /* Boolean isstopped() */ | ||||
| static int ai_isenemy(lua_State* L);            /* boolean isenemy(number). */ | ||||
| static int ai_isally(lua_State* L);             /* boolean isally(number). */ | ||||
| static int ai_incombat(lua_State* L);           /* boolean incombat([number]) */ | ||||
| /* Movement. */ | ||||
| static int ai_accel(lua_State* L);              /* accel(number); nuimber <= 1. */ | ||||
| static int ai_turn(lua_State* L);               /* turn(number); abs(number) <= 1. */ | ||||
| static int ai_face(lua_State* L);               /* face(number/pointer) */ | ||||
| static int ai_brake(lua_State* L);              /* Brake() */ | ||||
| static int ai_getnearestplanet(lua_State* L);   /* pointer getnearestplanet() */ | ||||
| static int ai_getrndplanet(lua_State* L);       /* pointer getrndplanet() */ | ||||
| static int ai_hyperspace(lua_State* L);         /* [number] hyperspace() */ | ||||
| static int ai_stop(lua_State* L);               /* stop() */ | ||||
| /* Combat. */ | ||||
| static int ai_combat(lua_State* L);             /* combat(number) */ | ||||
| static int ai_settarget(lua_State* L);          /* settarget(number) */ | ||||
| static int ai_secondary(lua_State* L);          /* string secondary() */ | ||||
| static int ai_hasturrets(lua_State* L);         /* bool hasturrets() */ | ||||
| static int ai_shoot(lua_State* L);              /* shoot(number) number = 1,2,3. */ | ||||
| static int ai_getenemy(lua_State* L);           /* number getenemy(). */ | ||||
| static int ai_hostile(lua_State* L);            /* hostile(number). */ | ||||
| /* Timers. */ | ||||
| static int ai_settimer(lua_State* L);           /* settimer(number, number) */ | ||||
| static int ai_timeup(lua_State* L);             /* boolean timeup(number) */ | ||||
| /* Messages. */ | ||||
| static int ai_comm(lua_State* L);               /* comm(string) */ | ||||
| static int ai_broadcast(lua_State* L);          /* broadcast(string) */ | ||||
| /* Loot. */ | ||||
| static int ai_credits(lua_State* L);            /* credits(number). */ | ||||
| static int ai_cargo(lua_State* L);              /* cargo(name, quantity). */ | ||||
| static int ai_shipprice(lua_State* L);          /* shipprice(). */ | ||||
| 
 | ||||
| static const luaL_Reg ai_methods[] = { | ||||
|   // Tasks.
 | ||||
|   /* Tasks. */ | ||||
|   { "pushtask",             ai_pushtask         }, | ||||
|   { "poptask",              ai_poptask          }, | ||||
|   { "taskname",             ai_taskname         }, | ||||
|   // Sanity checks.
 | ||||
|   /* Sanity checks. */ | ||||
|   { "exists",               ai_exists           }, | ||||
|   { "ismaxvel",             ai_ismaxvel         }, | ||||
|   { "isstopped",            ai_isstopped        }, | ||||
|   { "isenemy",              ai_isenemy          }, | ||||
|   { "isally",               ai_isally           }, | ||||
|   // Get's.
 | ||||
|   /* Get's. */ | ||||
|   { "incombat",             ai_incombat         }, | ||||
|   { "target",               ai_gettarget        }, | ||||
|   { "targetid",             ai_gettargetid      }, | ||||
| @ -167,14 +167,14 @@ static const luaL_Reg ai_methods[] = { | ||||
|   { "cargofree",            ai_cargofree        }, | ||||
|   { "nearestplanet",        ai_getnearestplanet }, | ||||
|   { "rndplanet",            ai_getrndplanet     }, | ||||
|   // Movement.
 | ||||
|   /* Movement. */ | ||||
|   { "accel",                ai_accel            }, | ||||
|   { "turn",                 ai_turn             }, | ||||
|   { "face",                 ai_face             }, | ||||
|   { "brake",                ai_brake            }, | ||||
|   { "stop",                 ai_stop             }, | ||||
|   { "hyperspace",           ai_hyperspace       }, | ||||
|   // Combat.
 | ||||
|   /* Combat. */ | ||||
|   { "combat",               ai_combat           }, | ||||
|   { "settarget",            ai_settarget        }, | ||||
|   { "secondary",            ai_secondary        }, | ||||
| @ -182,55 +182,55 @@ static const luaL_Reg ai_methods[] = { | ||||
|   { "shoot",                ai_shoot            }, | ||||
|   { "getenemy",             ai_getenemy         }, | ||||
|   { "hostile",              ai_hostile          }, | ||||
|   // Timers.
 | ||||
|   /* Timers. */ | ||||
|   { "settime",              ai_settimer         }, | ||||
|   { "timeup",               ai_timeup           }, | ||||
|   // Messages.
 | ||||
|   /* Messages. */ | ||||
|   { "comm",                 ai_comm             }, | ||||
|   { "broadcast",            ai_broadcast        }, | ||||
|   // Loot.
 | ||||
|   /* Loot. */ | ||||
|   { "setcredits",           ai_credits          }, | ||||
|   { "setcargo",             ai_cargo            }, | ||||
|   { "shipprice",            ai_shipprice        }, | ||||
|   { 0, 0 } // End.
 | ||||
|   { 0, 0 } /* End. */ | ||||
| }; | ||||
| 
 | ||||
| // Current pilot "thinking" and assorted variables.
 | ||||
| /* Current pilot "thinking" and assorted variables. */ | ||||
| static Pilot* cur_pilot     = NULL; | ||||
| static double pilot_acc     = 0.; | ||||
| static double pilot_turn    = 0.; | ||||
| static int pilot_flags      = 0; | ||||
| static int pilot_target     = 0; | ||||
| 
 | ||||
| // Ai status: 'Create' functions that can't be used elsewhere.
 | ||||
| /* Ai status: 'Create' functions that can't be used elsewhere. */ | ||||
| #define AI_STATUS_NORMAL  1 | ||||
| #define AI_STATUS_CREATE  2 | ||||
| static int ai_status = AI_STATUS_NORMAL; | ||||
| 
 | ||||
| // Attempt to run a function.
 | ||||
| /* Attempt to run a function. */ | ||||
| static void ai_run(const char* funcname) { | ||||
|   lua_getglobal(L, funcname); | ||||
|   if(lua_pcall(L, 0, 0, 0)) | ||||
|     // Errors accured.
 | ||||
|     /* Errors accured. */ | ||||
|     WARN("Pilot '%s' ai -> '%s' : %s", | ||||
|          cur_pilot->name, funcname, lua_tostring(L,-1)); | ||||
| } | ||||
| 
 | ||||
| // Destroy the AI part of the pilot.
 | ||||
| /* Destroy the AI part of the pilot. */ | ||||
| void ai_destroy(Pilot* p) { | ||||
|   if(p->task) | ||||
|     ai_freetask(p->task); | ||||
| } | ||||
| 
 | ||||
| // Init the AI stuff. Which is basically Lua.
 | ||||
| /* Init the AI stuff. Which is basically Lua. */ | ||||
| int ai_init(void) { | ||||
|   char** files; | ||||
|   uint32_t nfiles, i; | ||||
| 
 | ||||
|   // Get the file list.
 | ||||
|   /* Get the file list. */ | ||||
|   files = pack_listfiles(data, &nfiles); | ||||
| 
 | ||||
|   // Load the profiles.
 | ||||
|   /* Load the profiles. */ | ||||
|   for(i = 0; i < nfiles; i++) | ||||
|     if((strncmp(files[i], AI_PREFIX, strlen(AI_PREFIX))==0 && | ||||
|         strncmp(files[i] + strlen(files[i]) - strlen(AI_SUFFIX), | ||||
| @ -238,7 +238,7 @@ int ai_init(void) { | ||||
|       if(ai_loadProfile(files[i])) | ||||
|         WARN("Error loading AI profile '%s'", files[i]); | ||||
| 
 | ||||
|   // Free the char allocated by pack.
 | ||||
|   /* Free the char allocated by pack. */ | ||||
|   for(i = 0; i < nfiles; i++) | ||||
|     free(files[i]); | ||||
|   free(files); | ||||
| @ -248,7 +248,7 @@ int ai_init(void) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Init an IA_Profile and add it to the stack.
 | ||||
| /* Init an IA_Profile and add it to the stack. */ | ||||
| static int ai_loadProfile(char* filename) { | ||||
|   char* buf = NULL; | ||||
|   uint32_t bufsize = 0; | ||||
| @ -272,17 +272,17 @@ static int ai_loadProfile(char* filename) { | ||||
| 
 | ||||
|   L = profiles[nprofiles-1].L; | ||||
| 
 | ||||
|   // Open the standard Lua libraries.
 | ||||
|   //luaL_openlibs(L);
 | ||||
|   /* Open the standard Lua libraries. */ | ||||
|   /*luaL_openlibs(L); */ | ||||
| 
 | ||||
|   // Constants.
 | ||||
|   lua_regnumber(L, "player", PLAYER_ID); // Player id.
 | ||||
|   /* Constants. */ | ||||
|   lua_regnumber(L, "player", PLAYER_ID); /* Player id. */ | ||||
| 
 | ||||
|   // Register C funstions in Lua.
 | ||||
|   /* Register C funstions in Lua. */ | ||||
|   luaL_register(L, "ai", ai_methods); | ||||
|   lua_loadRnd(L); | ||||
| 
 | ||||
|   // Now load the file, since all the functions have been previously loaded.
 | ||||
|   /* Now load the file, since all the functions have been previously loaded. */ | ||||
|   buf = pack_readfile(DATA, filename, &bufsize); | ||||
|   if(luaL_dobuffer(L, buf, bufsize, filename) != 0) { | ||||
|     ERR("loading AI file: %s", filename); | ||||
| @ -296,7 +296,7 @@ static int ai_loadProfile(char* filename) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Get the AI_Profile with name.
 | ||||
| /* Get the AI_Profile with name. */ | ||||
| AI_Profile* ai_getProfile(char* name) { | ||||
|   if(profiles == NULL) return NULL; | ||||
| 
 | ||||
| @ -309,7 +309,7 @@ AI_Profile* ai_getProfile(char* name) { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| // Clean up global AI
 | ||||
| /* Clean up global AI */ | ||||
| void ai_exit(void) { | ||||
|   int i; | ||||
|   for(i = 0; i < nprofiles; i++) { | ||||
| @ -319,44 +319,44 @@ void ai_exit(void) { | ||||
|   free(profiles); | ||||
| } | ||||
| 
 | ||||
| // Heart of hearts of the ai!! Brains of the pilot.
 | ||||
| /* Heart of hearts of the ai!! Brains of the pilot. */ | ||||
| void ai_think(Pilot* pilot) { | ||||
|   cur_pilot = pilot; // Set current pilot being processed.
 | ||||
|   L = cur_pilot->ai->L; // Set the AI profile to the current pilot's.
 | ||||
|   cur_pilot = pilot; /* Set current pilot being processed. */ | ||||
|   L = cur_pilot->ai->L; /* Set the AI profile to the current pilot's. */ | ||||
| 
 | ||||
|   // Clean up some variables.
 | ||||
|   /* Clean up some variables. */ | ||||
|   pilot_acc     = 0.; | ||||
|   pilot_turn    = 0.; | ||||
|   pilot_flags   = 0; | ||||
|   pilot_target  = 0; | ||||
| 
 | ||||
|   // Control function if pilot is idle or tick is up.
 | ||||
|   /* Control function if pilot is idle or tick is up. */ | ||||
|   if((cur_pilot->tcontrol < SDL_GetTicks()) || (cur_pilot->task == NULL)) { | ||||
|     ai_run("control"); // Run control.
 | ||||
|     ai_run("control"); /* Run control. */ | ||||
|     lua_getglobal(L, "control_rate"); | ||||
|     cur_pilot->tcontrol = SDL_GetTicks() + 1000*(int)lua_tonumber(L, -1); | ||||
|   } | ||||
|   if(cur_pilot->task) | ||||
|     // Pilot has a currently running task.
 | ||||
|     /* Pilot has a currently running task. */ | ||||
|     ai_run(cur_pilot->task->name); | ||||
| 
 | ||||
|   // Make sure pilot_acc and pilot_turn are legal moves.
 | ||||
|   if(pilot_acc > 1.) pilot_acc = 1.;    // Value must be <= 1.
 | ||||
|   if(pilot_turn > 1.) pilot_turn = 1.;  // Value must be between -1 and 1.
 | ||||
|   /* Make sure pilot_acc and pilot_turn are legal moves. */ | ||||
|   if(pilot_acc > 1.) pilot_acc = 1.;    /* Value must be <= 1. */ | ||||
|   if(pilot_turn > 1.) pilot_turn = 1.;  /* Value must be between -1 and 1. */ | ||||
|   else if(pilot_turn < -1.) pilot_turn = -1.; | ||||
| 
 | ||||
|   cur_pilot->solid->dir_vel = 0.; | ||||
|   if(pilot_turn) // Set the turning velocity.
 | ||||
|   if(pilot_turn) /* Set the turning velocity. */ | ||||
|     cur_pilot->solid->dir_vel -= cur_pilot->turn * pilot_turn; | ||||
|   vect_pset(&cur_pilot->solid->force, cur_pilot->thrust * pilot_acc, | ||||
|             cur_pilot->solid->dir); | ||||
| 
 | ||||
|   // Fire weapons if needs be.
 | ||||
|   if(ai_isFlag(AI_PRIMARY)) pilot_shoot(pilot, pilot_target, 0); // Primary.
 | ||||
|   if(ai_isFlag(AI_SECONDARY)) pilot_shoot(pilot, pilot_target, 1); // Secondary.
 | ||||
|   /* Fire weapons if needs be. */ | ||||
|   if(ai_isFlag(AI_PRIMARY)) pilot_shoot(pilot, pilot_target, 0); /* Primary. */ | ||||
|   if(ai_isFlag(AI_SECONDARY)) pilot_shoot(pilot, pilot_target, 1); /* Secondary. */ | ||||
| } | ||||
| 
 | ||||
| // Pilot is attacked.
 | ||||
| /* Pilot is attacked. */ | ||||
| void ai_attacked(Pilot* attacked, const unsigned int attacker) { | ||||
|   cur_pilot = attacked; | ||||
|   L = cur_pilot->ai->L; | ||||
| @ -365,7 +365,7 @@ void ai_attacked(Pilot* attacked, const unsigned int attacker) { | ||||
|   lua_pcall(L, 1, 0, 0); | ||||
| } | ||||
| 
 | ||||
| // Pilot was just created.
 | ||||
| /* Pilot was just created. */ | ||||
| void ai_create(Pilot* pilot) { | ||||
|   cur_pilot = pilot; | ||||
|   L = cur_pilot->ai->L; | ||||
| @ -374,28 +374,28 @@ void ai_create(Pilot* pilot) { | ||||
|   ai_status = AI_STATUS_NORMAL; | ||||
| } | ||||
| 
 | ||||
| // =====================
 | ||||
| // INTERNAL C FUNCTIONS.
 | ||||
| // =====================
 | ||||
| /* ===================== */ | ||||
| /* INTERNAL C FUNCTIONS. */ | ||||
| /* ===================== */ | ||||
| 
 | ||||
| // Free the task.
 | ||||
| /* Free the task. */ | ||||
| static void ai_freetask(Task* t) { | ||||
|   if(t->next) ai_freetask(t->next); // Woot, recursive freeing!
 | ||||
|   if(t->next) ai_freetask(t->next); /* Woot, recursive freeing! */ | ||||
| 
 | ||||
|   if(t->name)               free(t->name); | ||||
|   if(t->dtype == TYPE_PTR)  free(t->dat.target); | ||||
|   free(t); | ||||
| } | ||||
| 
 | ||||
| // ========================================================
 | ||||
| // C functions to call from Lua.
 | ||||
| // ========================================================
 | ||||
| /* ======================================================== */ | ||||
| /* C functions to call from Lua. */ | ||||
| /* ======================================================== */ | ||||
| 
 | ||||
| // Push the current stack.
 | ||||
| /* Push the current stack. */ | ||||
| static int ai_pushtask(lua_State* L) { | ||||
|   int pos; | ||||
|   if(lua_isnumber(L, 1)) pos = (int) lua_tonumber(L, 1); | ||||
|   else return 0; // Invalid param.
 | ||||
|   else return 0; /* Invalid param. */ | ||||
| 
 | ||||
|   Task* t = MALLOC_L(Task); | ||||
|   t->name = (lua_isstring(L, 2)) ? strdup((char*) lua_tostring(L, 2)) : NULL; | ||||
| @ -408,10 +408,10 @@ static int ai_pushtask(lua_State* L) { | ||||
|       t->dat.ID = (unsigned int) lua_tonumber(L, 3); | ||||
|     } | ||||
|     else if(lua_islightuserdata(L, 3)) { | ||||
|       // Only pointer valid is Vec2* in Lua.
 | ||||
|       /* Only pointer valid is Vec2* in Lua. */ | ||||
|       t->dtype = TYPE_PTR; | ||||
|       t->dat.target = MALLOC_L(Vec2); | ||||
|       // No idea why vectcpy doesn't work here..
 | ||||
|       /* No idea why vectcpy doesn't work here.. */ | ||||
|       ((Vec2*)t->dat.target)->x     = ((Vec2*)lua_topointer(L,3))->x; | ||||
|       ((Vec2*)t->dat.target)->y     = ((Vec2*)lua_topointer(L,3))->y; | ||||
|       ((Vec2*)t->dat.target)->mod   = ((Vec2*)lua_topointer(L,3))->mod; | ||||
| @ -420,24 +420,24 @@ static int ai_pushtask(lua_State* L) { | ||||
|       t->dtype = TYPE_NULL; | ||||
|   } | ||||
| 
 | ||||
|   if(cur_pilot->task == NULL) // No other tasks.
 | ||||
|   if(cur_pilot->task == NULL) /* No other tasks. */ | ||||
|     cur_pilot->task = t; | ||||
|   else if(pos == 1) { | ||||
|     // Put at the end.
 | ||||
|     /* Put at the end. */ | ||||
|     Task* pointer; | ||||
|     for(pointer = cur_pilot->task; pointer->next; pointer = pointer->next); | ||||
|     pointer->next = t; | ||||
|   } else { | ||||
|     // Default put at the beginning.
 | ||||
|     /* Default put at the beginning. */ | ||||
|     t->next = cur_pilot->task; | ||||
|     cur_pilot->task = t; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Pop the current task.
 | ||||
| /* Pop the current task. */ | ||||
| static int ai_poptask(lua_State* L) { | ||||
|   (void)L; // Just a hack to avoid -W -Wall warnings.
 | ||||
|   (void)L; /* Just a hack to avoid -W -Wall warnings. */ | ||||
|   Task* t = cur_pilot->task; | ||||
|   cur_pilot->task = t->next; | ||||
|   t->next = NULL; | ||||
| @ -445,14 +445,14 @@ static int ai_poptask(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Grab the current tasks name.
 | ||||
| /* Grab the current tasks name. */ | ||||
| static int ai_taskname(lua_State* L) { | ||||
|   if(cur_pilot->task) lua_pushstring(L, cur_pilot->task->name); | ||||
|   else lua_pushstring(L, "none"); | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Grab the target pointer.
 | ||||
| /* Grab the target pointer. */ | ||||
| static int ai_gettarget(lua_State* L) { | ||||
|   if(cur_pilot->task->dtype == TYPE_PTR) { | ||||
|     lua_pushlightuserdata(L, cur_pilot->task->dat.target); | ||||
| @ -461,7 +461,7 @@ static int ai_gettarget(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Get the ID.
 | ||||
| /* Get the ID. */ | ||||
| static int ai_gettargetid(lua_State* L) { | ||||
|   if(cur_pilot->task->dtype == TYPE_INT) { | ||||
|     lua_pushnumber(L, cur_pilot->task->dat.ID); | ||||
| @ -475,7 +475,7 @@ static int ai_getrndpilot(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Get the pilots armour.
 | ||||
| /* Get the pilots armour. */ | ||||
| static int ai_armour(lua_State* L) { | ||||
|   double d; | ||||
| 
 | ||||
| @ -486,7 +486,7 @@ static int ai_armour(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Get pilots shield.
 | ||||
| /* Get pilots shield. */ | ||||
| static int ai_shield(lua_State* L) { | ||||
|   double d; | ||||
| 
 | ||||
| @ -497,7 +497,7 @@ static int ai_shield(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Get the pilot's armour in percentage.
 | ||||
| /* Get the pilot's armour in percentage. */ | ||||
| static int ai_parmour(lua_State* L) { | ||||
|   double d; | ||||
|   Pilot* p; | ||||
| @ -512,7 +512,7 @@ static int ai_parmour(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Get the pilot's shield in percentage.
 | ||||
| /* Get the pilot's shield in percentage. */ | ||||
| static int ai_pshield(lua_State* L) { | ||||
|   double d; | ||||
|   Pilot* p; | ||||
| @ -528,7 +528,7 @@ static int ai_pshield(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Get the distance from the pointer.
 | ||||
| /* Get the distance from the pointer. */ | ||||
| static int ai_getdistance(lua_State* L) { | ||||
|   Vec2* vect; | ||||
| 
 | ||||
| @ -539,31 +539,31 @@ static int ai_getdistance(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Get the pilots position.
 | ||||
| /* Get the pilots position. */ | ||||
| static int ai_getpos(lua_State* L) { | ||||
|   Pilot* p; | ||||
|   if(lua_isnumber(L, 1)) { | ||||
|     p = pilot_get((int)lua_tonumber(L,1)); // Pilot ID.
 | ||||
|     p = pilot_get((int)lua_tonumber(L,1)); /* Pilot ID. */ | ||||
|     if(p == NULL) return 0; | ||||
|   } | ||||
|   else p = cur_pilot; // Default to ones self.
 | ||||
|   else p = cur_pilot; /* Default to ones self. */ | ||||
| 
 | ||||
|   lua_pushlightuserdata(L, &p->solid->pos); | ||||
| 
 | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // ========================================================
 | ||||
| // Get the minimum braking distance.
 | ||||
| //
 | ||||
| // Braking vel ==> 0 = v - a*dt
 | ||||
| // Add turn around time (to initial velocity) :
 | ||||
| // ==> 180.*360./cur_pilot->turn
 | ||||
| // Add it to general euler equation x = v*t + 0.5 * a * t^2
 | ||||
| // Have fun.
 | ||||
| //
 | ||||
| // I really hate this function. Why isn't it depricated yet?
 | ||||
| // ========================================================
 | ||||
| /* ======================================================== */ | ||||
| /* Get the minimum braking distance. */ | ||||
| /* */ | ||||
| /* Braking vel ==> 0 = v - a*dt */ | ||||
| /* Add turn around time (to initial velocity) : */ | ||||
| /* ==> 180.*360./cur_pilot->turn */ | ||||
| /* Add it to general euler equation x = v*t + 0.5 * a * t^2 */ | ||||
| /* Have fun. */ | ||||
| /* */ | ||||
| /* I really hate this function. Why isn't it depricated yet? */ | ||||
| /* ======================================================== */ | ||||
| static int ai_minbrakedist(lua_State* L) { | ||||
|   double time, dist; | ||||
|   time = VMOD(cur_pilot->solid->vel) / | ||||
| @ -572,7 +572,7 @@ static int ai_minbrakedist(lua_State* L) { | ||||
|   dist = VMOD(cur_pilot->solid->vel)*0.9*(time+180./cur_pilot->turn) - | ||||
|       0.5 * (cur_pilot->thrust / cur_pilot->solid->mass)*time*time; | ||||
| 
 | ||||
|   lua_pushnumber(L, dist); // return
 | ||||
|   lua_pushnumber(L, dist); /* return */ | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| @ -591,19 +591,19 @@ static int ai_exists(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Are we at max velocity?
 | ||||
| /* Are we at max velocity? */ | ||||
| static int ai_ismaxvel(lua_State* L) { | ||||
|   lua_pushboolean(L,(VMOD(cur_pilot->solid->vel)>cur_pilot->speed-MIN_VEL_ERR)); | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Have we stopped?
 | ||||
| /* Have we stopped? */ | ||||
| static int ai_isstopped(lua_State* L) { | ||||
|   lua_pushboolean(L, VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR); | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Check if the pilot is an enemy.
 | ||||
| /* Check if the pilot is an enemy. */ | ||||
| static int ai_isenemy(lua_State* L) { | ||||
|   if(lua_isnumber(L,1)) | ||||
|     lua_pushboolean(L, areEnemies(cur_pilot->faction, | ||||
| @ -611,14 +611,14 @@ static int ai_isenemy(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Check if the pilot is an ally.
 | ||||
| /* Check if the pilot is an ally. */ | ||||
| static int ai_isally(lua_State* L) { | ||||
|   lua_pushboolean(L, areAllies(cur_pilot->faction, | ||||
|                                pilot_get(lua_tonumber(L,1))->faction)); | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Check to see if the pilot is in combat. Defaults to self.
 | ||||
| /* Check to see if the pilot is in combat. Defaults to self. */ | ||||
| static int ai_incombat(lua_State* L) { | ||||
|   Pilot* p; | ||||
| 
 | ||||
| @ -629,7 +629,7 @@ static int ai_incombat(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Accelerate the pilot based on a param.
 | ||||
| /* Accelerate the pilot based on a param. */ | ||||
| static int ai_accel(lua_State* L) { | ||||
|   double n; | ||||
| 
 | ||||
| @ -647,17 +647,17 @@ static int ai_accel(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Turn the pilot based on a param.
 | ||||
| /* Turn the pilot based on a param. */ | ||||
| static int ai_turn(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(1); | ||||
|   pilot_turn = (lua_isnumber(L, 1)) ? (double)lua_tonumber(L, 1) : 0.; | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Face the target.
 | ||||
| /* Face the target. */ | ||||
| static int ai_face(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(1); | ||||
|   Vec2* v, sv, tv; // Grab the position to face.
 | ||||
|   Vec2* v, sv, tv; /* Grab the position to face. */ | ||||
|   Pilot* p; | ||||
|   double mod, diff; | ||||
|   int invert = 0; | ||||
| @ -668,7 +668,7 @@ static int ai_face(lua_State* L) { | ||||
| 
 | ||||
|   if(n >= 0) { | ||||
|     p = pilot_get(n); | ||||
|     if(p == NULL) return 0; // Make sure pilot is valid.
 | ||||
|     if(p == NULL) return 0; /* Make sure pilot is valid. */ | ||||
|     vect_cset(&tv, VX(p->solid->pos) + FACE_WVEL*VX(p->solid->vel), | ||||
|               VY(p->solid->pos) + FACE_WVEL*VY(p->solid->vel)); | ||||
|     v = NULL; | ||||
| @ -682,12 +682,12 @@ static int ai_face(lua_State* L) { | ||||
|             VY(cur_pilot->solid->pos) + FACE_WVEL*VY(cur_pilot->solid->vel)); | ||||
| 
 | ||||
|   if(v == NULL) | ||||
|     // Target is dynamic.
 | ||||
|     /* Target is dynamic. */ | ||||
|     diff = angle_diff(cur_pilot->solid->dir, | ||||
|                       (n==-1) ? VANGLE(sv) : | ||||
|                                 vect_angle(&sv, &tv)); | ||||
|   else | ||||
|     // Target is static.
 | ||||
|     /* Target is static. */ | ||||
|     diff = angle_diff(cur_pilot->solid->dir, | ||||
|                       (n==-1) ? VANGLE(cur_pilot->solid->pos) : | ||||
|                                 vect_angle(&cur_pilot->solid->pos, v)); | ||||
| @ -699,9 +699,9 @@ static int ai_face(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // This is generally good for coming to a halt.
 | ||||
| /* This is generally good for coming to a halt. */ | ||||
| static int ai_brake(lua_State* L) { | ||||
|   (void)L; // Just a hack to avoid -W -Wall warnings.
 | ||||
|   (void)L; /* Just a hack to avoid -W -Wall warnings. */ | ||||
|   double diff, d; | ||||
| 
 | ||||
|   d = cur_pilot->solid->dir+M_PI; | ||||
| @ -715,34 +715,34 @@ static int ai_brake(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Return the nearest friendly planet's position to the pilot.
 | ||||
| /* Return the nearest friendly planet's position to the pilot. */ | ||||
| static int ai_getnearestplanet(lua_State* L) { | ||||
|   if(cur_system->nplanets == 0) return 0; // No planets.
 | ||||
|   if(cur_system->nplanets == 0) return 0; /* No planets. */ | ||||
| 
 | ||||
|   double dist, d; | ||||
|   int i, j; | ||||
| 
 | ||||
|   // Cycle through planets.
 | ||||
|   /* Cycle through planets. */ | ||||
|   for(dist = 0., j = -1, i = 0; i < cur_system->nplanets; i++) { | ||||
|     d = vect_dist(&cur_system->planets[i].pos, &cur_pilot->solid->pos); | ||||
|     if((!areEnemies(cur_pilot->faction, cur_system->planets[i].faction)) && | ||||
|        (d < dist)) { | ||||
|       // Closer friendly planet.
 | ||||
|       /* Closer friendly planet. */ | ||||
|       j = i; | ||||
|       dist = d; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // No friendly planet found.
 | ||||
|   /* No friendly planet found. */ | ||||
|   if(j == -1) return 0; | ||||
| 
 | ||||
|   lua_pushlightuserdata(L, &cur_system->planets[j].pos); | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Return a random friendly planet's position to the pilot.
 | ||||
| /* Return a random friendly planet's position to the pilot. */ | ||||
| static int ai_getrndplanet(lua_State* L) { | ||||
|   if(cur_system->nplanets == 0) return 0; // No planets.
 | ||||
|   if(cur_system->nplanets == 0) return 0; /* No planets. */ | ||||
| 
 | ||||
|   Planet** planets; | ||||
|   int nplanets, i; | ||||
| @ -754,13 +754,13 @@ static int ai_getrndplanet(lua_State* L) { | ||||
|        !areEnemies(cur_pilot->faction, cur_system->planets[i].faction)) | ||||
|       planets[nplanets++] = &cur_system->planets[i]; | ||||
| 
 | ||||
|   // No planet to land on found.
 | ||||
|   /* No planet to land on found. */ | ||||
|   if(nplanets == 0) { | ||||
|     free(planets); | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   // We can actually get a random planet now.
 | ||||
|   /* We can actually get a random planet now. */ | ||||
|   i = RNG(0,nplanets-1); | ||||
|   vectcpy(&v, &planets[i]->pos); | ||||
|   vect_cadd(&v, RNG(0, planets[i]->gfx_space->sw)-planets[i]->gfx_space->sw/2., | ||||
| @ -770,7 +770,7 @@ static int ai_getrndplanet(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Attempt to enter the pilot hyperspace. Return the distance if too far away.
 | ||||
| /* Attempt to enter the pilot hyperspace. Return the distance if too far away. */ | ||||
| static int ai_hyperspace(lua_State* L) { | ||||
|   int dist; | ||||
| 
 | ||||
| @ -781,9 +781,9 @@ static int ai_hyperspace(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Completely stop the pilot if it is below minimum vel error. (No instant stops.)
 | ||||
| /* Completely stop the pilot if it is below minimum vel error. (No instant stops.) */ | ||||
| static int ai_stop(lua_State* L) { | ||||
|   (void)L; // Just avoid a gcc warning.
 | ||||
|   (void)L; /* Just avoid a gcc warning. */ | ||||
| 
 | ||||
|   if(VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR) | ||||
|     vect_pset(&cur_pilot->solid->vel, 0., 0.); | ||||
| @ -791,7 +791,7 @@ static int ai_stop(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Toggle combat flag. Default is on.
 | ||||
| /* Toggle combat flag. Default is on. */ | ||||
| static int ai_combat(lua_State* L) { | ||||
|   int i; | ||||
| 
 | ||||
| @ -804,7 +804,7 @@ static int ai_combat(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Set the pilots target.
 | ||||
| /* Set the pilots target. */ | ||||
| static int ai_settarget(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(1); | ||||
| 
 | ||||
| @ -812,7 +812,7 @@ static int ai_settarget(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Set the secondary weapon. Biassed towards launchers..
 | ||||
| /* Set the secondary weapon. Biassed towards launchers.. */ | ||||
| static int ai_secondary(lua_State* L) { | ||||
|   if(cur_pilot->secondary) { | ||||
|     lua_pushstring(L, outfit_getTypeBroad(cur_pilot->secondary->outfit)); | ||||
| @ -844,7 +844,7 @@ static int ai_hasturrets(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Pew pew.. Says the pilot.
 | ||||
| /* Pew pew.. Says the pilot. */ | ||||
| static int ai_shoot(lua_State* L) { | ||||
|   int n = 1; | ||||
|   if(lua_isnumber(L, 1)) n = (int)lua_tonumber(L,1); | ||||
| @ -856,13 +856,13 @@ static int ai_shoot(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Get the nearest enemy.
 | ||||
| /* Get the nearest enemy. */ | ||||
| static int ai_getenemy(lua_State* L) { | ||||
|   lua_pushnumber(L,pilot_getNearest(cur_pilot)); | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Set the enemy hostile. (Simply notifies of an impending attack).
 | ||||
| /* Set the enemy hostile. (Simply notifies of an impending attack). */ | ||||
| static int ai_hostile(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(1); | ||||
| 
 | ||||
| @ -872,11 +872,11 @@ static int ai_hostile(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Set the timer.
 | ||||
| /* Set the timer. */ | ||||
| static int ai_settimer(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(2); | ||||
| 
 | ||||
|   int n; // Get the timer.
 | ||||
|   int n; /* Get the timer. */ | ||||
|   if(lua_isnumber(L, 1)) n = lua_tonumber(L,1); | ||||
| 
 | ||||
|   cur_pilot->timer[n] = (lua_isnumber(L,2)) ? | ||||
| @ -884,18 +884,18 @@ static int ai_settimer(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Check the timer.
 | ||||
| /* Check the timer. */ | ||||
| static int ai_timeup(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(1); | ||||
| 
 | ||||
|   int n; // Get the timer.
 | ||||
|   int n; /* Get the timer. */ | ||||
|   if(lua_isnumber(L,1)) n = lua_tonumber(L,1); | ||||
| 
 | ||||
|   lua_pushboolean(L, cur_pilot->timer[n] < SDL_GetTicks()); | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Have the pilot say something to player.
 | ||||
| /* Have the pilot say something to player. */ | ||||
| static int ai_comm(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(2); | ||||
| 
 | ||||
| @ -905,7 +905,7 @@ static int ai_comm(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Broadcasts to the entire area.
 | ||||
| /* Broadcasts to the entire area. */ | ||||
| static int ai_broadcast(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(1); | ||||
| 
 | ||||
| @ -915,7 +915,7 @@ static int ai_broadcast(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Set the pilots credits.
 | ||||
| /* Set the pilots credits. */ | ||||
| static int ai_credits(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(1); | ||||
|   if(ai_status != AI_STATUS_CREATE) return 0; | ||||
| @ -926,7 +926,7 @@ static int ai_credits(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Set the pilots cargo.
 | ||||
| /* Set the pilots cargo. */ | ||||
| static int ai_cargo(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(2); | ||||
|   if(ai_status != AI_STATUS_CREATE) return 0; | ||||
| @ -938,7 +938,7 @@ static int ai_cargo(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Get the pilot's ship value.
 | ||||
| /* Get the pilot's ship value. */ | ||||
| static int ai_shipprice(lua_State* L) { | ||||
|   lua_pushnumber(L, cur_pilot->ship->price); | ||||
|   return 1; | ||||
|  | ||||
							
								
								
									
										14
									
								
								src/ai.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/ai.h
									
									
									
									
									
								
							| @ -5,32 +5,32 @@ | ||||
| #define MAX_DIR_ERR 0.5*M_PI/180. | ||||
| #define MIN_VEL_ERR 5.0 | ||||
| 
 | ||||
| #define FACE_WVEL       0.1 // Weight of velocity compared to position to face.
 | ||||
| #define FACE_WVEL       0.1 /* Weight of velocity compared to position to face. */ | ||||
| 
 | ||||
| // Max number of AI timers.
 | ||||
| /* Max number of AI timers. */ | ||||
| #define MAX_AI_TIMERS 2 | ||||
| 
 | ||||
| typedef enum TaskData_ { TYPE_NULL, TYPE_INT, TYPE_PTR } TaskData; | ||||
| 
 | ||||
| // Basic task.
 | ||||
| /* Basic task. */ | ||||
| typedef struct Task_ { | ||||
|   struct Task_* next; | ||||
|   char* name; | ||||
| 
 | ||||
|   TaskData dtype; | ||||
|   union { | ||||
|     void* target; // Vec2 etc.
 | ||||
|     unsigned int ID; // Pilot ID etc.
 | ||||
|     void* target; /* Vec2 etc. */ | ||||
|     unsigned int ID; /* Pilot ID etc. */ | ||||
|   } dat; | ||||
| } Task; | ||||
| 
 | ||||
| // Ai profile.
 | ||||
| /* Ai profile. */ | ||||
| typedef struct AI_Profile_ { | ||||
|   char* name; | ||||
|   lua_State* L; | ||||
| } AI_Profile; | ||||
| 
 | ||||
| // Misc.
 | ||||
| /* Misc. */ | ||||
| AI_Profile* ai_getProfile(char* name); | ||||
| 
 | ||||
| int ai_init(void); | ||||
|  | ||||
							
								
								
									
										50
									
								
								src/base64.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								src/base64.c
									
									
									
									
									
								
							| @ -2,9 +2,9 @@ | ||||
| #include <string.h> | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| // Encode table - base64 alphabet is defined by the rfc
 | ||||
| /* Encode table - base64 alphabet is defined by the rfc */ | ||||
| static const char cb64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||||
| // Generate decode table at compile time.
 | ||||
| /* Generate decode table at compile time. */ | ||||
| #define B64(_)            \ | ||||
|   ((_) == 'A' ? 0         \ | ||||
|    : (_) == 'B' ? 1       \ | ||||
| @ -72,7 +72,7 @@ static const char cb64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx | ||||
|    : (_) == '/' ? 63      \ | ||||
|    : -1) | ||||
| 
 | ||||
| // Makes it much faster.
 | ||||
| /* Makes it much faster. */ | ||||
| static const signed char cd64[256] = { | ||||
|   B64(0),   B64(1),   B64(2),   B64(3), | ||||
|   B64(4),   B64(5),   B64(6),   B64(7), | ||||
| @ -140,34 +140,34 @@ static const signed char cd64[256] = { | ||||
|   B64(252), B64(253), B64(254), B64(255) | ||||
| }; | ||||
| 
 | ||||
| // Encode src of sz length storing the new length in len.
 | ||||
| /* Encode src of sz length storing the new length in len. */ | ||||
| char* base64_encode(size_t* len, char* src, size_t sz) { | ||||
|   char* r; | ||||
|   size_t i, c; | ||||
|   uint32_t n; | ||||
|   uint8_t ch[4], pad; | ||||
| 
 | ||||
|   // Create r.
 | ||||
|   /* Create r. */ | ||||
|   c = sz * 4 / 3 + sz % 3 + 2; | ||||
|   c += c / 76; | ||||
|   r = malloc(c * sizeof(char)); | ||||
| 
 | ||||
|   // Setup padding.
 | ||||
|   /* Setup padding. */ | ||||
|   pad = ((sz % 3) == 0) ? 0 : 3 - sz % 3; | ||||
| 
 | ||||
|   // Time to do the bulk of the work.
 | ||||
|   /* Time to do the bulk of the work. */ | ||||
|   i = 0; | ||||
|   for(c = 0; c < sz; c += 3) { | ||||
|     // Specification wants newline after every 76 characters.
 | ||||
|     /* Specification wants newline after every 76 characters. */ | ||||
|     if((c > 0) && ((c / 3 * 4) % 76 == 0)) | ||||
|       r[i++] = '\n'; | ||||
| 
 | ||||
|     // n is 24 bits.
 | ||||
|     /* n is 24 bits. */ | ||||
|     n =  (src[c] << 16); | ||||
|     n += (c+1<sz) ? (src[c+1] << 8) : 0;  // May be out of range.
 | ||||
|     n += (c+2<sz) ? (src[c+2] << 0) : 0;  // May be out of range.
 | ||||
|     n += (c+1<sz) ? (src[c+1] << 8) : 0;  /* May be out of range. */ | ||||
|     n += (c+2<sz) ? (src[c+2] << 0) : 0;  /* May be out of range. */ | ||||
| 
 | ||||
|     // ch[0-3] are 6 bits each.
 | ||||
|     /* ch[0-3] are 6 bits each. */ | ||||
|     ch[0] = (n >> 18) & 63; | ||||
|     ch[1] = (n >> 12) & 63; | ||||
|     ch[2] = (n >> 6)  & 63; | ||||
| @ -181,14 +181,14 @@ char* base64_encode(size_t* len, char* src, size_t sz) { | ||||
|    | ||||
|   for(c = 0; c < pad; c++) | ||||
|     r[i-c-1] = '='; | ||||
|   // It'll be a valid string.
 | ||||
|   /* It'll be a valid string. */ | ||||
|   r[i] = '\0'; | ||||
|   (*len) = i; | ||||
| 
 | ||||
|   return r; | ||||
| } | ||||
| 
 | ||||
| // Decode the buffer, same syntax as base64_encode.
 | ||||
| /* Decode the buffer, same syntax as base64_encode. */ | ||||
| #define dec_valid(inp)    (cd64[(int)inp] == -1) ? 0 : 1 | ||||
| #define dec_ch(inp)       cd64[(int)inp] | ||||
| 
 | ||||
| @ -197,43 +197,43 @@ char* base64_decode(size_t* len, char* src, size_t sz) { | ||||
|   size_t c, i, j; | ||||
|   uint32_t n; | ||||
| 
 | ||||
|   // Allocate r.
 | ||||
|   /* Allocate r. */ | ||||
|   c = sz * 3 / 4 + 2; | ||||
|   r = malloc(c * sizeof(char)); | ||||
| 
 | ||||
|   // Create a clean version of the text.
 | ||||
|   /* Create a clean version of the text. */ | ||||
|   pad = 0; | ||||
|   dat = malloc(sz * sizeof(char)); | ||||
|   j = 0; | ||||
|   for(i = 0; i < sz; i++) { | ||||
|     if(src[i] == '=') | ||||
|       // Control padding.
 | ||||
|       /* Control padding. */ | ||||
|       pad++; | ||||
|     if(dec_valid(src[i])) | ||||
|       // Only allow valid characters.
 | ||||
|       /* Only allow valid characters. */ | ||||
|       dat[j++] = src[i]; | ||||
|   } | ||||
| 
 | ||||
|   // Fill r.
 | ||||
|   /* Fill r. */ | ||||
|   i = 0; | ||||
|   for(c = 0; c < j; c += 4) { | ||||
|     // Process the input from base 64.
 | ||||
|     n = dec_ch(dat[c+0]) << 18; // Guaranteed to be valid.
 | ||||
|     n += (c+1<j) ? (dec_ch(dat[c+1]) << 12) : 0; // Check if in bounds.
 | ||||
|     /* Process the input from base 64. */ | ||||
|     n = dec_ch(dat[c+0]) << 18; /* Guaranteed to be valid. */ | ||||
|     n += (c+1<j) ? (dec_ch(dat[c+1]) << 12) : 0; /* Check if in bounds. */ | ||||
|     n += (c+2<j) ? (dec_ch(dat[c+2]) << 6) : 0; | ||||
|     n += (c+3<j) ? (dec_ch(dat[c+3]) << 0) : 0; | ||||
| 
 | ||||
|     // Convert the 24 bits of encoded data into 3 8 bit chunks.
 | ||||
|     /* Convert the 24 bits of encoded data into 3 8 bit chunks. */ | ||||
|     r[i++] = (n >> 16)  & 255; | ||||
|     r[i++] = (n >> 8)   & 255; | ||||
|     r[i++] = (n >> 0)   & 255; | ||||
| 
 | ||||
|   } | ||||
| 
 | ||||
|   // Cleanup.
 | ||||
|   /* Cleanup. */ | ||||
|   free(dat); | ||||
| 
 | ||||
|   (*len) = i - pad; // Must decount the padding.
 | ||||
|   (*len) = i - pad; /* Must decount the padding. */ | ||||
|   return r; | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										24
									
								
								src/board.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								src/board.c
									
									
									
									
									
								
							| @ -21,7 +21,7 @@ static void board_stealCargo(char* str); | ||||
| static int  board_fail(void); | ||||
| static void board_update(void); | ||||
| 
 | ||||
| // Attempt to board the players target.
 | ||||
| /* Attempt to board the players target. */ | ||||
| void player_board(void) { | ||||
|   Pilot* p; | ||||
| 
 | ||||
| @ -52,11 +52,11 @@ void player_board(void) { | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   // Pilot will be boarded.
 | ||||
|   /* Pilot will be boarded. */ | ||||
|   pilot_setFlag(p, PILOT_BOARDED); | ||||
|   player_message("Boarding ship %s", p->name); | ||||
| 
 | ||||
|   // Create the boarding window.
 | ||||
|   /* Create the boarding window. */ | ||||
|   board_wid = window_create("Boarding", -1, -1, BOARDING_WIDTH, BOARDING_HEIGHT); | ||||
| 
 | ||||
|   window_addText(board_wid, 20, -30, 120, 60, | ||||
| @ -91,7 +91,7 @@ static void board_stealCreds(char* str) { | ||||
|   p = pilot_get(player_target); | ||||
| 
 | ||||
|   if(p->credits == 0) { | ||||
|     // Can't steal from the poor. ;)
 | ||||
|     /* Can't steal from the poor. ;) */ | ||||
|     player_message("The ship has no SCreds."); | ||||
|     return; | ||||
|   } | ||||
| @ -100,7 +100,7 @@ static void board_stealCreds(char* str) { | ||||
| 
 | ||||
|   player->credits += p->credits; | ||||
|   p->credits = 0; | ||||
|   board_update(); // Update the lack of credits.
 | ||||
|   board_update(); /* Update the lack of credits. */ | ||||
|   player_message("You manage to steal the ship's Scred."); | ||||
| } | ||||
| 
 | ||||
| @ -112,7 +112,7 @@ static void board_stealCargo(char* str) { | ||||
|   p = pilot_get(player_target); | ||||
| 
 | ||||
|   if(p->ncommodities==0) { | ||||
|     // No cargo.
 | ||||
|     /* No cargo. */ | ||||
|     player_message("The ship has no cargo."); | ||||
|     return; | ||||
|   } | ||||
| @ -123,7 +123,7 @@ static void board_stealCargo(char* str) { | ||||
| 
 | ||||
|   if(board_fail()) return; | ||||
| 
 | ||||
|   // Steal as much as possible until full - TODO: Allow the player to choose.
 | ||||
|   /* Steal as much as possible until full - TODO: Allow the player to choose. */ | ||||
|   q = 1; | ||||
|   while((p->ncommodities > 0) && (q != 0)) { | ||||
|     q = pilot_addCargo(player, p->commodities[0].commodity, | ||||
| @ -136,30 +136,30 @@ static void board_stealCargo(char* str) { | ||||
|   player_message("You manage to steal the ship's cargo."); | ||||
| } | ||||
| 
 | ||||
| // Failed to board.
 | ||||
| /* Failed to board. */ | ||||
| static int board_fail(void) { | ||||
|   Pilot* p; | ||||
| 
 | ||||
|   p = pilot_get(player_target); | ||||
| 
 | ||||
|   // Fail chance.
 | ||||
|   /* Fail chance. */ | ||||
|   if(RNG(0, 100) > (int)(50. * | ||||
|                          (10. + (double)p->ship->crew/10.+(double)player->ship->crew))) | ||||
|     return 0; | ||||
| 
 | ||||
|   if(RNG(0, 2)==0) { | ||||
|     // 33% of instant death.
 | ||||
|     /* 33% of instant death. */ | ||||
|     p->armour = -1; | ||||
|     player_message("You have tripped the ship's self destruct mechanism!"); | ||||
|   } else | ||||
|     // You just got locked out!!
 | ||||
|     /* You just got locked out!! */ | ||||
|     player_message("The ship's security system locks you out!"); | ||||
| 
 | ||||
|   board_exit(NULL); | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Update the cargo and credit fields.
 | ||||
| /* Update the cargo and credit fields. */ | ||||
| static void board_update(void) { | ||||
|   int i; | ||||
|   char str[128], buf[32]; | ||||
|  | ||||
| @ -2,16 +2,16 @@ | ||||
| #include "log.h" | ||||
| #include "collision.h" | ||||
| 
 | ||||
| // Collide sprite at (asx, asy) int 'at' at pos 'ap' with sprite at (bsx,bsy)
 | ||||
| //in 'bt' at 'bp'
 | ||||
| // at   - Texture a.
 | ||||
| // asx  - Position of x of sprite a.
 | ||||
| // asy  - Position of y of sprite a.
 | ||||
| // ap   - Position in space of sprite a.
 | ||||
| // bt   - Texture b.
 | ||||
| // bsx  - Position of x of sprite b.
 | ||||
| // bsy  - Position of y of sprite b.
 | ||||
| // bp   - Position in space of sprite b.
 | ||||
| /* Collide sprite at (asx, asy) int 'at' at pos 'ap' with sprite at (bsx,bsy) */ | ||||
| /*in 'bt' at 'bp' */ | ||||
| /* at   - Texture a. */ | ||||
| /* asx  - Position of x of sprite a. */ | ||||
| /* asy  - Position of y of sprite a. */ | ||||
| /* ap   - Position in space of sprite a. */ | ||||
| /* bt   - Texture b. */ | ||||
| /* bsx  - Position of x of sprite b. */ | ||||
| /* bsy  - Position of y of sprite b. */ | ||||
| /* bp   - Position in space of sprite b. */ | ||||
| int CollideSprite(const glTexture* at, const int asx, const int asy, | ||||
|                   const Vec2* ap, const glTexture* bt, | ||||
|                   const int bsx, const int bsy, const Vec2* bp) { | ||||
| @ -23,33 +23,33 @@ int CollideSprite(const glTexture* at, const int asx, const int asy, | ||||
|   int rasy, rbsy; | ||||
|   int abx, aby, bbx, bby; | ||||
| 
 | ||||
|   // a - cube coords.
 | ||||
|   /* a - cube coords. */ | ||||
|   ax1 = (int)VX(*ap) - (int)(at->sw)/2; | ||||
|   ay1 = (int)VY(*ap) - (int)(at->sh)/2; | ||||
|   ax2 = ax1 + (int)(at->sw) - 1; | ||||
|   ay2 = ay1 + (int)(at->sh) - 1; | ||||
| 
 | ||||
|   // b - cube coords.
 | ||||
|   /* b - cube coords. */ | ||||
|   bx1 = (int)VX(*bp) - (int)(bt->sw)/2; | ||||
|   by1 = (int)VY(*bp) - (int)(bt->sh)/2; | ||||
|   bx2 = bx1 + (int)(bt->sw) - 1; | ||||
|   by2 = by1 + (int)(bt->sh) - 1; | ||||
| 
 | ||||
|   // Check if bounding boxes intersect.
 | ||||
|   /* Check if bounding boxes intersect. */ | ||||
|   if((bx2 < ax1) || (ax2 < bx1)) return 0; | ||||
|   if((by2 < ay1) || (ay2 < by1)) return 0; | ||||
| 
 | ||||
|   // Define the remaining binding box.
 | ||||
|   /* Define the remaining binding box. */ | ||||
|   inter_x0 = MAX(ax1, bx1); | ||||
|   inter_x1 = MIN(ax2, bx2); | ||||
|   inter_y0 = MAX(ay1, by1); | ||||
|   inter_y1 = MIN(ay2, by2); | ||||
| 
 | ||||
|   // Real vertical sprite value (flipped).
 | ||||
|   /* Real vertical sprite value (flipped). */ | ||||
|   rasy = at->sy - asy - 1; | ||||
|   rbsy = bt->sy - bsy - 1; | ||||
| 
 | ||||
|   // Set up the base points.
 | ||||
|   /* Set up the base points. */ | ||||
|   abx = asx*(int)(at->sw)   - ax1; | ||||
|   aby = rasy*(int)(at->sh)  - ay1; | ||||
|   bbx = bsx*(int)(bt->sw)   - bx1; | ||||
| @ -57,7 +57,7 @@ int CollideSprite(const glTexture* at, const int asx, const int asy, | ||||
| 
 | ||||
|   for(y = inter_y0; y <= inter_y1; y++) | ||||
|     for(x = inter_x0; x <= inter_x1; x++) | ||||
|       // Compute offsets for surface before passing to TransparentPixel test.
 | ||||
|       /* Compute offsets for surface before passing to TransparentPixel test. */ | ||||
|       if((!gl_isTrans(at, abx + x, aby + y)) && | ||||
|          (!gl_isTrans(bt, bbx + x, bby + y))) | ||||
|         return 1; | ||||
|  | ||||
							
								
								
									
										12
									
								
								src/colour.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/colour.c
									
									
									
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| #include "colour.h" | ||||
| 
 | ||||
| // Default colors.
 | ||||
| /* Default colors. */ | ||||
| glColour cWhite     = { .r = 1.00, .g = 1.00, .b = 1.00, .a = 1. }; | ||||
| glColour cGrey90    = { .r = 0.90, .g = 0.90, .b = 0.90, .a = 1. }; | ||||
| glColour cGrey80    = { .r = 0.80, .g = 0.80, .b = 0.80, .a = 1. }; | ||||
| @ -21,21 +21,21 @@ glColour cDarkBlue  = { .r = 0.10, .g = 0.20, .b = 0.80, .a = 1. }; | ||||
| glColour cBlue      = { .r = 0.20, .g = 0.20, .b = 0.80, .a = 1. }; | ||||
| glColour cPurple    = { .r = 0.90, .g = 0.10, .b = 0.90, .a = 1. }; | ||||
| 
 | ||||
| // Game specific.
 | ||||
| /* Game specific. */ | ||||
| glColour cConsole           = { .r = 0.1, .g = 0.9, .b = 0.1, .a = 1. }; | ||||
| glColour cDConsole          = { .r = 0.0, .g = 0.7, .b = 0.0, .a = 1. }; | ||||
| // Toolkit.
 | ||||
| /* Toolkit. */ | ||||
| glColour cHilight           = { .r = 0.1, .g = 0.9, .b = 0.1, .a = 0.3 }; | ||||
| // Objects
 | ||||
| /* Objects */ | ||||
| glColour cInert             = { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1. }; | ||||
| glColour cNeutral           = { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1. }; | ||||
| glColour cFriend            = { .r = 0.0, .g = 1.0, .b = 0.0, .a = 1. }; | ||||
| glColour cHostile           = { .r = 0.9, .g = 0.2, .b = 0.2, .a = 1. }; | ||||
| // Radar
 | ||||
| /* Radar */ | ||||
| glColour cRadar_player      = { .r = 0.4, .g = 0.8, .b = 0.4, .a = 1. }; | ||||
| glColour cRadar_targ        = { .r = 0.0, .g = 0.7, .b = 1.0, .a = 1. }; | ||||
| glColour cRadar_weap        = { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1. }; | ||||
| // Bars.
 | ||||
| /* Bars. */ | ||||
| glColour cShield            = { .r = 0.2, .g = 0.2, .b = 0.8, .a = 1. }; | ||||
| glColour cArmour            = { .r = 0.5, .g = 0.5, .b = 0.5, .a = 1. }; | ||||
| glColour cEnergy            = { .r = 0.2, .g = 0.8, .b = 0.2, .a = 1. }; | ||||
|  | ||||
							
								
								
									
										18
									
								
								src/colour.h
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/colour.h
									
									
									
									
									
								
							| @ -1,17 +1,17 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| // Colours.
 | ||||
| /* Colours. */ | ||||
| typedef struct glColour_ { | ||||
|   double r, g, b, a; | ||||
| } glColour; | ||||
| 
 | ||||
| // Default colors.
 | ||||
| // -- Greyscale.
 | ||||
| /* Default colors. */ | ||||
| /* -- Greyscale. */ | ||||
| extern glColour cWhite; | ||||
| #define cGrey   cGrey70 | ||||
| extern glColour cBlack; | ||||
| 
 | ||||
| // Greys
 | ||||
| /* Greys */ | ||||
| extern glColour cGrey90; | ||||
| extern glColour cGrey80; | ||||
| extern glColour cGrey70; | ||||
| @ -30,21 +30,21 @@ extern glColour cDarkBlue; | ||||
| extern glColour cBlue; | ||||
| extern glColour cPurple; | ||||
| 
 | ||||
| // Game specific.
 | ||||
| /* Game specific. */ | ||||
| extern glColour cConsole; | ||||
| extern glColour cDConsole; | ||||
| // Toolkit.
 | ||||
| /* Toolkit. */ | ||||
| extern glColour cHilight; | ||||
| // Objects.
 | ||||
| /* Objects. */ | ||||
| extern glColour cInert; | ||||
| extern glColour cNeutral; | ||||
| extern glColour cFriend; | ||||
| extern glColour cHostile; | ||||
| // Radar.
 | ||||
| /* Radar. */ | ||||
| extern glColour cRadar_player; | ||||
| extern glColour cRadar_targ; | ||||
| extern glColour cRadar_weap; | ||||
| // Health.
 | ||||
| /* Health. */ | ||||
| extern glColour cShield; | ||||
| extern glColour cArmour; | ||||
| extern glColour cEnergy; | ||||
|  | ||||
							
								
								
									
										64
									
								
								src/conf.c
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								src/conf.c
									
									
									
									
									
								
							| @ -44,20 +44,20 @@ | ||||
|   lua_remove(L, -1); \ | ||||
|   } | ||||
| 
 | ||||
| // Some crap from main.
 | ||||
| /* Some crap from main. */ | ||||
| extern int nosound; | ||||
| extern int show_fps; | ||||
| extern int max_fps; | ||||
| extern int indjoystick; | ||||
| extern char* namjoystick; | ||||
| // From player.c
 | ||||
| extern const char* keybindNames[]; // Keybindings.
 | ||||
| // input.c.
 | ||||
| /* From player.c */ | ||||
| extern const char* keybindNames[]; /* Keybindings. */ | ||||
| /* input.c. */ | ||||
| extern unsigned int input_afterburnSensibility; | ||||
| 
 | ||||
| static void print_usage(char** argv); | ||||
| 
 | ||||
| // Print usage.
 | ||||
| /* Print usage. */ | ||||
| static void print_usage(char** argv) { | ||||
|   LOG("USAGE: %s [OPTION]", argv[0]); | ||||
|   LOG("Options are:"); | ||||
| @ -75,35 +75,35 @@ static void print_usage(char** argv) { | ||||
|   LOG(" -v                     - Print the version and exit"); | ||||
| } | ||||
| 
 | ||||
| // Set the default configuration.
 | ||||
| /* Set the default configuration. */ | ||||
| void conf_setDefaults(void) { | ||||
|   // Global.
 | ||||
|   /* Global. */ | ||||
|   data = DATA_DEF; | ||||
|   // GL.
 | ||||
|   /* GL. */ | ||||
|   gl_screen.w = 800; | ||||
|   gl_screen.h = 600; | ||||
|   gl_screen.flags = 0; | ||||
|   // Openal.
 | ||||
|   /* Openal. */ | ||||
|   nosound = 0; | ||||
|   // Joystick.
 | ||||
|   /* Joystick. */ | ||||
|   indjoystick = -1; | ||||
|   namjoystick = NULL; | ||||
|   // Input.
 | ||||
|   /* Input. */ | ||||
|   input_setDefault(); | ||||
| } | ||||
| 
 | ||||
| // Ok.. Parse a config file plox.
 | ||||
| /* Ok.. Parse a config file plox. */ | ||||
| int conf_loadConfig(const char* file) { | ||||
|   int i = 0; | ||||
|   double d = 0.; | ||||
| 
 | ||||
|   lua_State* L = luaL_newstate(); | ||||
|   if(luaL_dofile(L, file) == 0) { | ||||
|     // Conf file exists indeed.
 | ||||
|     // Global.
 | ||||
|     /* Conf file exists indeed. */ | ||||
|     /* Global. */ | ||||
|     conf_loadString("data", data); | ||||
| 
 | ||||
|     // OpenGL properties..
 | ||||
|     /* OpenGL properties.. */ | ||||
|     conf_loadInt("width", gl_screen.w); | ||||
|     conf_loadInt("height", gl_screen.h); | ||||
|     conf_loadBool("fullscreen", i); | ||||
| @ -120,14 +120,14 @@ int conf_loadConfig(const char* file) { | ||||
|     conf_loadBool("aa_polygon", i); | ||||
|     if(i) { gl_screen.flags |= OPENGL_AA_POLYGON; i = 0; } | ||||
| 
 | ||||
|     // FPS.
 | ||||
|     /* FPS. */ | ||||
|     conf_loadBool("showfps", show_fps); | ||||
|     conf_loadInt("maxfps", max_fps); | ||||
| 
 | ||||
|     // Input.
 | ||||
|     /* Input. */ | ||||
|     conf_loadInt("afterburn", input_afterburnSensibility); | ||||
| 
 | ||||
|     // Sound.
 | ||||
|     /* Sound. */ | ||||
|     conf_loadBool("nosound", i); | ||||
|     nosound = i; i = 0; | ||||
|     conf_loadFloat("sound", d); | ||||
| @ -135,7 +135,7 @@ int conf_loadConfig(const char* file) { | ||||
|     conf_loadFloat("music", d); | ||||
|     if(d) { music_volume(d); d = 0.; } | ||||
| 
 | ||||
|     // Joystick.
 | ||||
|     /* Joystick. */ | ||||
|     lua_getglobal(L, "joystick"); | ||||
|     if(lua_isnumber(L, -1)) { | ||||
|       indjoystick = (int)lua_tonumber(L, -1); | ||||
| @ -146,7 +146,7 @@ int conf_loadConfig(const char* file) { | ||||
|       lua_remove(L, -1); | ||||
|     } | ||||
| 
 | ||||
|     // If there are any keybindings. Grab them.
 | ||||
|     /* If there are any keybindings. Grab them. */ | ||||
|     char* str; | ||||
|     int type, key, reverse; | ||||
|     for(i = 0; strcmp(keybindNames[i], "end"); i++) { | ||||
| @ -155,26 +155,26 @@ int conf_loadConfig(const char* file) { | ||||
|       key = -1; | ||||
|       reverse = 0; | ||||
|       if(lua_istable(L, -1)) { | ||||
|         // It's a gawd damn table!!
 | ||||
|         /* It's a gawd damn table!! */ | ||||
|         lua_pushstring(L, "type"); | ||||
|         lua_gettable(L, -2); | ||||
|         if(lua_isstring(L, -1)) | ||||
|           str = (char*)lua_tostring(L, -1); | ||||
| 
 | ||||
|         // Get the key.
 | ||||
|         /* Get the key. */ | ||||
|         lua_pushstring(L, "key"); | ||||
|         lua_gettable(L, -3); | ||||
|         if(lua_isnumber(L, -1)) | ||||
|           key = (int)lua_tonumber(L, -1); | ||||
| 
 | ||||
|         // Is it reversed? Only used for axis.
 | ||||
|         /* Is it reversed? Only used for axis. */ | ||||
|         lua_pushstring(L, "reverse"); | ||||
|         lua_gettable(L, -4); | ||||
|         if(lua_isnumber(L, -1)) | ||||
|           reverse = 1; | ||||
| 
 | ||||
|         if(key != -1 && str != NULL) { | ||||
|           // Then the keybind is valid. Get the type.
 | ||||
|           /* Then the keybind is valid. Get the type. */ | ||||
|           if(strcmp(str, "null")==0)            type = KEYBIND_NULL; | ||||
|           else if(strcmp(str, "keyboard")==0)   type = KEYBIND_KEYBOARD; | ||||
|           else if(strcmp(str, "jaxis")==0)      type = KEYBIND_JAXIS; | ||||
| @ -183,12 +183,12 @@ int conf_loadConfig(const char* file) { | ||||
|             WARN("Unknown keybinding of type %s", str); | ||||
|             continue; | ||||
|           } | ||||
|           // Set the keybind.
 | ||||
|           /* Set the keybind. */ | ||||
|           input_setKeybind((char*)keybindNames[i], type, key, reverse); | ||||
|         } else | ||||
|           WARN("Malformed keybind in %s", file); | ||||
| 
 | ||||
|         // Clean up after table crap.
 | ||||
|         /* Clean up after table crap. */ | ||||
|         lua_remove(L,-1); | ||||
|         lua_remove(L,-1); | ||||
|         lua_remove(L,-1); | ||||
| @ -196,7 +196,7 @@ int conf_loadConfig(const char* file) { | ||||
|       } | ||||
|     } | ||||
|   } else { | ||||
|     // Failed to load the config file..
 | ||||
|     /* Failed to load the config file.. */ | ||||
|     DEBUG("Config file '%s' not found.", file); | ||||
|     lua_close(L); | ||||
|     return 1; | ||||
| @ -205,7 +205,7 @@ int conf_loadConfig(const char* file) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Parse some CLI options.
 | ||||
| /* Parse some CLI options. */ | ||||
| void conf_parseCLI(int argc, char** argv) { | ||||
|   static struct option long_options[] = { | ||||
|     { "fullscreen",     no_argument,        0,  'f' }, | ||||
| @ -262,8 +262,8 @@ void conf_parseCLI(int argc, char** argv) { | ||||
|       sound_volume(atof(optarg)); | ||||
|       break; | ||||
|     case 'v': | ||||
|       // By now it has already displayed the version.
 | ||||
|       //LOG(APPNAME": version %d.%d.%d", VMAJOR, VMINOR, VREV);
 | ||||
|       /* By now it has already displayed the version. */ | ||||
|       /*LOG(APPNAME": version %d.%d.%d", VMAJOR, VMINOR, VREV); */ | ||||
|       exit(EXIT_SUCCESS); | ||||
|     case 'h': | ||||
|       print_usage(argv); | ||||
| @ -272,9 +272,9 @@ void conf_parseCLI(int argc, char** argv) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Saves the current configuration.
 | ||||
| /* Saves the current configuration. */ | ||||
| int conf_saveConfig(void) { | ||||
|   // TODO:
 | ||||
|   /* TODO: */ | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| // Loading.
 | ||||
| /* Loading. */ | ||||
| void conf_setDefaults(void); | ||||
| int conf_loadConfig(const char* file); | ||||
| void conf_parseCLI(int argc, char** argv); | ||||
| 
 | ||||
| // Saving.
 | ||||
| /* Saving. */ | ||||
| int conf_saveConfig(void); | ||||
| 
 | ||||
|  | ||||
| @ -8,19 +8,19 @@ | ||||
| #include "log.h" | ||||
| #include "economy.h" | ||||
| 
 | ||||
| #define XML_COMMODITY_ID  "Commodities" // XML section identifier.
 | ||||
| #define XML_COMMODITY_ID  "Commodities" /* XML section identifier. */ | ||||
| #define XML_COMMODITY_TAG  "commodity" | ||||
| #define COMMODITY_DATA   "../dat/commodity.xml" | ||||
| 
 | ||||
| // Commodity stack.
 | ||||
| /* Commodity stack. */ | ||||
| static Commodity* commodity_stack = NULL; | ||||
| static int commodity_nstack = 0; | ||||
| 
 | ||||
| static void commodity_freeOne(Commodity* com); | ||||
| static Commodity* commodity_parse(xmlNodePtr parent); | ||||
| 
 | ||||
| // Convert credits to a usable string for displaying.
 | ||||
| // str must have 10 characters allocated.
 | ||||
| /* Convert credits to a usable string for displaying. */ | ||||
| /* str must have 10 characters allocated. */ | ||||
| void credits2str(char* str, unsigned int credits, int decimals) { | ||||
|   if(decimals < 0) | ||||
|     snprintf(str, 32, "%d", credits); | ||||
| @ -33,7 +33,7 @@ void credits2str(char* str, unsigned int credits, int decimals) { | ||||
|   else snprintf(str, 16, "%d", credits); | ||||
| } | ||||
| 
 | ||||
| // Get a commodity.
 | ||||
| /* Get a commodity. */ | ||||
| Commodity* commodity_get(const char* name) { | ||||
|   int i; | ||||
|   for(i = 0; i < commodity_nstack; i++) | ||||
| @ -44,7 +44,7 @@ Commodity* commodity_get(const char* name) { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| // Free a commodity.
 | ||||
| /* Free a commodity. */ | ||||
| static void commodity_freeOne(Commodity* com) { | ||||
|   if(com->name) free(com->name); | ||||
|   if(com->description) free(com->description); | ||||
| @ -70,7 +70,7 @@ static Commodity* commodity_parse(xmlNodePtr parent) { | ||||
|     else if(xml_isNode(node, "low")) | ||||
|       tmp->low = xml_getInt(node); | ||||
|   } while((node = node->next)); | ||||
| #if 0 // Let's kill this for now.
 | ||||
| #if 0 /* Let's kill this for now. */
 | ||||
| #define MELEMENT(o,s)if(o)WARN("Commodity '%s' missing '"s"' element",tmp->name) | ||||
|   MELEMENT(tmp->high==0,        "high"); | ||||
|   MELEMENT(tmp->description==NULL,   "description"); | ||||
| @ -91,14 +91,14 @@ int commodity_load(void) { | ||||
| 
 | ||||
|   Commodity* tmp = NULL; | ||||
| 
 | ||||
|   node = doc->xmlChildrenNode; // Commoditys node.
 | ||||
|   node = doc->xmlChildrenNode; /* Commoditys node. */ | ||||
|   if(strcmp((char*)node->name, XML_COMMODITY_ID)) { | ||||
|     ERR("Malformed "COMMODITY_DATA | ||||
|         " file: Missing root element '"XML_COMMODITY_ID"'"); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   node = node->xmlChildrenNode; // First faction node.
 | ||||
|   node = node->xmlChildrenNode; /* First faction node. */ | ||||
|   if(node == NULL) { | ||||
|     ERR("Malformed "COMMODITY_DATA" file: does not contain elements"); | ||||
|     return -1; | ||||
|  | ||||
| @ -3,14 +3,14 @@ | ||||
| typedef struct Commodity_ { | ||||
|   char* name; | ||||
|   char* description; | ||||
|   int low, medium, high; // Prices.
 | ||||
|   int low, medium, high; /* Prices. */ | ||||
| } Commodity; | ||||
| 
 | ||||
| // Commidity stuff.
 | ||||
| /* Commidity stuff. */ | ||||
| Commodity* commodity_get(const char* name); | ||||
| int commodity_load(void); | ||||
| void commodity_free(void); | ||||
| 
 | ||||
| // Misc.
 | ||||
| /* Misc. */ | ||||
| void credits2str(char* str, unsigned int credits, int decimals); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										122
									
								
								src/faction.c
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								src/faction.c
									
									
									
									
									
								
							| @ -7,7 +7,7 @@ | ||||
| #include "xml.h" | ||||
| #include "faction.h" | ||||
| 
 | ||||
| #define XML_FACTION_ID    "Factions" // XML section id.
 | ||||
| #define XML_FACTION_ID    "Factions" /* XML section id. */ | ||||
| #define XML_FACTION_TAG   "faction" | ||||
| #define XML_ALLIANCE_ID   "Alliances" | ||||
| #define XML_ALLIANCE_TAG  "alliance" | ||||
| @ -16,9 +16,9 @@ | ||||
| 
 | ||||
| #define FACTION_DATA "../dat/faction.xml" | ||||
| 
 | ||||
| #define PLAYER_ALLY   70 // Above this, player is considered ally.
 | ||||
| #define PLAYER_ALLY   70 /* Above this, player is considered ally. */ | ||||
| 
 | ||||
| #define ALLIANCE_OFFSET 27182 // Special offset for alliances.
 | ||||
| #define ALLIANCE_OFFSET 27182 /* Special offset for alliances. */ | ||||
| 
 | ||||
| typedef struct Faction_ { | ||||
|   char* name; | ||||
| @ -28,33 +28,33 @@ typedef struct Faction_ { | ||||
|   int*  allies; | ||||
|   int   nallies; | ||||
| 
 | ||||
|   int player; // Standing with player - from -100 to 100.
 | ||||
|   int player; /* Standing with player - from -100 to 100. */ | ||||
| } Faction; | ||||
| 
 | ||||
| static Faction* faction_stack = NULL; | ||||
| static int nfactions = 0; | ||||
| 
 | ||||
| // Save alliance.
 | ||||
| /* Save alliance. */ | ||||
| typedef struct Alliance_ { | ||||
|   char* name; | ||||
|   int* factions; | ||||
|   int nfactions; | ||||
| } Alliance; | ||||
| 
 | ||||
| // Stack of alliances.
 | ||||
| /* Stack of alliances. */ | ||||
| static Alliance* alliances = NULL; | ||||
| static int nalliances = 0; | ||||
| 
 | ||||
| // Static.
 | ||||
| /* Static. */ | ||||
| static Faction* faction_parse(xmlNodePtr parent); | ||||
| static void alliance_parse(xmlNodePtr parent); | ||||
| static void enemies_parse(xmlNodePtr parent); | ||||
| static Alliance* alliance_get(char* name); | ||||
| // Extern.
 | ||||
| /* Extern. */ | ||||
| int pfaction_save(xmlTextWriterPtr writer); | ||||
| int pfaction_load(xmlNodePtr parent); | ||||
| 
 | ||||
| // Return the faction of name "name".
 | ||||
| /* Return the faction of name "name". */ | ||||
| int faction_get(const char* name) { | ||||
|   int i; | ||||
|   for(i = 0; i < nfactions; i++) | ||||
| @ -68,7 +68,7 @@ int faction_get(const char* name) { | ||||
|   return -1; | ||||
| } | ||||
| 
 | ||||
| // Return the id of an alliance.
 | ||||
| /* Return the id of an alliance. */ | ||||
| int faction_getAlliance(char* name) { | ||||
|   int i; | ||||
|   for(i = 0; i < nalliances; i++) | ||||
| @ -85,7 +85,7 @@ char* faction_name(int f) { | ||||
|   return faction_stack[f].name; | ||||
| } | ||||
| 
 | ||||
| // Return the alliance of name 'name'.
 | ||||
| /* Return the alliance of name 'name'. */ | ||||
| static Alliance* alliance_get(char* name) { | ||||
|   int i; | ||||
|   for(i = 0; i < nalliances; i++) | ||||
| @ -118,14 +118,14 @@ int faction_getPlayer(int f) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Return 1 if Faction a and b are enemies.
 | ||||
| /* Return 1 if Faction a and b are enemies. */ | ||||
| int areEnemies(int a, int b) { | ||||
|   Faction* fa, *fb; | ||||
|   int i = 0; | ||||
|    | ||||
|   if(a == b) return 0; // Luckily our factions aren't masochistic.
 | ||||
|   if(a == b) return 0; /* Luckily our factions aren't masochistic. */ | ||||
| 
 | ||||
|   // Player handled seperately.
 | ||||
|   /* Player handled seperately. */ | ||||
|   if(a == FACTION_PLAYER) { | ||||
|     if(faction_isFaction(b)) { | ||||
|       if(faction_stack[b].player < 0) | ||||
| @ -147,24 +147,24 @@ int areEnemies(int a, int b) { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Handle a.
 | ||||
|   /* Handle a. */ | ||||
|   if(faction_isFaction(a)) fa = &faction_stack[a]; | ||||
|   else { | ||||
|     // a isn't valid.
 | ||||
|     /* a isn't valid. */ | ||||
|     DEBUG("areEnemies: %d is an invalid faction/alliance", a); | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   // Handle b.
 | ||||
|   /* Handle b. */ | ||||
|   if(faction_isFaction(b)) fb = &faction_stack[b]; | ||||
|   else { | ||||
|     // b isn't valid.
 | ||||
|     /* b isn't valid. */ | ||||
|     DEBUG("areEnemies: %d is an invalid faction/alliance", b); | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   if(fa && fb) { | ||||
|     // Both are factions.
 | ||||
|     /* Both are factions. */ | ||||
|     for(i = 0; i < fa->nenemies; i++) | ||||
|       if(fa->enemies[i] == b) | ||||
|         return 1; | ||||
| @ -175,12 +175,12 @@ int areEnemies(int a, int b) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Return 1 if Faction a and b are allies.
 | ||||
| /* Return 1 if Faction a and b are allies. */ | ||||
| int areAllies(int a, int b) { | ||||
|   Faction* fa, *fb; | ||||
|   int i; | ||||
| 
 | ||||
|   // We assume player becomes allies with high rating.
 | ||||
|   /* We assume player becomes allies with high rating. */ | ||||
|   if(a == FACTION_PLAYER) { | ||||
|     if(faction_isFaction(b)) { | ||||
|       if(faction_stack[b].player > PLAYER_ALLY) return 1; | ||||
| @ -200,22 +200,22 @@ int areAllies(int a, int b) { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // D'aww. Player has no allies.
 | ||||
|   /* D'aww. Player has no allies. */ | ||||
|   if((a == FACTION_PLAYER) || (b == FACTION_PLAYER)) | ||||
|     return 0; | ||||
| 
 | ||||
|   // Handle a.
 | ||||
|   /* Handle a. */ | ||||
|   if(faction_isFaction(a)) fa = &faction_stack[a]; | ||||
|   else { | ||||
|     // b isn't valid.
 | ||||
|     /* b isn't valid. */ | ||||
|     DEBUG("%d is an invalid faction/alliance", a); | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   // Handle b.
 | ||||
|   /* Handle b. */ | ||||
|   if(faction_isFaction(b)) fb = &faction_stack[b]; | ||||
|   else { | ||||
|     // b isn't valid.
 | ||||
|     /* b isn't valid. */ | ||||
|     DEBUG("%d is an invalid faction/alliance", b); | ||||
|     return 0; | ||||
|   } | ||||
| @ -223,7 +223,7 @@ int areAllies(int a, int b) { | ||||
|   if(a == b) return 0; | ||||
|    | ||||
|   if(fa && fb) { | ||||
|     // Both are factions.
 | ||||
|     /* Both are factions. */ | ||||
|     for(i = 0; i < fa->nallies; i++) | ||||
|       if(fa->allies[i] == b) | ||||
|         return 1; | ||||
| @ -235,7 +235,7 @@ int areAllies(int a, int b) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Is faction f part of alliance a?
 | ||||
| /* Is faction f part of alliance a? */ | ||||
| int faction_ofAlliance(int f, int a) { | ||||
|   int i; | ||||
|   Alliance* aa; | ||||
| @ -259,7 +259,7 @@ int faction_ofAlliance(int f, int a) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Return true if a s an alliance.
 | ||||
| /* Return true if a s an alliance. */ | ||||
| int faction_isAlliance(int a) { | ||||
|   if((a < ALLIANCE_OFFSET) || (a >= ALLIANCE_OFFSET + nalliances)) | ||||
|     return 0; | ||||
| @ -267,14 +267,14 @@ int faction_isAlliance(int a) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Return true if f is a faction.
 | ||||
| /* Return true if f is a faction. */ | ||||
| int faction_isFaction(int f) { | ||||
|   if((f < 0) || (f >= nfactions)) | ||||
|     return 0; | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Parses a single faction, but does not set the allies/enemies.
 | ||||
| /* Parses a single faction, but does not set the allies/enemies. */ | ||||
| static Faction* faction_parse(xmlNodePtr parent) { | ||||
|   xmlNodePtr node; | ||||
|   int player; | ||||
| @ -300,7 +300,7 @@ static Faction* faction_parse(xmlNodePtr parent) { | ||||
|   return tmp; | ||||
| } | ||||
| 
 | ||||
| // We set allies/enemies here, in the faction_stack.
 | ||||
| /* We set allies/enemies here, in the faction_stack. */ | ||||
| static void alliance_parse(xmlNodePtr parent) { | ||||
|   Alliance* a; | ||||
|   int* i, j, n, m; | ||||
| @ -312,22 +312,22 @@ static void alliance_parse(xmlNodePtr parent) { | ||||
|   do { | ||||
|     if((node->type == XML_NODE_START) && (strcmp((char*)node->name, | ||||
|                                                  XML_ALLIANCE_TAG)==0)) { | ||||
|       // Allocate a new alliance.
 | ||||
|       /* Allocate a new alliance. */ | ||||
|       alliances = realloc(alliances, sizeof(Alliance)*(++nalliances)); | ||||
|       alliances[nalliances-1].name = (char*)xmlGetProp(node,(xmlChar*)"name"); | ||||
|       alliances[nalliances-1].factions = NULL; | ||||
|       alliances[nalliances-1].nfactions = 0; | ||||
| 
 | ||||
|       // Parse the current alliance's allies.
 | ||||
|       /* Parse the current alliance's allies. */ | ||||
|       cur = node->xmlChildrenNode; | ||||
|       do { | ||||
|         if(strcmp((char*)cur->name, "ally")==0) { | ||||
|           // Add the faction (and pointers to make things simple).
 | ||||
|           /* Add the faction (and pointers to make things simple). */ | ||||
|           a = alliances + nalliances-1; | ||||
|           i = &a->nfactions; | ||||
|           (*i)++; | ||||
| 
 | ||||
|           // Load the faction.
 | ||||
|           /* Load the faction. */ | ||||
|           a->factions = realloc(a->factions, (*i)*sizeof(int)); | ||||
|           a->factions[(*i)-1] = faction_get((char*)cur->children->content); | ||||
| 
 | ||||
| @ -337,13 +337,13 @@ static void alliance_parse(xmlNodePtr parent) { | ||||
|         } | ||||
|       } while((cur = cur->next)); | ||||
| 
 | ||||
|       // Set the crap needed by faction_stack.
 | ||||
|       /* Set the crap needed by faction_stack. */ | ||||
|       for(j = 0; j < (*i); j++) { | ||||
|         ft = &faction_stack[a->factions[j]]; | ||||
|         ft->nallies += (*i)-1; | ||||
|         ft->allies = realloc(ft->allies, (ft->nallies)*sizeof(int)); | ||||
|         for(n = 0, m = 0; n < (*i); n++, m++) { | ||||
|           // Add as ally for all factions exept self.
 | ||||
|           /* Add as ally for all factions exept self. */ | ||||
|           if(n == j) m--; | ||||
|           else if(n != j) | ||||
|             ft->allies[ft->nallies-(*i)+1+m] = a->factions[n]; | ||||
| @ -380,7 +380,7 @@ static void enemies_parse(xmlNodePtr parent) { | ||||
|           f = realloc(f, sizeof(int*)*i); | ||||
| 
 | ||||
|           if(strcmp(type, "alliance")==0) { | ||||
|             // Enemy thing is an alliance.
 | ||||
|             /* Enemy thing is an alliance. */ | ||||
|             a = alliance_get((char*)cur->children->content); | ||||
|             if(a == NULL) | ||||
|               WARN("Alliance %s not found in stack", | ||||
| @ -389,7 +389,7 @@ static void enemies_parse(xmlNodePtr parent) { | ||||
|             f[i-1] = a->factions; | ||||
|           } | ||||
|           else if(strcmp(type,"faction")==0) { | ||||
|             // Enemy thing is only a faction.
 | ||||
|             /* Enemy thing is only a faction. */ | ||||
|             j[i-1] = 1; | ||||
|             f[i-1] = malloc(sizeof(int)); | ||||
|             f[i-1][0] = faction_get((char*)cur->children->content); | ||||
| @ -400,38 +400,38 @@ static void enemies_parse(xmlNodePtr parent) { | ||||
|           free(type); | ||||
|         } | ||||
|       } while((cur = cur->next)); | ||||
|       // Now actually parse and load up the enemies.
 | ||||
|       for(n = 0; n < i; n++) {        // Unsinged int.
 | ||||
|         for(m = 0; m < j[n]; m++) {   // Unsigned int.
 | ||||
|           // Faction.
 | ||||
|           // Add all the faction enemies to nenemies and alloc.
 | ||||
|       /* Now actually parse and load up the enemies. */ | ||||
|       for(n = 0; n < i; n++) {        /* Unsinged int. */ | ||||
|         for(m = 0; m < j[n]; m++) {   /* Unsigned int. */ | ||||
|           /* Faction. */ | ||||
|           /* Add all the faction enemies to nenemies and alloc. */ | ||||
|           for(e = 0, x = 0; x < i; x++) | ||||
|             if(x != n) e += j[x]; // Store the total enemies.
 | ||||
|           // Now allocate the memory.
 | ||||
|             if(x != n) e += j[x]; /* Store the total enemies. */ | ||||
|           /* Now allocate the memory. */ | ||||
|           ft = &faction_stack[f[n][m]]; | ||||
|           ft->nenemies += e; | ||||
|           ft->enemies = realloc(ft->enemies, sizeof(int)*ft->nenemies); | ||||
| 
 | ||||
|           // Add the actualy enemies.
 | ||||
|           /* Add the actualy enemies. */ | ||||
|           for(x = 0, z = 0; x < i; x++) | ||||
|             if(x != n) | ||||
|               // Make sure it's not from the same group.
 | ||||
|               /* Make sure it's not from the same group. */ | ||||
|               if(x != n) | ||||
|                 for(y = 0; y < j[x]; y++, z++) | ||||
|                   ft->enemies[ft->nenemies-e+z] = f[x][y]; | ||||
|         } | ||||
|       } | ||||
|       // Free al the temp memory.
 | ||||
|       /* Free al the temp memory. */ | ||||
|       for(x = 0; x < i; x++) | ||||
|         if(j[x]==1) free(f[x]); // Free the single malloced factions.
 | ||||
|       free(f); // Free the rest.
 | ||||
|         if(j[x]==1) free(f[x]); /* Free the single malloced factions. */ | ||||
|       free(f); /* Free the rest. */ | ||||
|       free(j); | ||||
|     } | ||||
|   } while((node = node->next)); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Load all the factions.
 | ||||
| /* Load all the factions. */ | ||||
| int factions_load(void) { | ||||
|   uint32_t bufsize; | ||||
|   char* buf = pack_readfile(DATA, FACTION_DATA, &bufsize); | ||||
| @ -441,19 +441,19 @@ int factions_load(void) { | ||||
| 
 | ||||
|   Faction* tmp = NULL; | ||||
| 
 | ||||
|   node = doc->xmlChildrenNode; // Faction node.
 | ||||
|   node = doc->xmlChildrenNode; /* Faction node. */ | ||||
|   if(!xml_isNode(node, XML_FACTION_ID)) { | ||||
|     ERR("Malformed "FACTION_DATA" file: missing root element '"XML_FACTION_ID"'"); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   node = node->xmlChildrenNode; // First faction node.
 | ||||
|   node = node->xmlChildrenNode; /* First faction node. */ | ||||
|   if(node == NULL) { | ||||
|     ERR("Malformed "FACTION_DATA" file: does not contain elements"); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   // Player faction is hardcoded.
 | ||||
|   /* Player faction is hardcoded. */ | ||||
|   faction_stack = malloc(sizeof(Faction)); | ||||
|   faction_stack[0].name     = strdup("Player"); | ||||
|   faction_stack[0].nallies  = 0; | ||||
| @ -484,7 +484,7 @@ int factions_load(void) { | ||||
| 
 | ||||
| void factions_free(void) { | ||||
|   int i; | ||||
|   // Free alliances.
 | ||||
|   /* Free alliances. */ | ||||
|   for(i = 0; i < nalliances; i++) { | ||||
|     free(alliances[i].name); | ||||
|     free(alliances[i].factions); | ||||
| @ -493,7 +493,7 @@ void factions_free(void) { | ||||
|   alliances = NULL; | ||||
|   nalliances = 0; | ||||
| 
 | ||||
|   // Free factions.
 | ||||
|   /* Free factions. */ | ||||
|   for(i = 0; i < nfactions; i++) { | ||||
|     free(faction_stack[i].name); | ||||
|     if(faction_stack[i].nallies > 0)  free(faction_stack[i].allies); | ||||
| @ -509,17 +509,17 @@ int pfaction_save(xmlTextWriterPtr writer) { | ||||
| 
 | ||||
|   xmlw_startElem(writer, "factions"); | ||||
| 
 | ||||
|   // Player is faction 0.
 | ||||
|   /* Player is faction 0. */ | ||||
|   for(i = 1; i < nfactions; i++) { | ||||
|     xmlw_startElem(writer, "faction"); | ||||
| 
 | ||||
|     xmlw_attr(writer, "name", "%s", faction_stack[i].name); | ||||
|     xmlw_str(writer, "%d", faction_stack[i].player); | ||||
| 
 | ||||
|     xmlw_endElem(writer); // Faction.
 | ||||
|     xmlw_endElem(writer); /* Faction. */ | ||||
|   } | ||||
| 
 | ||||
|   xmlw_endElem(writer); // Faction.
 | ||||
|   xmlw_endElem(writer); /* Faction. */ | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| @ -2,27 +2,27 @@ | ||||
| 
 | ||||
| #define FACTION_PLAYER 0 | ||||
| 
 | ||||
| // Get stuff.
 | ||||
| /* Get stuff. */ | ||||
| int faction_get(const char* name); | ||||
| int faction_getAlliance(char* name); | ||||
| char* faction_name(int f); | ||||
| 
 | ||||
| // Player stuff.
 | ||||
| /* Player stuff. */ | ||||
| void faction_modPlayer(int f, int mod); | ||||
| int faction_getPlayer(int f); | ||||
| 
 | ||||
| // Works with only factions.
 | ||||
| /* Works with only factions. */ | ||||
| int areEnemies(int a, int b); | ||||
| int areAllies(int a, int b); | ||||
| 
 | ||||
| // Faction + Alliance.
 | ||||
| /* Faction + Alliance. */ | ||||
| int faction_ofAlliance(int f, int a); | ||||
| 
 | ||||
| // Check.
 | ||||
| /* Check. */ | ||||
| int faction_isAlliance(int a); | ||||
| int faction_isFaction(int f); | ||||
| 
 | ||||
| // Load/Free.
 | ||||
| /* Load/Free. */ | ||||
| int factions_load(void); | ||||
| void factions_free(void); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										186
									
								
								src/font.c
									
									
									
									
									
								
							
							
						
						
									
										186
									
								
								src/font.c
									
									
									
									
									
								
							| @ -10,19 +10,19 @@ | ||||
| 
 | ||||
| #define FONT_DEF  "../dat/font.ttf" | ||||
| 
 | ||||
| // == Font render routines.================================
 | ||||
| // Use a display list to store ASCII chars rendered with
 | ||||
| // freefont. There are several drawing methods depending
 | ||||
| // on whether you want to print it all, to a max width,
 | ||||
| // print centered or print a block of text.
 | ||||
| //
 | ||||
| // There are hardcoded size limits. 256 characters for all
 | ||||
| // routines exept gl_printText which has a 1024 limit.
 | ||||
| //
 | ||||
| // TODO: Check if length is too long.
 | ||||
| // ========================================================
 | ||||
| /* == Font render routines.================================ */ | ||||
| /* Use a display list to store ASCII chars rendered with */ | ||||
| /* freefont. There are several drawing methods depending */ | ||||
| /* on whether you want to print it all, to a max width, */ | ||||
| /* print centered or print a block of text. */ | ||||
| /* */ | ||||
| /* There are hardcoded size limits. 256 characters for all */ | ||||
| /* routines exept gl_printText which has a 1024 limit. */ | ||||
| /* */ | ||||
| /* TODO: Check if length is too long. */ | ||||
| /* ======================================================== */ | ||||
| 
 | ||||
| // Default font.
 | ||||
| /* Default font. */ | ||||
| glFont gl_defFont; | ||||
| glFont gl_smallFont; | ||||
| 
 | ||||
| @ -32,7 +32,7 @@ static void glFontMakeDList(FT_Face face, char ch, | ||||
| 
 | ||||
| static int pot(int n); | ||||
| 
 | ||||
| // Get the closest power of two.
 | ||||
| /* Get the closest power of two. */ | ||||
| static int pot(int n) { | ||||
|   int i = 1; | ||||
|   while(i < n) | ||||
| @ -40,11 +40,11 @@ static int pot(int n) { | ||||
|   return i; | ||||
| } | ||||
| 
 | ||||
| // Print text on screen! YES!!!! Just like printf! But different!
 | ||||
| // Defaults ft_font to gl_defFont if NULL.
 | ||||
| /* Print text on screen! YES!!!! Just like printf! But different! */ | ||||
| /* Defaults ft_font to gl_defFont if NULL. */ | ||||
| void gl_print(const glFont* ft_font, const double x, const double y, | ||||
|               const glColour* c, const char* fmt, ...) { | ||||
|   //float h = ft_font->h / .63; // Slightly increases font size.
 | ||||
|   /*float h = ft_font->h / .63; // Slightly increases font size. */ | ||||
|   char txt[256]; | ||||
|   va_list ap; | ||||
| 
 | ||||
| @ -52,7 +52,7 @@ void gl_print(const glFont* ft_font, const double x, const double y, | ||||
| 
 | ||||
|   if(fmt == NULL) return; | ||||
|   else { | ||||
|     // convert the symbols to text.
 | ||||
|     /* convert the symbols to text. */ | ||||
|     va_start(ap, fmt); | ||||
|     vsprintf(txt, fmt, ap); | ||||
|     va_end(ap); | ||||
| @ -63,24 +63,24 @@ void gl_print(const glFont* ft_font, const double x, const double y, | ||||
|   glListBase(ft_font->list_base); | ||||
| 
 | ||||
|   glMatrixMode(GL_MODELVIEW); | ||||
|   glPushMatrix(); // Translation matrix.
 | ||||
|   glPushMatrix(); /* Translation matrix. */ | ||||
|   glTranslated(x - (double)SCREEN_W/2., y - (double)SCREEN_H/2., 0); | ||||
| 
 | ||||
|   if(c == NULL) glColor4d(1., 1., 1., 1.); | ||||
|   else COLOUR(*c); | ||||
|   glCallLists(strlen(txt), GL_UNSIGNED_BYTE, &txt); | ||||
| 
 | ||||
|   glPopMatrix(); // Translation matrix.
 | ||||
|   glPopMatrix(); /* Translation matrix. */ | ||||
|   glDisable(GL_TEXTURE_2D); | ||||
| 
 | ||||
|   gl_checkErr(); | ||||
| } | ||||
| 
 | ||||
| // Acts just like gl_print, but prints to a max length of max.
 | ||||
| // Return the amount of characters we had to suppress.
 | ||||
| /* Acts just like gl_print, but prints to a max length of max. */ | ||||
| /* Return the amount of characters we had to suppress. */ | ||||
| int gl_printMax(const glFont* ft_font, const int max, | ||||
|                 const double x, const double y, const glColour* c, const char* fmt, ...) { | ||||
|   //float h = ft_font->h / .63; // Slightly increases font size.
 | ||||
|   /*float h = ft_font->h / .63; // Slightly increases font size. */ | ||||
|   char txt[256]; | ||||
|   va_list ap; | ||||
|   int i, n, len, ret; | ||||
| @ -89,37 +89,37 @@ int gl_printMax(const glFont* ft_font, const int max, | ||||
| 
 | ||||
|   if(fmt == NULL) return -1; | ||||
|   else { | ||||
|     // convert the symbols to text.
 | ||||
|     /* convert the symbols to text. */ | ||||
|     va_start(ap, fmt); | ||||
|     vsprintf(txt, fmt, ap); | ||||
|     va_end(ap); | ||||
|   } | ||||
| 
 | ||||
|   // Limit the size.
 | ||||
|   /* Limit the size. */ | ||||
|   len = (int)strlen(txt); | ||||
|   for(n = 0, i = 0; i < len; i++) { | ||||
|     n += ft_font->w[(int)txt[i]]; | ||||
|     if(n > max) { | ||||
|       ret = len - i; // Difference.
 | ||||
|       ret = len - i; /* Difference. */ | ||||
|       txt[i] = '\0'; | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Display the text.
 | ||||
|   /* Display the text. */ | ||||
|   glEnable(GL_TEXTURE_2D); | ||||
| 
 | ||||
|   glListBase(ft_font->list_base); | ||||
| 
 | ||||
|   glMatrixMode(GL_MODELVIEW); // Projection gets full fast using modelview.
 | ||||
|   glPushMatrix(); // Translation matrix.
 | ||||
|   glMatrixMode(GL_MODELVIEW); /* Projection gets full fast using modelview. */ | ||||
|   glPushMatrix(); /* Translation matrix. */ | ||||
|   glTranslated(x - (double)SCREEN_W/2., y - (double)SCREEN_H/2., 0); | ||||
| 
 | ||||
|   if(c == NULL) glColor4d(1., 1., 1., 1.); | ||||
|   else COLOUR(*c); | ||||
|   glCallLists(i, GL_UNSIGNED_BYTE, &txt); | ||||
| 
 | ||||
|   glPopMatrix(); // Translation matrix.
 | ||||
|   glPopMatrix(); /* Translation matrix. */ | ||||
|   glDisable(GL_TEXTURE_2D); | ||||
| 
 | ||||
|   gl_checkErr(); | ||||
| @ -127,33 +127,33 @@ int gl_printMax(const glFont* ft_font, const int max, | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| // Acts just like gl_printMax, but centers the text in the width.
 | ||||
| /* Acts just like gl_printMax, but centers the text in the width. */ | ||||
| int gl_printMid(const glFont* ft_font, const int width, double x, const double y, | ||||
|                 const glColour* c, const char* fmt, ...) { | ||||
|   //float h = ft_font->h / .63; // Slightly increases font size.
 | ||||
|   /*float h = ft_font->h / .63; // Slightly increases font size. */ | ||||
|   char txt[256]; | ||||
|   va_list ap; | ||||
|   int i, n, len, ret; | ||||
| 
 | ||||
|   ret = 0; // Default return value.
 | ||||
|   ret = 0; /* Default return value. */ | ||||
| 
 | ||||
|   if(ft_font == NULL) ft_font = &gl_defFont; | ||||
| 
 | ||||
|   if(fmt == NULL) return -1; | ||||
|   else { | ||||
|     // convert the symbols to text.
 | ||||
|     /* convert the symbols to text. */ | ||||
|     va_start(ap, fmt); | ||||
|     vsprintf(txt, fmt, ap); | ||||
|     va_end(ap); | ||||
|   } | ||||
| 
 | ||||
|   // Limit the size.
 | ||||
|   /* Limit the size. */ | ||||
|   len = (int)strlen(txt); | ||||
|   for(n = 0, i = 0; i < len; i++) { | ||||
|     n += ft_font->w[(int)txt[i]]; | ||||
|     if(n > width) { | ||||
|       ret = len - i; // Difference.
 | ||||
|       n -= ft_font->w[(int)txt[i]]; // Actual size.
 | ||||
|       ret = len - i; /* Difference. */ | ||||
|       n -= ft_font->w[(int)txt[i]]; /* Actual size. */ | ||||
|       txt[i] = '\0'; | ||||
|       break; | ||||
|     } | ||||
| @ -161,20 +161,20 @@ int gl_printMid(const glFont* ft_font, const int width, double x, const double y | ||||
| 
 | ||||
|   x += (double)(width-n)/2.; | ||||
| 
 | ||||
|   // Display the text.
 | ||||
|   /* Display the text. */ | ||||
|   glEnable(GL_TEXTURE_2D); | ||||
| 
 | ||||
|   glListBase(ft_font->list_base); | ||||
| 
 | ||||
|   glMatrixMode(GL_MODELVIEW); // Projection gets full fast using modelview.
 | ||||
|   glPushMatrix(); // Translation matrix.
 | ||||
|   glMatrixMode(GL_MODELVIEW); /* Projection gets full fast using modelview. */ | ||||
|   glPushMatrix(); /* Translation matrix. */ | ||||
|   glTranslated(x - (double)SCREEN_W/2., y - (double)SCREEN_H/2., 0); | ||||
| 
 | ||||
|   if(c == NULL) glColor4d(1., 1., 1., 1.); | ||||
|   else COLOUR(*c); | ||||
|   glCallLists(i, GL_UNSIGNED_BYTE, &txt); | ||||
| 
 | ||||
|   glPopMatrix(); // Translation matrix.
 | ||||
|   glPopMatrix(); /* Translation matrix. */ | ||||
|   glDisable(GL_TEXTURE_2D); | ||||
| 
 | ||||
|   gl_checkErr(); | ||||
| @ -182,24 +182,24 @@ int gl_printMid(const glFont* ft_font, const int width, double x, const double y | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| // Print text with line breaks included to a max width and height precet.
 | ||||
| /* Print text with line breaks included to a max width and height precet. */ | ||||
| int gl_printText(const glFont* ft_font, const int width, const int height, | ||||
|                  double bx, double by, glColour* c, const char* fmt, ...) { | ||||
| 
 | ||||
|   //float h = ft_font->h / .63; // Slightly increase font size.
 | ||||
|   /*float h = ft_font->h / .63; // Slightly increase font size. */ | ||||
|   char txt[4096]; | ||||
|   char buf[256]; | ||||
|   va_list ap; | ||||
|   int p, i, j, n, m, len, ret, lastspace; | ||||
|   double x, y; | ||||
| 
 | ||||
|   ret = 0; // Default return value.
 | ||||
|   ret = 0; /* Default return value. */ | ||||
| 
 | ||||
|   if(ft_font == NULL) ft_font = &gl_defFont; | ||||
| 
 | ||||
|   if(fmt == NULL) return -1; | ||||
|   else { | ||||
|     // Convert the symbols to text.
 | ||||
|     /* Convert the symbols to text. */ | ||||
|     va_start(ap, fmt); | ||||
|     vsprintf(txt, fmt, ap); | ||||
|     va_end(ap); | ||||
| @ -207,22 +207,22 @@ int gl_printText(const glFont* ft_font, const int width, const int height, | ||||
|   bx -= (double)SCREEN_W/2.; | ||||
|   by -= (double)SCREEN_H/2.; | ||||
|   x = bx; | ||||
|   y = by + height - (double)ft_font->h; // y is top left corner.
 | ||||
|   y = by + height - (double)ft_font->h; /* y is top left corner. */ | ||||
| 
 | ||||
|   // Prepare opengl.
 | ||||
|   /* Prepare opengl. */ | ||||
|   glEnable(GL_TEXTURE_2D); | ||||
|   glListBase(ft_font->list_base); | ||||
|   if(c == NULL) glColor4d(1., 1., 1., 1.); | ||||
|   else COLOUR(*c); | ||||
| 
 | ||||
|   len = (int)strlen(txt); | ||||
|   // Limit size per line.
 | ||||
|   lastspace = -1; // Last ' ' or \n int text.
 | ||||
|   n = 0; // Current width.
 | ||||
|   i = 0; // Current position.
 | ||||
|   p = -1; // Where we last drew up to.
 | ||||
|   /* Limit size per line. */ | ||||
|   lastspace = -1; /* Last ' ' or \n int text. */ | ||||
|   n = 0; /* Current width. */ | ||||
|   i = 0; /* Current position. */ | ||||
|   p = -1; /* Where we last drew up to. */ | ||||
|   while(i < len+1) { | ||||
|     if(by - y > (double)height) return len-lastspace; // Past height.
 | ||||
|     if(by - y > (double)height) return len-lastspace; /* Past height. */ | ||||
| 
 | ||||
|     n += ft_font->w[(int)txt[i]]; | ||||
| 
 | ||||
| @ -231,7 +231,7 @@ int gl_printText(const glFont* ft_font, const int width, const int height, | ||||
|     if(((n > width) && ((p != lastspace))) | ||||
|         || (txt[i] == '\n') || (txt[i] == '\0')) { | ||||
| 
 | ||||
|       // Time to draw the line.
 | ||||
|       /* Time to draw the line. */ | ||||
|       m = 0; | ||||
|       if(lastspace == -1) lastspace = 0; | ||||
|       for(j = 0; j < (lastspace-p-1); j++) { | ||||
| @ -243,20 +243,20 @@ int gl_printText(const glFont* ft_font, const int width, const int height, | ||||
|         if(m > width) break; | ||||
|         buf[j] = txt[p+j+1]; | ||||
|       } | ||||
|       // No need for null termination.
 | ||||
|       /* No need for null termination. */ | ||||
| 
 | ||||
|       glMatrixMode(GL_MODELVIEW); // using modelview, projection gets full fast.
 | ||||
|       glPushMatrix(); // Translation matrix.
 | ||||
|       glMatrixMode(GL_MODELVIEW); /* using modelview, projection gets full fast. */ | ||||
|       glPushMatrix(); /* Translation matrix. */ | ||||
|       glTranslated(x, y, 0); | ||||
| 
 | ||||
|       // This is what we are displaying.
 | ||||
|       /* This is what we are displaying. */ | ||||
|       glCallLists(j, GL_UNSIGNED_BYTE, &buf); | ||||
|       glPopMatrix(); // Translation matrix.
 | ||||
|       glPopMatrix(); /* Translation matrix. */ | ||||
| 
 | ||||
|       p = lastspace; | ||||
|       n = 0; | ||||
|       i = lastspace; | ||||
|       y -= 1.5*(double)ft_font->h; // Move position down.
 | ||||
|       y -= 1.5*(double)ft_font->h; /* Move position down. */ | ||||
|     } | ||||
|     i++; | ||||
|   } | ||||
| @ -267,17 +267,17 @@ int gl_printText(const glFont* ft_font, const int width, const int height, | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| // Get the width of the text about to be printed.
 | ||||
| /* Get the width of the text about to be printed. */ | ||||
| int gl_printWidth(const glFont* ft_font, const char* fmt, ...) { | ||||
|   int i, n; | ||||
|   char txt[256]; // Holds the string.
 | ||||
|   char txt[256]; /* Holds the string. */ | ||||
|   va_list ap; | ||||
| 
 | ||||
|   if(ft_font == NULL) ft_font = &gl_defFont; | ||||
| 
 | ||||
|   if(fmt == NULL) return 0; | ||||
|   else { | ||||
|     // Convert the symbols to text.
 | ||||
|     /* Convert the symbols to text. */ | ||||
|     va_start(ap, fmt); | ||||
|     vsprintf(txt, fmt, ap); | ||||
|     va_end(ap); | ||||
| @ -292,7 +292,7 @@ int gl_printWidth(const glFont* ft_font, const char* fmt, ...) { | ||||
| int gl_printHeight(const glFont* ft_font, const int width, | ||||
|                   const char* fmt, ...) { | ||||
|    | ||||
|   char txt[1024]; // Holds the string.
 | ||||
|   char txt[1024]; /* Holds the string. */ | ||||
|   va_list ap; | ||||
|   int p, i, n, len, lastspace; | ||||
|   double x, y; | ||||
| @ -301,7 +301,7 @@ int gl_printHeight(const glFont* ft_font, const int width, | ||||
| 
 | ||||
|   if(fmt == NULL) return -1; | ||||
|   else { | ||||
|     // Convert the symbols to text.
 | ||||
|     /* Convert the symbols to text. */ | ||||
|     va_start(ap, fmt); | ||||
|     vsprintf(txt, fmt, ap); | ||||
|     va_end(ap); | ||||
| @ -310,11 +310,11 @@ int gl_printHeight(const glFont* ft_font, const int width, | ||||
|   y = 0.; | ||||
| 
 | ||||
|   len = (int) strlen(txt); | ||||
|   // Limit the size per line.
 | ||||
|   lastspace = -1; // Last ' ' or '\n' in the text.
 | ||||
|   n = 0;    // Current width.
 | ||||
|   i = 0;    // Current position.
 | ||||
|   p = -1;   // Where we last drew up to.
 | ||||
|   /* Limit the size per line. */ | ||||
|   lastspace = -1; /* Last ' ' or '\n' in the text. */ | ||||
|   n = 0;    /* Current width. */ | ||||
|   i = 0;    /* Current position. */ | ||||
|   p = -1;   /* Where we last drew up to. */ | ||||
| 
 | ||||
|   while(i < len+1) { | ||||
|     n += ft_font->w[(int)txt[i]]; | ||||
| @ -327,16 +327,16 @@ int gl_printHeight(const glFont* ft_font, const int width, | ||||
|       p = lastspace; | ||||
|       n = 0; | ||||
|       i = lastspace; | ||||
|       y += 1.5*(double)ft_font->h; // Move position down.
 | ||||
|       y += 1.5*(double)ft_font->h; /* Move position down. */ | ||||
|     } | ||||
|     i++; | ||||
|   } | ||||
|   return (int)y; | ||||
| } | ||||
| 
 | ||||
| // ================
 | ||||
| // FONT!
 | ||||
| // ================
 | ||||
| /* ================ */ | ||||
| /* FONT! */ | ||||
| /* ================ */ | ||||
| static void glFontMakeDList(FT_Face face, char ch, GLuint list_base, | ||||
|                             GLuint* tex_base, int* width_base) { | ||||
|   FT_Glyph glyph; | ||||
| @ -353,18 +353,18 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base, | ||||
|   if(FT_Get_Glyph(face->glyph, &glyph)) | ||||
|     WARN("FT_Ge_Glyph failed"); | ||||
| 
 | ||||
|   // Convert your glyph to a bitmap.
 | ||||
|   /* Convert your glyph to a bitmap. */ | ||||
|   FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1); | ||||
|   FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph; | ||||
| 
 | ||||
|   bitmap = bitmap_glyph->bitmap; // To simplify.
 | ||||
|   bitmap = bitmap_glyph->bitmap; /* To simplify. */ | ||||
| 
 | ||||
|   // Need the POT wrapping for GL.
 | ||||
|   /* Need the POT wrapping for GL. */ | ||||
|   w = pot(bitmap.width); | ||||
|   h = pot(bitmap.rows); | ||||
| 
 | ||||
|   // Memory for textured data.
 | ||||
|   // Bitmap is useing two channels, one for luminosity and one for alpha.
 | ||||
|   /* Memory for textured data. */ | ||||
|   /* Bitmap is useing two channels, one for luminosity and one for alpha. */ | ||||
|   expanded_data = (GLubyte*)malloc(sizeof(GLubyte)*2*w*h + 1); | ||||
|   for(j = 0; j < h; j++) { | ||||
|     for(i = 0; i < w; i++) { | ||||
| @ -373,28 +373,28 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base, | ||||
|             0 : bitmap.buffer[i + bitmap.width*j]; | ||||
|     } | ||||
|   } | ||||
|   // Create the GL texture.
 | ||||
|   /* Create the GL texture. */ | ||||
|   glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]); | ||||
|   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
|   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
|   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_LUMINANCE_ALPHA, | ||||
|                GL_UNSIGNED_BYTE, expanded_data); | ||||
| 
 | ||||
|   free(expanded_data); // No need for this now.
 | ||||
|   free(expanded_data); /* No need for this now. */ | ||||
| 
 | ||||
|   // Create the display lists.
 | ||||
|   /* Create the display lists. */ | ||||
|   glNewList(list_base+ch, GL_COMPILE); | ||||
| 
 | ||||
|   // Corrects a spacing flaw between letters and
 | ||||
|   // downwards correction for letters like g or y.
 | ||||
|   /* Corrects a spacing flaw between letters and */ | ||||
|   /* downwards correction for letters like g or y. */ | ||||
|   glPushMatrix(); | ||||
|   glTranslated(bitmap_glyph->left, bitmap_glyph->top-bitmap.rows, 0); | ||||
| 
 | ||||
|   // Take the opengl POT wrapping into account.
 | ||||
|   /* Take the opengl POT wrapping into account. */ | ||||
|   x = (double)bitmap.width/(double)w; | ||||
|   y = (double)bitmap.rows/(double)h; | ||||
| 
 | ||||
|   // Draw the texture mapped quad.
 | ||||
|   /* Draw the texture mapped quad. */ | ||||
|   glBindTexture(GL_TEXTURE_2D, tex_base[(int)ch]); | ||||
|   glBegin(GL_QUADS); | ||||
|   glTexCoord2d(0, 0); | ||||
| @ -411,7 +411,7 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base, | ||||
|   glTranslated(face->glyph->advance.x >> 6, 0,0); | ||||
|   width_base[(int)ch] = (int)(face->glyph->advance.x >> 6); | ||||
| 
 | ||||
|   // End of the display list.
 | ||||
|   /* End of the display list. */ | ||||
|   glEndList(); | ||||
| 
 | ||||
|   FT_Done_Glyph(glyph); | ||||
| @ -427,7 +427,7 @@ void gl_fontInit(glFont* font, const char* fname, const unsigned int h) { | ||||
| 
 | ||||
|   FT_Byte* buf = pack_readfile(DATA, (fname) ? fname : FONT_DEF, &bufsize); | ||||
| 
 | ||||
|   // Allocatagery.
 | ||||
|   /* Allocatagery. */ | ||||
|   font->textures = malloc(sizeof(GLuint)*128); | ||||
|   font->w = malloc(sizeof(int)*128); | ||||
|   font->h = (int)h; | ||||
| @ -436,29 +436,29 @@ void gl_fontInit(glFont* font, const char* fname, const unsigned int h) { | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   // Create a FreeType font library.
 | ||||
|   /* Create a FreeType font library. */ | ||||
|   FT_Library library; | ||||
|   if(FT_Init_FreeType(&library)) { | ||||
|     WARN("FT_Init_FreeType failed"); | ||||
|   } | ||||
| 
 | ||||
|   // Objects that freetype uses to store font info.
 | ||||
|   /* Objects that freetype uses to store font info. */ | ||||
|   FT_Face face; | ||||
|   if(FT_New_Memory_Face(library, buf, bufsize, 0, &face)) | ||||
|     WARN("FT_New_Memory_Face failed loading library from %s", fname); | ||||
| 
 | ||||
|   // FreeType is pretty nice and measures using 1/64 of a pixel, therfore expand.
 | ||||
|   /* FreeType is pretty nice and measures using 1/64 of a pixel, therfore expand. */ | ||||
|   FT_Set_Char_Size(face, h << 6, h << 6, 96, 96); | ||||
| 
 | ||||
|   // Have OpenGL allocate space for the textures / display lists.
 | ||||
|   /* Have OpenGL allocate space for the textures / display lists. */ | ||||
|   font->list_base = glGenLists(128); | ||||
|   glGenTextures(128, font->textures); | ||||
| 
 | ||||
|   // Create each of the font display lists.
 | ||||
|   /* Create each of the font display lists. */ | ||||
|   for(i = 0; i < 128; i++) | ||||
|     glFontMakeDList(face, i, font->list_base, font->textures, font->w); | ||||
| 
 | ||||
|   // We can now free the face and library.
 | ||||
|   /* We can now free the face and library. */ | ||||
|   FT_Done_Face(face); | ||||
|   FT_Done_FreeType(library); | ||||
|   free(buf); | ||||
|  | ||||
							
								
								
									
										22
									
								
								src/font.h
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/font.h
									
									
									
									
									
								
							| @ -1,39 +1,39 @@ | ||||
| #pragma once | ||||
| #include "opengl.h" | ||||
| 
 | ||||
| // Font info.
 | ||||
| /* Font info. */ | ||||
| typedef struct glFont_ { | ||||
|   int h; // Height.
 | ||||
|   int h; /* Height. */ | ||||
|   int* w; | ||||
|   GLuint* textures; | ||||
|   GLuint list_base; | ||||
| } glFont; | ||||
| 
 | ||||
| extern glFont gl_defFont; // Default font.
 | ||||
| extern glFont gl_smallFont; // Small font.
 | ||||
| extern glFont gl_defFont; /* Default font. */ | ||||
| extern glFont gl_smallFont; /* Small font. */ | ||||
| 
 | ||||
| // glFont loading/freeing.
 | ||||
| // If font is NULL it uses the internal default font, same with gl_print
 | ||||
| /* glFont loading/freeing. */ | ||||
| /* If font is NULL it uses the internal default font, same with gl_print */ | ||||
| void gl_fontInit(glFont* font, const char* fname, const unsigned int h); | ||||
| void gl_freeFont(glFont* font); | ||||
| 
 | ||||
| // Print text.
 | ||||
| /* Print text. */ | ||||
| void gl_print(const glFont* ft_font, const double x, const double y, | ||||
|               const glColour* c, const char* fmt, ...); | ||||
| 
 | ||||
| // Print text to a max length.
 | ||||
| /* Print text to a max length. */ | ||||
| int gl_printMax(const glFont* ft_font, const int max, | ||||
|                 const double x, const double y, const glColour* c, const char* fmt, ...); | ||||
| 
 | ||||
| // Print text centered in width at x.
 | ||||
| /* Print text centered in width at x. */ | ||||
| int gl_printMid(const glFont* ft_font, const int width, | ||||
|                 double x, const double y, const glColour* c, const char* fmt, ...); | ||||
| 
 | ||||
| // Respects \n -> bx, by is top left position.
 | ||||
| /* Respects \n -> bx, by is top left position. */ | ||||
| int gl_printText(const glFont* ft_font, const int width, const int height, | ||||
|                  double bx, double by, glColour* c, const char* fmt, ...); | ||||
| 
 | ||||
| // Get the width of the text that you wish to print.
 | ||||
| /* Get the width of the text that you wish to print. */ | ||||
| int  gl_printWidth(const glFont* ft_font, const char* fmt, ...); | ||||
| 
 | ||||
| int gl_printHeight(const glFont* ft_font, const int width, | ||||
|  | ||||
							
								
								
									
										68
									
								
								src/hook.c
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								src/hook.c
									
									
									
									
									
								
							| @ -6,31 +6,31 @@ | ||||
| #include "xml.h" | ||||
| #include "hook.h" | ||||
| 
 | ||||
| // The hook.
 | ||||
| /* The hook. */ | ||||
| typedef struct Hook_ { | ||||
|   unsigned int id;      // Unique id.
 | ||||
|   unsigned int parent;  // Mission it's connected to.
 | ||||
|   char* func;           // Function returned.
 | ||||
|   char* stack;          // Stack it's a part of.
 | ||||
|   unsigned int id;      /* Unique id. */ | ||||
|   unsigned int parent;  /* Mission it's connected to. */ | ||||
|   char* func;           /* Function returned. */ | ||||
|   char* stack;          /* Stack it's a part of. */ | ||||
| 
 | ||||
|   int delete;           // Indicates it should be deleted when possible.
 | ||||
|   int delete;           /* Indicates it should be deleted when possible. */ | ||||
| } Hook; | ||||
| 
 | ||||
| // The stack.
 | ||||
| static unsigned int     hook_id             = 0; // Unique hook id.
 | ||||
| /* The stack. */ | ||||
| static unsigned int     hook_id             = 0; /* Unique hook id. */ | ||||
| static Hook*            hook_stack          = NULL; | ||||
| static int              hook_mstack         = 0; | ||||
| static int              hook_nstack         = 0; | ||||
| static int              hook_runningstack   = 0;  // Check if stack is running.
 | ||||
| static int              hook_runningstack   = 0;  /* Check if stack is running. */ | ||||
| 
 | ||||
| // Extern.
 | ||||
| /* Extern. */ | ||||
| extern int misn_run(Mission* misn, char* func); | ||||
| // Intern.
 | ||||
| /* Intern. */ | ||||
| static int hook_run(Hook* hook); | ||||
| static void hook_free(Hook* h); | ||||
| static int hook_needSave(Hook* h); | ||||
| static int hook_parse(xmlNodePtr base); | ||||
| // Extern.
 | ||||
| /* Extern. */ | ||||
| int hook_save(xmlTextWriterPtr writer); | ||||
| int hook_load(xmlNodePtr parent); | ||||
| 
 | ||||
| @ -38,38 +38,38 @@ static int hook_run(Hook* hook) { | ||||
|   int i; | ||||
|   Mission* misn; | ||||
| 
 | ||||
|   if(hook->delete) return 0; // Hook should be deleted not run.
 | ||||
|   if(hook->delete) return 0; /* Hook should be deleted not run. */ | ||||
| 
 | ||||
|   // Locate the mission.
 | ||||
|   /* Locate the mission. */ | ||||
|   for(i = 0; i < MISSION_MAX; i++) | ||||
|     if(player_missions[i].id == hook->parent) | ||||
|       break; | ||||
|   if(i >= MISSION_MAX) { | ||||
|     WARN("Trying to run hook with parent not in player mission stack: deleting"); | ||||
|     hook->delete = 1; // So delete it.
 | ||||
|     hook->delete = 1; /* So delete it. */ | ||||
|     return -1; | ||||
|   } | ||||
|   misn = &player_missions[i]; | ||||
| 
 | ||||
|   if(misn_run(misn, hook->func) < 0) | ||||
|     // Error has accured.
 | ||||
|     /* Error has accured. */ | ||||
|     WARN("Hook [%s] '%d' -> '%s' failed", hook->stack, | ||||
|          hook->id, hook->func); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Add/Remove hooks.
 | ||||
| /* Add/Remove hooks. */ | ||||
| unsigned int hook_add(unsigned int parent, char* func, char* stack) { | ||||
|   Hook* new_hook; | ||||
| 
 | ||||
|   // If the memory must grow.
 | ||||
|   /* If the memory must grow. */ | ||||
|   if(hook_nstack+1 > hook_mstack) { | ||||
|     hook_mstack += 5; | ||||
|     hook_stack = realloc(hook_stack, hook_mstack*sizeof(Hook)); | ||||
|   } | ||||
| 
 | ||||
|   // Create the new hook.
 | ||||
|   /* Create the new hook. */ | ||||
|   new_hook = &hook_stack[hook_nstack]; | ||||
|   new_hook->id      = ++hook_id; | ||||
|   new_hook->parent  = parent; | ||||
| @ -99,14 +99,14 @@ void hook_rm(unsigned int id) { | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   // Last hook, just clip the stack.
 | ||||
|   /* Last hook, just clip the stack. */ | ||||
|   if(m == (hook_nstack-1)) { | ||||
|     hook_free(&hook_stack[m]); | ||||
|     hook_nstack--; | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   // Move it!
 | ||||
|   /* Move it! */ | ||||
|   memmove(&hook_stack[m], &hook_stack[m+1], sizeof(Hook)*(hook_nstack-(m+1))); | ||||
|   hook_nstack--; | ||||
| } | ||||
| @ -120,16 +120,16 @@ void hook_rmParent(unsigned int parent) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Run all hooks off the stack.
 | ||||
| /* Run all hooks off the stack. */ | ||||
| int hooks_run(char* stack) { | ||||
|   int i; | ||||
| 
 | ||||
|   hook_runningstack = 1; // Running hooks.
 | ||||
|   hook_runningstack = 1; /* Running hooks. */ | ||||
|   for(i = 0; i < hook_nstack; i++) | ||||
|     if((strcmp(stack, hook_stack[i].stack)==0) && !hook_stack[i].delete) { | ||||
|       hook_run(&hook_stack[i]); | ||||
|     } | ||||
|   hook_runningstack = 0; // Not running hooks anymore.
 | ||||
|   hook_runningstack = 0; /* Not running hooks anymore. */ | ||||
| 
 | ||||
|   for(i = 0; i < hook_nstack; i++) | ||||
|     if((strcmp(stack, hook_stack[i].stack)==0) && hook_stack[i].delete) { | ||||
| @ -140,7 +140,7 @@ int hooks_run(char* stack) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Run a single hook by id.
 | ||||
| /* Run a single hook by id. */ | ||||
| void hook_runID(unsigned int id) { | ||||
|   int i; | ||||
| 
 | ||||
| @ -152,13 +152,13 @@ void hook_runID(unsigned int id) { | ||||
|   DEBUG("Attempting to run hook of id '%d' which is not in the stack", id); | ||||
| } | ||||
| 
 | ||||
| // Free a hook.
 | ||||
| /* Free a hook. */ | ||||
| static void hook_free(Hook* h) { | ||||
|   if(h->func != NULL)   free(h->func); | ||||
|   if(h->stack != NULL)  free(h->stack); | ||||
| } | ||||
| 
 | ||||
| // Clean upi after ourselves.
 | ||||
| /* Clean upi after ourselves. */ | ||||
| void hook_cleanup(void) { | ||||
|   int i; | ||||
| 
 | ||||
| @ -166,12 +166,12 @@ void hook_cleanup(void) { | ||||
|     hook_free(&hook_stack[i]); | ||||
|   free(hook_stack); | ||||
|   hook_stack  = NULL; | ||||
|   // Sane defaults just in case.
 | ||||
|   /* Sane defaults just in case. */ | ||||
|   hook_nstack = 0; | ||||
|   hook_mstack = 0; | ||||
| } | ||||
| 
 | ||||
| // Save the hooks.
 | ||||
| /* Save the hooks. */ | ||||
| static int hook_needSave(Hook* h) { | ||||
|   int i; | ||||
|   char* nosave[] = { "death", "end" }; | ||||
| @ -190,23 +190,23 @@ int hook_save(xmlTextWriterPtr writer) { | ||||
|   for(i = 0; i < hook_nstack; i++) { | ||||
|     h = &hook_stack[i]; | ||||
| 
 | ||||
|     if(!hook_needSave(h)) continue; // No need to save it.
 | ||||
|     if(!hook_needSave(h)) continue; /* No need to save it. */ | ||||
| 
 | ||||
|     xmlw_startElem(writer, "hook"); | ||||
| 
 | ||||
|     //xmlw_attr(writer, "id", "%u", h->id); // I don't think it's needed.
 | ||||
|     /*xmlw_attr(writer, "id", "%u", h->id); // I don't think it's needed. */ | ||||
|     xmlw_elem(writer, "parent", "%u", h->parent); | ||||
|     xmlw_elem(writer, "func", "%s", h->func); | ||||
|     xmlw_elem(writer, "stack", "%s", h->stack); | ||||
| 
 | ||||
|     xmlw_endElem(writer); // Hook.
 | ||||
|     xmlw_endElem(writer); /* Hook. */ | ||||
|   } | ||||
|   xmlw_endElem(writer); // Hooks.
 | ||||
|   xmlw_endElem(writer); /* Hooks. */ | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Load hooks for a player.
 | ||||
| /* Load hooks for a player. */ | ||||
| int hook_load(xmlNodePtr parent) { | ||||
|   xmlNodePtr node; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										26
									
								
								src/hook.h
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								src/hook.h
									
									
									
									
									
								
							| @ -1,25 +1,25 @@ | ||||
| #pragma once | ||||
| #include "mission.h" | ||||
| 
 | ||||
| // Add/Run hooks.
 | ||||
| /* Add/Run hooks. */ | ||||
| unsigned int hook_add(unsigned int parent, char* func, char* stack); | ||||
| void hook_rm(unsigned int id); | ||||
| void hook_rmParent(unsigned int parent); | ||||
| 
 | ||||
| // ========================================================
 | ||||
| // Run Hooks:
 | ||||
| //
 | ||||
| // Currently used:
 | ||||
| //    -- "land"     - When landed.
 | ||||
| //    -- "takeoff"  - When taking off.
 | ||||
| //    -- "jump"     - When changing systems.
 | ||||
| //    -- "time"     - When time is increment drastically 
 | ||||
| //                    (hyperspace and taking off.
 | ||||
| // ========================================================
 | ||||
| /* ======================================================== */ | ||||
| /* Run Hooks: */ | ||||
| /* */ | ||||
| /* Currently used: */ | ||||
| /*    -- "land"     - When landed. */ | ||||
| /*    -- "takeoff"  - When taking off. */ | ||||
| /*    -- "jump"     - When changing systems. */ | ||||
| /*    -- "time"     - When time is increment drastically  */ | ||||
| /*                    (hyperspace and taking off. */ | ||||
| /* ======================================================== */ | ||||
| 
 | ||||
| int hooks_run(char* stack); | ||||
| void hook_runID(unsigned int id); // Runs hook of specific id.
 | ||||
| void hook_runID(unsigned int id); /* Runs hook of specific id. */ | ||||
| 
 | ||||
| // Destroy hook.
 | ||||
| /* Destroy hook. */ | ||||
| void hook_cleanup(void); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										152
									
								
								src/input.c
									
									
									
									
									
								
							
							
						
						
									
										152
									
								
								src/input.c
									
									
									
									
									
								
							| @ -11,61 +11,61 @@ | ||||
| #define KEY_PRESS   ( 1.) | ||||
| #define KEY_RELEASE (-1.) | ||||
| 
 | ||||
| // Keybind structure.
 | ||||
| /* Keybind structure. */ | ||||
| typedef struct Keybind_ { | ||||
|   char* name;       // Keybinding name, taken from keybindNames[]
 | ||||
|   KeybindType type; // type, defined in player.h.
 | ||||
|   unsigned int key; // Key/axis/button event number.
 | ||||
|   double reverse;   // 1. if normal, -1 if reversed, only useful for joystick axis.
 | ||||
|   char* name;       /* Keybinding name, taken from keybindNames[] */ | ||||
|   KeybindType type; /* type, defined in player.h. */ | ||||
|   unsigned int key; /* Key/axis/button event number. */ | ||||
|   double reverse;   /* 1. if normal, -1 if reversed, only useful for joystick axis. */ | ||||
| } Keybind; | ||||
| 
 | ||||
| static Keybind** input_keybinds; // Contains the players keybindings.
 | ||||
| static Keybind** input_keybinds; /* Contains the players keybindings. */ | ||||
| 
 | ||||
| 
 | ||||
| // Name of each keybinding.
 | ||||
| /* Name of each keybinding. */ | ||||
| const char* keybindNames[] = { | ||||
|   "accel", "left", "right", "reverse", // Movement.
 | ||||
|   "primary", "target", "target_nearest", "face", "board", // Combat.
 | ||||
|   "secondary", "secondary_next", // Secondary weapons.
 | ||||
|   "target_planet", "land", "thyperspace","starmap", "jump", // Navigation.
 | ||||
|   "mapzoomin", "mapzoomout", "screenshot", "pause", "menu", "info", // Misc.
 | ||||
|   "end" }; // Must terminate at the end.
 | ||||
|   "accel", "left", "right", "reverse", /* Movement. */ | ||||
|   "primary", "target", "target_nearest", "face", "board", /* Combat. */ | ||||
|   "secondary", "secondary_next", /* Secondary weapons. */ | ||||
|   "target_planet", "land", "thyperspace","starmap", "jump", /* Navigation. */ | ||||
|   "mapzoomin", "mapzoomout", "screenshot", "pause", "menu", "info", /* Misc. */ | ||||
|   "end" }; /* Must terminate at the end. */ | ||||
| 
 | ||||
| // Accel hacks.
 | ||||
| static unsigned int input_accelLast  = 0;   // Used to see if double tap.
 | ||||
| unsigned int input_afterburnSensibility = 500;  // ms between taps to afterburn.
 | ||||
| /* Accel hacks. */ | ||||
| static unsigned int input_accelLast  = 0;   /* Used to see if double tap. */ | ||||
| unsigned int input_afterburnSensibility = 500;  /* ms between taps to afterburn. */ | ||||
| 
 | ||||
| // From player.c
 | ||||
| /* From player.c */ | ||||
| extern double player_turn; | ||||
| extern unsigned int player_target; | ||||
| // Grabbed from main.c
 | ||||
| /* Grabbed from main.c */ | ||||
| extern int show_fps; | ||||
| 
 | ||||
| 
 | ||||
| // Set the default input keys.
 | ||||
| /* Set the default input keys. */ | ||||
| void input_setDefault(void) { | ||||
|   // Movement.
 | ||||
|   /* Movement. */ | ||||
|   input_setKeybind("accel",           KEYBIND_KEYBOARD, SDLK_w,       0); | ||||
|   input_setKeybind("left",            KEYBIND_KEYBOARD, SDLK_a,       0); | ||||
|   input_setKeybind("right",           KEYBIND_KEYBOARD, SDLK_d,       0); | ||||
|   input_setKeybind("reverse",         KEYBIND_KEYBOARD, SDLK_s,       0); | ||||
|   // Combat.
 | ||||
|   /* Combat. */ | ||||
|   input_setKeybind("primary",         KEYBIND_KEYBOARD, SDLK_SPACE,   0); | ||||
|   input_setKeybind("target",          KEYBIND_KEYBOARD, SDLK_TAB,     0); | ||||
|   input_setKeybind("target_nearest",  KEYBIND_KEYBOARD, SDLK_r,       0); | ||||
|   input_setKeybind("face",            KEYBIND_KEYBOARD, SDLK_f,       0); | ||||
|   input_setKeybind("board",           KEYBIND_KEYBOARD, SDLK_b,       0); | ||||
|   // Secondary weapon.
 | ||||
|   /* Secondary weapon. */ | ||||
|   input_setKeybind("secondary",       KEYBIND_KEYBOARD, SDLK_LSHIFT,  0); | ||||
|   input_setKeybind("secondary_next",  KEYBIND_KEYBOARD, SDLK_e,       0); | ||||
|   // Space
 | ||||
|   /* Space */ | ||||
|   input_setKeybind("target_planet",   KEYBIND_KEYBOARD, SDLK_p,       0); | ||||
|   input_setKeybind("land",            KEYBIND_KEYBOARD, SDLK_l,       0); | ||||
|   input_setKeybind("thyperspace",     KEYBIND_KEYBOARD, SDLK_h,       0); | ||||
|   input_setKeybind("starmap",         KEYBIND_KEYBOARD, SDLK_m,       0); | ||||
|   input_setKeybind("jump",            KEYBIND_KEYBOARD, SDLK_j,       0); | ||||
| 
 | ||||
|   // Misc.
 | ||||
|   /* Misc. */ | ||||
|   input_setKeybind("mapzoomin",       KEYBIND_KEYBOARD, SDLK_0,       0); | ||||
|   input_setKeybind("mapzoomout",      KEYBIND_KEYBOARD, SDLK_9,       0); | ||||
|   input_setKeybind("screenshot",      KEYBIND_KEYBOARD, SDLK_F12,     0); | ||||
| @ -74,14 +74,14 @@ void input_setDefault(void) { | ||||
|   input_setKeybind("info",            KEYBIND_KEYBOARD, SDLK_i,       0); | ||||
| } | ||||
| 
 | ||||
| // Initialization/exit functions (does not assign keys).
 | ||||
| /* Initialization/exit functions (does not assign keys). */ | ||||
| void input_init(void) { | ||||
|   Keybind* tmp; | ||||
|   int i; | ||||
|   for(i = 0; strcmp(keybindNames[i], "end"); i++); // Get number of bindings.
 | ||||
|   for(i = 0; strcmp(keybindNames[i], "end"); i++); /* Get number of bindings. */ | ||||
|   input_keybinds = malloc(i*sizeof(Keybind*)); | ||||
| 
 | ||||
|   // Create a null keybinding for each.
 | ||||
|   /* Create a null keybinding for each. */ | ||||
|   for(i = 0; strcmp(keybindNames[i], "end"); i++) { | ||||
|     tmp = MALLOC_L(Keybind); | ||||
|     tmp->name = (char*)keybindNames[i]; | ||||
| @ -99,7 +99,7 @@ void input_exit(void) { | ||||
|   free(input_keybinds); | ||||
| } | ||||
| 
 | ||||
| // Binds key of type [type] to action keybind.
 | ||||
| /* Binds key of type [type] to action keybind. */ | ||||
| void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) { | ||||
|   int i; | ||||
|   for(i = 0; strcmp(keybindNames[i], "end"); i++) | ||||
| @ -112,7 +112,7 @@ void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) { | ||||
|   WARN("Unable to set keybind '%s', That command does not exist.", keybind); | ||||
| } | ||||
| 
 | ||||
| // Get the value of a keybind.
 | ||||
| /* Get the value of a keybind. */ | ||||
| int input_getKeybind(char* keybind, KeybindType* type, int* reverse) { | ||||
|   int i; | ||||
|   for(i = 0; strcmp(keybindNames[i], "end"); i++) | ||||
| @ -126,14 +126,14 @@ int input_getKeybind(char* keybind, KeybindType* type, int* reverse) { | ||||
|   return -1; | ||||
| } | ||||
| 
 | ||||
| // == Run input method. ================================================
 | ||||
| // keynum : Index of the input_keybinds keybind.
 | ||||
| // value  : Value of keypress (defined above).
 | ||||
| // abs    : Whether or not it's an abs value (For those pesky joysticks.
 | ||||
| // =====================================================================
 | ||||
| /* == Run input method. ================================================ */ | ||||
| /* keynum : Index of the input_keybinds keybind. */ | ||||
| /* value  : Value of keypress (defined above). */ | ||||
| /* abs    : Whether or not it's an abs value (For those pesky joysticks. */ | ||||
| /* ===================================================================== */ | ||||
| #define KEY(s)   (strcmp(input_keybinds[keynum]->name, s)==0) | ||||
| #define INGAME() (!toolkit) | ||||
| // We won't be having any more funny stuff from VLack..
 | ||||
| /* We won't be having any more funny stuff from VLack.. */ | ||||
| #define NOHYP() \ | ||||
|   (player && !pilot_isFlag(player, PILOT_HYP_PREP) && \ | ||||
|   !pilot_isFlag(player, PILOT_HYP_BEGIN) && \ | ||||
| @ -141,16 +141,16 @@ int input_getKeybind(char* keybind, KeybindType* type, int* reverse) { | ||||
| static void input_key(int keynum, double value, int abs) { | ||||
|   unsigned int t; | ||||
| 
 | ||||
|   // Accelerating.
 | ||||
|   /* Accelerating. */ | ||||
|   if(KEY("accel")) { | ||||
|     if(abs)player_accel(value); | ||||
|     else { | ||||
|       // Prevent it from getting stuck.
 | ||||
|       /* Prevent it from getting stuck. */ | ||||
|       if(value == KEY_PRESS) player_accel(1.); | ||||
|       else if(value == KEY_RELEASE) player_accelOver(); | ||||
|     } | ||||
| 
 | ||||
|     // Double tap accel = afterburn!
 | ||||
|     /* Double tap accel = afterburn! */ | ||||
|     t = SDL_GetTicks(); | ||||
|     if((value == KEY_PRESS) && (t-input_accelLast <= input_afterburnSensibility)) | ||||
|       player_afterburn(); | ||||
| @ -159,80 +159,80 @@ static void input_key(int keynum, double value, int abs) { | ||||
| 
 | ||||
|     if(value == KEY_PRESS) input_accelLast = t; | ||||
|   } | ||||
|   // Turning left.
 | ||||
|   /* Turning left. */ | ||||
|   else if(KEY("left")) { | ||||
|     // Set flags for facing correction.
 | ||||
|     /* Set flags for facing correction. */ | ||||
|     if(value == KEY_PRESS) { player_setFlag(PLAYER_TURN_LEFT); } | ||||
|     else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_TURN_LEFT); } | ||||
| 
 | ||||
|     if(abs) { player_turn = -value; } | ||||
|     else { player_turn -= value; } | ||||
|     if(player_turn < -1.) { player_turn = -1.; }// Make sure value is sane.
 | ||||
|     if(player_turn < -1.) { player_turn = -1.; }/* Make sure value is sane. */ | ||||
|   } | ||||
|   // Turning right.
 | ||||
|   /* Turning right. */ | ||||
|   else if(KEY("right")) { | ||||
|     // Set flags for facing correction.
 | ||||
|     /* Set flags for facing correction. */ | ||||
|     if(value == KEY_PRESS) { player_setFlag(PLAYER_TURN_RIGHT); } | ||||
|     else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_TURN_RIGHT); } | ||||
| 
 | ||||
|     if(abs) { player_turn = value; } | ||||
|     else { player_turn += value; } | ||||
| 
 | ||||
|     if(player_turn < -1.) { player_turn = -1.; } // Make sure value is sane.
 | ||||
|     if(player_turn < -1.) { player_turn = -1.; } /* Make sure value is sane. */ | ||||
|   } | ||||
|   // Turn around to face vel.
 | ||||
|   /* Turn around to face vel. */ | ||||
|   else if(KEY("reverse")) { | ||||
|     if(value == KEY_PRESS) { player_setFlag(PLAYER_REVERSE); } | ||||
|     else if(value == KEY_RELEASE) { | ||||
|       player_rmFlag(PLAYER_REVERSE); | ||||
|       player_turn = 0; // Turning corrections.
 | ||||
|       player_turn = 0; /* Turning corrections. */ | ||||
|       if(player_isFlag(PLAYER_TURN_LEFT))  { player_turn -= 1; } | ||||
|       if(player_isFlag(PLAYER_TURN_RIGHT)) { player_turn += 1; } | ||||
|     } | ||||
|   } | ||||
|   // Shoot primary weapon. BOOM BOOM.
 | ||||
|   /* Shoot primary weapon. BOOM BOOM. */ | ||||
|   else if(KEY("primary")) { | ||||
|     if(value == KEY_PRESS) { player_setFlag(PLAYER_PRIMARY); } | ||||
|     else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_PRIMARY); } | ||||
|   } | ||||
|   // Targetting.
 | ||||
|   /* Targetting. */ | ||||
|   else if(INGAME() && KEY("target")) { | ||||
|     if(value == KEY_PRESS) player_target = pilot_getNext(player_target); | ||||
|   } | ||||
|   else if(INGAME() && KEY("target_nearest")) { | ||||
|     if(value == KEY_PRESS) player_target = pilot_getHostile(); | ||||
|   } | ||||
|   // Face the target.
 | ||||
|   /* Face the target. */ | ||||
|   else if(KEY("face")) { | ||||
|     if(value == KEY_PRESS) { player_setFlag(PLAYER_FACE); } | ||||
|     else if(value == KEY_RELEASE) { | ||||
|       player_rmFlag(PLAYER_FACE); | ||||
| 
 | ||||
|       // Turning corrections.
 | ||||
|       /* Turning corrections. */ | ||||
|       player_turn = 0; | ||||
|       if(player_isFlag(PLAYER_TURN_LEFT))  { player_turn -= 1; } | ||||
|       if(player_isFlag(PLAYER_TURN_RIGHT)) { player_turn += 1; } | ||||
|     } | ||||
|   } | ||||
|   // Board those ships.
 | ||||
|   /* Board those ships. */ | ||||
|   else if(KEY("board") && INGAME() && NOHYP()) { | ||||
|     if(value == KEY_PRESS) player_board(); | ||||
|   } | ||||
|   // Shooting secondary weapon.
 | ||||
|   /* Shooting secondary weapon. */ | ||||
|   else if(KEY("secondary") && NOHYP()) { | ||||
|     if(value == KEY_PRESS) { player_setFlag(PLAYER_SECONDARY); } | ||||
|     else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_SECONDARY); } | ||||
|   } | ||||
|   // Selecting secondary weapon.
 | ||||
|   /* Selecting secondary weapon. */ | ||||
|   else if(KEY("secondary_next") && INGAME()) { | ||||
|     if(value == KEY_PRESS) player_secondaryNext(); | ||||
|   } | ||||
|   // Space.
 | ||||
|   // Target planet (cycles just like target).
 | ||||
|   /* Space. */ | ||||
|   /* Target planet (cycles just like target). */ | ||||
|   else if(KEY("target_planet") && INGAME() && NOHYP()) { | ||||
|     if(value == KEY_PRESS) player_targetPlanet(); | ||||
|   } | ||||
|   // Target nearest planet or attempt to land.
 | ||||
|   /* Target nearest planet or attempt to land. */ | ||||
|   else if(KEY("land") && INGAME() && NOHYP()) { | ||||
|     if(value == KEY_PRESS) player_land(); | ||||
|   } | ||||
| @ -245,19 +245,19 @@ static void input_key(int keynum, double value, int abs) { | ||||
|   else if(KEY("jump") && INGAME()) { | ||||
|     if(value == KEY_PRESS) player_jump(); | ||||
|   } | ||||
|   // Zoom in.
 | ||||
|   /* Zoom in. */ | ||||
|   else if(KEY("mapzoomin") && INGAME()) { | ||||
|     if(value == KEY_PRESS) player_setRadarRel(1); | ||||
|   } | ||||
|   // Zoom out.
 | ||||
|   /* Zoom out. */ | ||||
|   else if(KEY("mapzoomout") && INGAME()) { | ||||
|     if(value == KEY_PRESS) player_setRadarRel(-1); | ||||
|   } | ||||
|   // Take a screenshot.
 | ||||
|   /* Take a screenshot. */ | ||||
|   else if(KEY("screenshot") && INGAME()) { | ||||
|     if(value == KEY_PRESS) player_screenshot(); | ||||
|   } | ||||
|   // Pause the game.
 | ||||
|   /* Pause the game. */ | ||||
|   else if(KEY("pause") && NOHYP()) { | ||||
|     if(value == KEY_PRESS) { | ||||
|       if(!toolkit) { | ||||
| @ -265,18 +265,18 @@ static void input_key(int keynum, double value, int abs) { | ||||
|       } else pause_game(); | ||||
|     } | ||||
|   } | ||||
|   // Opens a menu.
 | ||||
|   /* Opens a menu. */ | ||||
|   else if(KEY("menu")) { | ||||
|     if(value == KEY_PRESS) menu_small(); | ||||
|   } | ||||
|   // Show pilot information.
 | ||||
|   /* Show pilot information. */ | ||||
|   else if(KEY("info") && NOHYP()) { | ||||
|     if(value == KEY_PRESS) menu_info(); | ||||
|   } | ||||
| } | ||||
| #undef KEY | ||||
| 
 | ||||
| // --Events--
 | ||||
| /* --Events-- */ | ||||
| 
 | ||||
| static void input_joyaxis(const unsigned int axis, const int value); | ||||
| static void input_joydown(const unsigned int button); | ||||
| @ -284,9 +284,9 @@ static void input_joyup(const unsigned int button); | ||||
| static void input_keydown(SDLKey key); | ||||
| static void input_keyup(SDLKey key); | ||||
| 
 | ||||
| // Joystick.
 | ||||
| /* Joystick. */ | ||||
| 
 | ||||
| // Axis.
 | ||||
| /* Axis. */ | ||||
| static void input_joyaxis(const unsigned int axis, const int value) { | ||||
|   int i; | ||||
|   for(i = 0; strcmp(keybindNames[i], "end"); i++) | ||||
| @ -297,7 +297,7 @@ static void input_joyaxis(const unsigned int axis, const int value) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Joystick button down.
 | ||||
| /* Joystick button down. */ | ||||
| static void input_joydown(const unsigned int button) { | ||||
|   int i; | ||||
|   for(i = 0; strcmp(keybindNames[i], "end");i++) | ||||
| @ -308,7 +308,7 @@ static void input_joydown(const unsigned int button) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Joystick button up.
 | ||||
| /* Joystick button up. */ | ||||
| static void input_joyup(const unsigned int button) { | ||||
|   int i; | ||||
|   for(i = 0; strcmp(keybindNames[i], "end"); i++) | ||||
| @ -319,9 +319,9 @@ static void input_joyup(const unsigned int button) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Keyboard.
 | ||||
| /* Keyboard. */ | ||||
| 
 | ||||
| // Key down.
 | ||||
| /* Key down. */ | ||||
| static void input_keydown(SDLKey key) { | ||||
|   int i; | ||||
|   for(i = 0; strcmp(keybindNames[i], "end"); i++) | ||||
| @ -332,7 +332,7 @@ static void input_keydown(SDLKey key) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Key up.
 | ||||
| /* Key up. */ | ||||
| static void input_keyup(SDLKey key) { | ||||
|   int i; | ||||
|   for(i = 0; strcmp(keybindNames[i], "end"); i++) | ||||
| @ -343,14 +343,14 @@ static void input_keyup(SDLKey key) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Global input.
 | ||||
| /* Global input. */ | ||||
| 
 | ||||
| // Just seperates the event types.
 | ||||
| /* Just seperates the event types. */ | ||||
| void input_handle(SDL_Event* event) { | ||||
|   // Pause the game if it is unfocused.
 | ||||
|   /* Pause the game if it is unfocused. */ | ||||
|   if(event->type == SDL_ACTIVEEVENT) { | ||||
|     if(event->active.state != SDL_APPMOUSEFOCUS) { | ||||
|       // We don't need mouse focus.
 | ||||
|       /* We don't need mouse focus. */ | ||||
|       if((event->active.gain == 0) && !paused) pause_game(); | ||||
|       else if((event->active.gain == 1) && paused) unpause_game(); | ||||
|       return; | ||||
| @ -358,9 +358,9 @@ void input_handle(SDL_Event* event) { | ||||
|   } | ||||
| 
 | ||||
|   if(toolkit) | ||||
|     // Toolkit is handled seperately.
 | ||||
|     /* Toolkit is handled seperately. */ | ||||
|     if(toolkit_input(event)) | ||||
|       return; // We don't process it if toolkit grabs it.
 | ||||
|       return; /* We don't process it if toolkit grabs it. */ | ||||
| 
 | ||||
|   switch(event->type) { | ||||
|   case SDL_JOYAXISMOTION: | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| #pragma once | ||||
| #include <SDL.h> | ||||
| 
 | ||||
| // Input types.
 | ||||
| /* Input types. */ | ||||
| typedef enum { | ||||
|   KEYBIND_NULL, | ||||
|   KEYBIND_KEYBOARD, | ||||
| @ -9,15 +9,15 @@ typedef enum { | ||||
|   KEYBIND_JBUTTON | ||||
| } KeybindType; | ||||
| 
 | ||||
| // Set input.
 | ||||
| /* Set input. */ | ||||
| void input_setDefault(void); | ||||
| void input_setKeybind(char* keybind, KeybindType type, int key, int reverse); | ||||
| int  input_getKeybind(char* keybind, KeybindType* type, int* reverse); | ||||
| 
 | ||||
| // Handle the events.
 | ||||
| /* Handle the events. */ | ||||
| void input_handle(SDL_Event* event); | ||||
| 
 | ||||
| // Init/Exit.
 | ||||
| /* Init/Exit. */ | ||||
| void input_init(void); | ||||
| void input_exit(void); | ||||
| 
 | ||||
|  | ||||
| @ -24,9 +24,9 @@ int joystick_use(int indjoystick) { | ||||
|     indjoystick = 0; | ||||
|   } | ||||
|   if(joystick) | ||||
|     // Might as well close it if it is open already.
 | ||||
|     /* Might as well close it if it is open already. */ | ||||
|     SDL_JoystickClose(joystick); | ||||
|   // Start using the joystick.
 | ||||
|   /* Start using the joystick. */ | ||||
|   LOG("Using joystick %d", indjoystick); | ||||
|   joystick = SDL_JoystickOpen(indjoystick); | ||||
|   if(joystick == NULL) { | ||||
| @ -44,19 +44,19 @@ int joystick_use(int indjoystick) { | ||||
| int joystick_init(void) { | ||||
|   int numjoysticks, i; | ||||
| 
 | ||||
|   // Init the SDL subsys.
 | ||||
|   /* Init the SDL subsys. */ | ||||
|   if(SDL_InitSubSystem(SDL_INIT_JOYSTICK)) { | ||||
|     WARN("Unable to init the joystick subsystem."); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   // Figure out how many joysticks there are.
 | ||||
|   /* Figure out how many joysticks there are. */ | ||||
|   numjoysticks = SDL_NumJoysticks(); | ||||
|   LOG("%d joystick%s detected", numjoysticks, (numjoysticks==1)?"":"s"); | ||||
|   for(i = 0; i < numjoysticks; i++) | ||||
|     LOG("\t\t%d. %s", i, SDL_JoystickName(i)); | ||||
| 
 | ||||
|   // Enable joystick events.
 | ||||
|   /* Enable joystick events. */ | ||||
|   SDL_JoystickEventState(SDL_ENABLE); | ||||
| 
 | ||||
|   return 0; | ||||
|  | ||||
| @ -1,12 +1,12 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| // Get the joystick index number based on its name.
 | ||||
| /* Get the joystick index number based on its name. */ | ||||
| int joystick_get(char* namjoystick); | ||||
| 
 | ||||
| // set the game to use the joystick of index indjoystick.
 | ||||
| /* set the game to use the joystick of index indjoystick. */ | ||||
| int joystick_use(int indjoystick); | ||||
| 
 | ||||
| // Exit functions.
 | ||||
| /* Exit functions. */ | ||||
| int joystick_init(void); | ||||
| void joystick_exit(void); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										184
									
								
								src/land.c
									
									
									
									
									
								
							
							
						
						
									
										184
									
								
								src/land.c
									
									
									
									
									
								
							| @ -17,37 +17,37 @@ | ||||
| #include "music.h" | ||||
| #include "land.h" | ||||
| 
 | ||||
| // Global/main window.
 | ||||
| /* Global/main window. */ | ||||
| #define LAND_WIDTH    700 | ||||
| #define LAND_HEIGHT   600 | ||||
| #define BUTTON_WIDTH  200 | ||||
| #define BUTTON_HEIGHT 40 | ||||
| 
 | ||||
| // Commodity window.
 | ||||
| /* Commodity window. */ | ||||
| #define COMMODITY_WIDTH   400 | ||||
| #define COMMODITY_HEIGHT  400 | ||||
| 
 | ||||
| // Outfits.
 | ||||
| /* Outfits. */ | ||||
| #define OUTFITS_WIDTH   700 | ||||
| #define OUTFITS_HEIGHT  600 | ||||
| 
 | ||||
| // Shipyard.
 | ||||
| /* Shipyard. */ | ||||
| #define SHIPYARD_WIDTH  700 | ||||
| #define SHIPYARD_HEIGHT  600 | ||||
| 
 | ||||
| // News window.
 | ||||
| /* News window. */ | ||||
| #define NEWS_WIDTH    400 | ||||
| #define NEWS_HEIGHT   500 | ||||
| 
 | ||||
| // Bar window.
 | ||||
| /* Bar window. */ | ||||
| #define BAR_WIDTH     460 | ||||
| #define BAR_HEIGHT    300 | ||||
| 
 | ||||
| // Mission computer window.
 | ||||
| /* Mission computer window. */ | ||||
| #define MISSION_WIDTH   700 | ||||
| #define MISSION_HEIGHT  600 | ||||
| 
 | ||||
| // We use visited flags to not duplicate missions generated.
 | ||||
| /* We use visited flags to not duplicate missions generated. */ | ||||
| #define VISITED_LAND      (1<<0) | ||||
| #define VISITED_COMMODITY (1<<1) | ||||
| #define VISITED_BAR       (1<<2) | ||||
| @ -57,30 +57,30 @@ | ||||
| #define has_visited(f)    (land_visited  & (f)) | ||||
| static unsigned int land_visited = 0; | ||||
| 
 | ||||
| // Land variables.
 | ||||
| /* Land variables. */ | ||||
| int landed = 0; | ||||
| Planet* land_planet = NULL; | ||||
| 
 | ||||
| // Mission computer stack.
 | ||||
| /* Mission computer stack. */ | ||||
| static Mission* mission_computer = NULL; | ||||
| static int mission_ncomputer = 0; | ||||
| 
 | ||||
| // Player stuff.
 | ||||
| /* Player stuff. */ | ||||
| extern int hyperspace_target; | ||||
| 
 | ||||
| // Window stuff.
 | ||||
| static int land_wid = 0; // Primary land window.
 | ||||
| // For the second opened land window
 | ||||
| /* Window stuff. */ | ||||
| static int land_wid = 0; /* Primary land window. */ | ||||
| /* For the second opened land window */ | ||||
| static int secondary_wid = 0; | ||||
| static int terciary_wid = 0; // For fancy things like news, your ship etc..
 | ||||
| static int terciary_wid = 0; /* For fancy things like news, your ship etc.. */ | ||||
| 
 | ||||
| // Commodity excahnge.
 | ||||
| /* Commodity excahnge. */ | ||||
| static void commodity_exchange(void); | ||||
| static void commodity_exchange_close(char* str); | ||||
| static void commodity_update(char* str); | ||||
| static void commodity_buy(char* str); | ||||
| static void commodity_sell(char* str); | ||||
| // Outfits.
 | ||||
| /* Outfits. */ | ||||
| static void outfits(void); | ||||
| static void outfits_close(char* str); | ||||
| static void outfits_update(char* str); | ||||
| @ -90,36 +90,36 @@ static int  outfit_canSell(Outfit* outfit, int q, int errmsg); | ||||
| static void outfits_sell(char* str); | ||||
| static int  outfits_getMod(void); | ||||
| static void outfits_renderMod(double bx, double by, double w, double h); | ||||
| // Shipyard.
 | ||||
| /* Shipyard. */ | ||||
| static void shipyard(void); | ||||
| static void shipyard_close(char* str); | ||||
| static void shipyard_update(char* str); | ||||
| static void shipyard_info(char* str); | ||||
| static void shipyard_buy(char* str); | ||||
| // Your ship.
 | ||||
| /* Your ship. */ | ||||
| static void shipyard_yours(char* str); | ||||
| static void shipyard_yoursClose(char* str); | ||||
| static void shipyard_yoursUpdate(char* str); | ||||
| static void shipyard_yoursChange(char* str); | ||||
| static void shipyard_yoursTransport(char* str); | ||||
| static int  shipyard_yoursTransportPrice(char* shipname); | ||||
| // Spaceport bar.
 | ||||
| /* Spaceport bar. */ | ||||
| static void spaceport_bar(void); | ||||
| static void spaceport_bar_close(char* str); | ||||
| // News.
 | ||||
| /* News. */ | ||||
| static void news(void); | ||||
| static void news_close(char* str); | ||||
| // Mission computer.
 | ||||
| /* Mission computer. */ | ||||
| static void misn(void); | ||||
| static void misn_close(char* str); | ||||
| static void misn_accept(char* str); | ||||
| static void misn_genList(int first); | ||||
| static void misn_update(char* str); | ||||
| // Refuel.
 | ||||
| /* Refuel. */ | ||||
| static int refuel_price(void); | ||||
| static void spaceport_refuel(char* str); | ||||
| 
 | ||||
| // The local market.
 | ||||
| /* The local market. */ | ||||
| static void commodity_exchange(void) { | ||||
|   int i; | ||||
|   char** goods; | ||||
| @ -163,7 +163,7 @@ static void commodity_exchange(void) { | ||||
|   commodity_update(NULL); | ||||
| 
 | ||||
|   if(!has_visited(VISITED_COMMODITY)) { | ||||
|     // TODO: mission check.
 | ||||
|     /* TODO: mission check. */ | ||||
|     visited(VISITED_COMMODITY); | ||||
|   } | ||||
| } | ||||
| @ -241,14 +241,14 @@ static void outfits(void) { | ||||
|   int noutfits; | ||||
|   char buf[128]; | ||||
| 
 | ||||
|   // Create window.
 | ||||
|   /* Create window. */ | ||||
|   snprintf(buf, 128, "%s - Outfits", land_planet->name); | ||||
|   secondary_wid = window_create(buf, -1, -1, | ||||
|                                 OUTFITS_WIDTH, OUTFITS_HEIGHT); | ||||
|   // Will allow buying from keyboard.
 | ||||
|   /* Will allow buying from keyboard. */ | ||||
|   window_setFptr(secondary_wid, outfits_buy); | ||||
| 
 | ||||
|   // Buttons.
 | ||||
|   /* Buttons. */ | ||||
|   window_addButton(secondary_wid, -20, 20, | ||||
|                    BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseOutfits", | ||||
|                    "Close", outfits_close); | ||||
| @ -261,7 +261,7 @@ static void outfits(void) { | ||||
|                    BUTTON_WIDTH, BUTTON_HEIGHT, "btnSellOutfit", | ||||
|                    "Sell", outfits_sell); | ||||
| 
 | ||||
|   // Fancy 128x128 image.
 | ||||
|   /* Fancy 128x128 image. */ | ||||
|   window_addRect(secondary_wid, -20, -50, 128, 128, "rctImage", &cBlack, 0); | ||||
|   window_addImage(secondary_wid, -20-128, -50-128, "imgOutfit", NULL, 1); | ||||
| 
 | ||||
| @ -288,17 +288,17 @@ static void outfits(void) { | ||||
|                  OUTFITS_WIDTH-300, 200, 0, "txtDescription", | ||||
|                  &gl_smallFont, NULL, NULL); | ||||
| 
 | ||||
|   // Set up the outfits to buy/sell.
 | ||||
|   /* Set up the outfits to buy/sell. */ | ||||
|   outfits = outfit_getTech(&noutfits, land_planet->tech, PLANET_TECH_MAX); | ||||
|   window_addList(secondary_wid, 20, 40, | ||||
|                  200, OUTFITS_HEIGHT-80, "lstOutfits", | ||||
|                  outfits, noutfits, 0, outfits_update); | ||||
| 
 | ||||
|   // Write the outfits stuff.
 | ||||
|   /* Write the outfits stuff. */ | ||||
|   outfits_update(NULL); | ||||
| 
 | ||||
|   if(!has_visited(VISITED_OUTFITS)) { | ||||
|     // TODO: mission check.
 | ||||
|     /* TODO: mission check. */ | ||||
|     visited(VISITED_OUTFITS); | ||||
|   } | ||||
| } | ||||
| @ -325,13 +325,13 @@ static void outfits_update(char* str) { | ||||
|   else | ||||
|     window_disableButton(secondary_wid, "btnBuyOutfit"); | ||||
| 
 | ||||
|   // Gray out sell button.
 | ||||
|   /* Gray out sell button. */ | ||||
|   if(outfit_canSell(outfit, 1, 0) > 0) | ||||
|     window_enableButton(secondary_wid, "btnSellOutfit"); | ||||
|   else | ||||
|     window_disableButton(secondary_wid, "btnSellOutfit"); | ||||
| 
 | ||||
|   // New text.
 | ||||
|   /* New text. */ | ||||
|   window_modifyText(secondary_wid, "txtDescription", outfit->description); | ||||
|   credits2str(buf2, outfit->price,  2); | ||||
|   credits2str(buf3, player->credits, 2); | ||||
| @ -359,7 +359,7 @@ static void outfits_update(char* str) { | ||||
| static int outfit_canBuy(Outfit* outfit, int q, int errmsg) { | ||||
|   char buf[16]; | ||||
| 
 | ||||
|   // Can player actually fit the outfit?
 | ||||
|   /* Can player actually fit the outfit? */ | ||||
|   if((pilot_freeSpace(player) - outfit->mass) < 0) { | ||||
|     if(errmsg != 0) | ||||
|     dialogue_alert("No enough free space (you need %d more slots).", | ||||
| @ -367,7 +367,7 @@ static int outfit_canBuy(Outfit* outfit, int q, int errmsg) { | ||||
|     return 0; | ||||
|   } | ||||
|   else if(player_outfitOwned(outfit->name) >= outfit->max) { | ||||
|     // Already has too many.
 | ||||
|     /* Already has too many. */ | ||||
|     if(errmsg != 0) | ||||
|       dialogue_alert("You can only carry %d of this outfit.", outfit->max); | ||||
|     return 0; | ||||
| @ -377,14 +377,14 @@ static int outfit_canBuy(Outfit* outfit, int q, int errmsg) { | ||||
|       dialogue_alert("You can only have one afterburner."); | ||||
|     return 0; | ||||
|   } | ||||
|   // Takes away cargo space but you don't have any.
 | ||||
|   /* Takes away cargo space but you don't have any. */ | ||||
|   else if(outfit_isMod(outfit) && (outfit->u.mod.cargo < 0) | ||||
|       && (pilot_cargoFree(player) < -outfit->u.mod.cargo)) { | ||||
|     if(errmsg != 0) | ||||
|       dialogue_alert("You need to empty your cargo first."); | ||||
|     return 0; | ||||
|   } | ||||
|   // Not enough $$.
 | ||||
|   /* Not enough $$. */ | ||||
|   else if(q*(int)outfit->price >= player->credits) { | ||||
|     if(errmsg != 0) { | ||||
|       credits2str(buf, q*outfit->price - player->credits, 2); | ||||
| @ -407,7 +407,7 @@ static void outfits_buy(char* str) { | ||||
| 
 | ||||
|   q = outfits_getMod(); | ||||
| 
 | ||||
|   // Can buy the outfit?
 | ||||
|   /* Can buy the outfit? */ | ||||
|   if(outfit_canBuy(outfit, q, 1) == 0) return; | ||||
| 
 | ||||
|   player->credits -= outfit->price * pilot_addOutfit(player, outfit, | ||||
| @ -416,13 +416,13 @@ static void outfits_buy(char* str) { | ||||
| } | ||||
| 
 | ||||
| static int outfit_canSell(Outfit* outfit, int q, int errmsg) { | ||||
|   // No outfits to sell.
 | ||||
|   /* No outfits to sell. */ | ||||
|   if(player_outfitOwned(outfit->name) <= 0) { | ||||
|     if(errmsg != 0) | ||||
|       dialogue_alert("You can't sell something you don't have!"); | ||||
|     return 0; | ||||
|   } | ||||
|   // Can't sell when you are using it.
 | ||||
|   /* Can't sell when you are using it. */ | ||||
|   else if(outfit_isMod(outfit) && (pilot_cargoFree(player) < outfit->u.mod.cargo * q)) { | ||||
|     if(errmsg != 0) | ||||
|       dialogue_alert("You currently have cargo in this modification."); | ||||
| @ -448,14 +448,14 @@ static void outfits_sell(char* str) { | ||||
| 
 | ||||
|   q = outfits_getMod(); | ||||
| 
 | ||||
|   // Has no outfits to sell.
 | ||||
|   /* Has no outfits to sell. */ | ||||
|   if(outfit_canSell(outfit, q, 1) == 0) return; | ||||
| 
 | ||||
|   player->credits += outfit->price * pilot_rmOutfit(player, outfit, q); | ||||
|   outfits_update(NULL); | ||||
| } | ||||
| 
 | ||||
| // Return the current modifier status.
 | ||||
| /* Return the current modifier status. */ | ||||
| static int outfits_getMod(void) { | ||||
|   SDLMod mods; | ||||
|   int q; | ||||
| @ -531,17 +531,17 @@ static void shipyard(void) { | ||||
|                  SHIPYARD_WIDTH-300, 200, 0, "txtDescription", | ||||
|                  &gl_smallFont, NULL, NULL); | ||||
| 
 | ||||
|   // Setup the ships to buy/sell.
 | ||||
|   /* Setup the ships to buy/sell. */ | ||||
|   ships = ship_getTech(&nships, land_planet->tech, PLANET_TECH_MAX); | ||||
|   window_addList(secondary_wid, 20, 40, | ||||
|                  200, SHIPYARD_HEIGHT-80, "lstShipyard", | ||||
|                  ships, nships, 0, shipyard_update); | ||||
| 
 | ||||
|   // Write the shipyard stuff.
 | ||||
|   /* Write the shipyard stuff. */ | ||||
|   shipyard_update(NULL); | ||||
| 
 | ||||
|   if(!has_visited(VISITED_SHIPYARD)) { | ||||
|     // TODO: mission check.
 | ||||
|     /* TODO: mission check. */ | ||||
|     visited(VISITED_SHIPYARD); | ||||
|   } | ||||
| } | ||||
| @ -619,7 +619,7 @@ static void shipyard_buy(char* str) { | ||||
|   player_newShip(ship, player->solid->pos.x, player->solid->pos.y, | ||||
|                  0., 0., player->solid->dir); | ||||
| 
 | ||||
|   player->credits -= ship->price; // Auch! Paying is hard!
 | ||||
|   player->credits -= ship->price; /* Auch! Paying is hard! */ | ||||
| 
 | ||||
|   shipyard_update(NULL); | ||||
| } | ||||
| @ -698,7 +698,7 @@ static void shipyard_yoursUpdate(char* str) { | ||||
| 
 | ||||
|   shipname = toolkit_getList(terciary_wid, "lstYourShips"); | ||||
|   if(strcmp(shipname, "None")==0) { | ||||
|     // No ships.
 | ||||
|     /* No ships. */ | ||||
|     window_disableButton(terciary_wid, "btnChangeShip"); | ||||
|     window_disableButton(terciary_wid, "btnTransportShip"); | ||||
|     return; | ||||
| @ -707,13 +707,13 @@ static void shipyard_yoursUpdate(char* str) { | ||||
|   loc = player_getLoc(ship->name); | ||||
|   price = shipyard_yoursTransportPrice(shipname); | ||||
| 
 | ||||
|   // Update the image.
 | ||||
|   /* Update the image. */ | ||||
|   window_modifyImage(terciary_wid, "imgTarget", ship->ship->gfx_target); | ||||
| 
 | ||||
|   // Update text.
 | ||||
|   credits2str(buf2, price, 2); // Transport.
 | ||||
|   /* Update text. */ | ||||
|   credits2str(buf2, price, 2); /* Transport. */ | ||||
| 
 | ||||
|   credits2str(buf3, 0, 2); // Sell price.
 | ||||
|   credits2str(buf3, 0, 2); /* Sell price. */ | ||||
|   snprintf(buf, 256, | ||||
|       "%s\n" | ||||
|       "%s\n" | ||||
| @ -740,9 +740,9 @@ static void shipyard_yoursUpdate(char* str) { | ||||
|   window_modifyText(terciary_wid, "txtDOutfits", buf4); | ||||
|   free(buf4); | ||||
| 
 | ||||
|   // Button disabling.
 | ||||
|   /* Button disabling. */ | ||||
|   if(strcmp(land_planet->name, loc)) { | ||||
|     // Ship not here.
 | ||||
|     /* Ship not here. */ | ||||
|     window_disableButton(terciary_wid, "btnChangeShip"); | ||||
|     if(price > player->credits) | ||||
|       window_disableButton(terciary_wid, "btnTransportShip"); | ||||
| @ -761,7 +761,7 @@ static void shipyard_yoursChange(char* str) { | ||||
|   shipname = toolkit_getList(terciary_wid, "lstYourShips"); | ||||
|   newship = player_getShip(shipname); | ||||
|   if(strcmp(shipname, "None")==0) { | ||||
|     // No ships.
 | ||||
|     /* No ships. */ | ||||
|     dialogue_alert("You need another ship to change to!"); | ||||
|     return; | ||||
|   } | ||||
| @ -780,7 +780,7 @@ static void shipyard_yoursChange(char* str) { | ||||
| 
 | ||||
|   player_swapShip(shipname); | ||||
| 
 | ||||
|   // Recreate the window.
 | ||||
|   /* Recreate the window. */ | ||||
|   shipyard_yoursClose(NULL); | ||||
|   shipyard_yours(NULL); | ||||
| } | ||||
| @ -791,30 +791,30 @@ static void shipyard_yoursTransport(char* str) { | ||||
|   char* shipname, buf[16]; | ||||
| 
 | ||||
|   shipname = toolkit_getList(terciary_wid, "lstYourShips"); | ||||
|   if(strcmp(shipname, "None")==0) { // No ships.
 | ||||
|   if(strcmp(shipname, "None")==0) { /* No ships. */ | ||||
|     dialogue_alert("You can't transport nothing here!"); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   price = shipyard_yoursTransportPrice(shipname); | ||||
|   if(price == 0) { | ||||
|     // Already here.
 | ||||
|     /* Already here. */ | ||||
|     dialogue_alert("Your ship '%s' is already here.", shipname); | ||||
|     return; | ||||
|   } | ||||
|   else if(player->credits < price) { | ||||
|     // You are broke.
 | ||||
|     /* You are broke. */ | ||||
|     credits2str(buf, price-player->credits, 2); | ||||
|     dialogue_alert("You need %d more credits to transport '%s' here.", | ||||
|                   buf, shipname); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   // Success.
 | ||||
|   /* Success. */ | ||||
|   player->credits -= price; | ||||
|   player_setLoc(shipname, land_planet->name); | ||||
| 
 | ||||
|   // Update the window to reflect the change.
 | ||||
|   /* Update the window to reflect the change. */ | ||||
|   shipyard_yoursUpdate(NULL); | ||||
| } | ||||
| 
 | ||||
| @ -825,7 +825,7 @@ static int shipyard_yoursTransportPrice(char* shipname) { | ||||
| 
 | ||||
|   ship = player_getShip(shipname); | ||||
|   loc = player_getLoc(shipname); | ||||
|   if(strcmp(loc, land_planet->name)==0) // Already here.
 | ||||
|   if(strcmp(loc, land_planet->name)==0) /* Already here. */ | ||||
|     return 0; | ||||
| 
 | ||||
|   price = (int)ship->solid->mass*500; | ||||
| @ -833,7 +833,7 @@ static int shipyard_yoursTransportPrice(char* shipname) { | ||||
|   return price; | ||||
| } | ||||
| 
 | ||||
| // Spaceport bar.
 | ||||
| /* Spaceport bar. */ | ||||
| static void spaceport_bar(void) { | ||||
|   secondary_wid = window_create("SpacePort Bar", -1, -1, BAR_WIDTH, BAR_HEIGHT); | ||||
| 
 | ||||
| @ -861,7 +861,7 @@ static void spaceport_bar_close(char* str) { | ||||
|   secondary_wid = 0; | ||||
| } | ||||
| 
 | ||||
| // Planet news reports.
 | ||||
| /* Planet news reports. */ | ||||
| static void news(void) { | ||||
|   terciary_wid = window_create("News Reports", | ||||
|                            -1, -1, NEWS_WIDTH, NEWS_HEIGHT); | ||||
| @ -882,12 +882,12 @@ static void news_close(char* str) { | ||||
|   terciary_wid = 0; | ||||
| } | ||||
| 
 | ||||
| // Mission computer, cos' missions rule!
 | ||||
| /* Mission computer, cos' missions rule! */ | ||||
| static void misn(void) { | ||||
|   secondary_wid = window_create("Mission Computer", | ||||
|       -1, -1, MISSION_WIDTH, MISSION_HEIGHT); | ||||
| 
 | ||||
|   // Buttons.
 | ||||
|   /* Buttons. */ | ||||
|   window_addButton(secondary_wid, -20, 20, | ||||
|                    BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseMission", | ||||
|                    "Close", misn_close); | ||||
| @ -896,7 +896,7 @@ static void misn(void) { | ||||
|                    BUTTON_WIDTH, BUTTON_HEIGHT, "btnAcceptMission", | ||||
|                    "Accept", misn_accept); | ||||
| 
 | ||||
|   // Text.
 | ||||
|   /* Text. */ | ||||
|   window_addText(secondary_wid, 300+40, -60, | ||||
|                  300, 40, 0, "txtSReward", | ||||
|                  &gl_smallFont, &cDConsole, "Reward:"); | ||||
| @ -932,7 +932,7 @@ static void misn_accept(char* str) { | ||||
|     pos = toolkit_getListPos(secondary_wid, "lstMission"); | ||||
|     misn = &mission_computer[pos]; | ||||
|     if(mission_accept(misn)) { | ||||
|       // Success is accepting the mission.
 | ||||
|       /* Success is accepting the mission. */ | ||||
|       memmove(misn, &mission_computer[pos+1], | ||||
|           sizeof(Mission) * (mission_ncomputer-pos-1)); | ||||
|       mission_ncomputer--; | ||||
| @ -948,9 +948,9 @@ static void misn_genList(int first) { | ||||
|   if(!first) | ||||
|     window_destroyWidget(secondary_wid, "lstMission"); | ||||
| 
 | ||||
|   // List.
 | ||||
|   /* List. */ | ||||
|   if(mission_ncomputer != 0) { | ||||
|     // there are missions.
 | ||||
|     /* there are missions. */ | ||||
|     misn_names = malloc(sizeof(char*) * mission_ncomputer); | ||||
|     j = 0; | ||||
|     for(i = 0; i < mission_ncomputer; i++) | ||||
| @ -958,7 +958,7 @@ static void misn_genList(int first) { | ||||
|         misn_names[j++] = strdup(mission_computer[i].title); | ||||
|   }  | ||||
|   if((mission_ncomputer == 0) || (j == 0)) { | ||||
|     // No missions.
 | ||||
|     /* No missions. */ | ||||
|     if(j == 0) free(misn_names); | ||||
|     misn_names = malloc(sizeof(char*)); | ||||
|     misn_names[0] = strdup("No Missions"); | ||||
| @ -992,17 +992,17 @@ static void misn_update(char* str) { | ||||
|   window_enableButton(secondary_wid, "btnAcceptMission"); | ||||
| } | ||||
| 
 | ||||
| // Return how much it will cost to refuel the player.
 | ||||
| /* Return how much it will cost to refuel the player. */ | ||||
| static int refuel_price(void) { | ||||
|   return (player->fuel_max - player->fuel)*3; | ||||
| } | ||||
| 
 | ||||
| // Refuel the player.
 | ||||
| /* Refuel the player. */ | ||||
| static void spaceport_refuel(char* str) { | ||||
|   (void)str; | ||||
| 
 | ||||
|   if(player->credits < refuel_price()) { | ||||
|     // Player is out of moniez after landing D:
 | ||||
|     /* Player is out of moniez after landing D: */ | ||||
|     dialogue_alert("You seem to not have enough scred to refuel your ship."); | ||||
|     return; | ||||
|   } | ||||
| @ -1012,23 +1012,23 @@ static void spaceport_refuel(char* str) { | ||||
|   window_destroyWidget(land_wid, "btnRefuel"); | ||||
| } | ||||
| 
 | ||||
| // Land the player.
 | ||||
| /* Land the player. */ | ||||
| void land(Planet* p) { | ||||
|   char buf[32], cred[16]; | ||||
| 
 | ||||
|   if(landed) return; | ||||
| 
 | ||||
|   // Change music.
 | ||||
|   /* Change music. */ | ||||
|   music_choose("land"); | ||||
| 
 | ||||
|   land_planet = p; | ||||
|   land_wid = window_create(p->name, -1, -1, LAND_WIDTH, LAND_HEIGHT); | ||||
| 
 | ||||
|   // Pretty display.
 | ||||
|   /* Pretty display. */ | ||||
|   window_addImage(land_wid, 20, -40, "imgPlanet", p->gfx_exterior, 1); | ||||
|   window_addText(land_wid, 440, 80, LAND_WIDTH-460, 460, 0, | ||||
|                  "txtPlanetDesc", &gl_smallFont, &cBlack, p->description); | ||||
|   // Buttons.
 | ||||
|   /* Buttons. */ | ||||
|   window_addButton(land_wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, | ||||
|                    "btnTakeoff", "Takeoff", (void(*)(char*))takeoff); | ||||
| 
 | ||||
| @ -1047,7 +1047,7 @@ void land(Planet* p) { | ||||
|                      BUTTON_WIDTH, BUTTON_HEIGHT, "btnOutfits", | ||||
|                      "Outfits", (void(*)(char*))outfits); | ||||
| 
 | ||||
|   // Third column.
 | ||||
|   /* Third column. */ | ||||
|   if(planet_hasService(land_planet, PLANET_SERVICE_BASIC)) { | ||||
|     window_addButton(land_wid, 20, 20, | ||||
|                      BUTTON_WIDTH, BUTTON_HEIGHT, "btnNews", | ||||
| @ -1063,7 +1063,7 @@ void land(Planet* p) { | ||||
|       window_addButton(land_wid, -20, 20+2*(BUTTON_HEIGHT+20), | ||||
|           BUTTON_WIDTH, BUTTON_HEIGHT, "btnRefuel", | ||||
|           buf, spaceport_refuel); | ||||
|       if(player->credits < refuel_price()) // Not enough memory.
 | ||||
|       if(player->credits < refuel_price()) /* Not enough memory. */ | ||||
|         window_disableButton(land_wid, "btnRefuel"); | ||||
|     } | ||||
|   } | ||||
| @ -1072,56 +1072,56 @@ void land(Planet* p) { | ||||
|   landed = 1; | ||||
|   hooks_run("land"); | ||||
| 
 | ||||
|   // Generate mission computer stuff.
 | ||||
|   /* Generate mission computer stuff. */ | ||||
|   mission_computer = missions_computer(&mission_ncomputer, | ||||
|       land_planet->faction, land_planet->name, cur_system->name); | ||||
| 
 | ||||
|   if(!has_visited(VISITED_LAND)) { | ||||
|     // TODO: mission check.
 | ||||
|     /* TODO: mission check. */ | ||||
|     visited(VISITED_LAND); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Takeoff from the planet.
 | ||||
| /* Takeoff from the planet. */ | ||||
| void takeoff(void) { | ||||
|   int  sw, sh, i, h; | ||||
|   char* lt; | ||||
| 
 | ||||
|   if(!landed) return; | ||||
| 
 | ||||
|   // The music.
 | ||||
|   /* The music. */ | ||||
|   music_choose("takeoff"); | ||||
| 
 | ||||
|   sw = land_planet->gfx_space->w; | ||||
|   sh = land_planet->gfx_space->h; | ||||
| 
 | ||||
|   // No longer authorized to land.
 | ||||
|   /* No longer authorized to land. */ | ||||
|   player_rmFlag(PLAYER_LANDACK); | ||||
| 
 | ||||
|   // Set player to another position with random facing direction and no velocity.
 | ||||
|   /* Set player to another position with random facing direction and no velocity. */ | ||||
|   player_warp(land_planet->pos.x + RNG(-sw/2, sw/2), | ||||
|       land_planet->pos.y + RNG(-sh/2, sh/2)); | ||||
|   vect_pset(&player->solid->vel, 0., 0.); | ||||
|   player->solid->dir = RNG(0, 359) * M_PI/180.; | ||||
| 
 | ||||
|   // Heal the player.
 | ||||
|   /* Heal the player. */ | ||||
|   player->armour = player->armour_max; | ||||
|   player->shield = player->shield_max; | ||||
|   player->energy = player->energy_max; | ||||
| 
 | ||||
|   // Time goes by, triggers hook before takeoff.
 | ||||
|   /* Time goes by, triggers hook before takeoff. */ | ||||
|   ltime_inc(RNG(2*LTIME_UNIT_LENGTH, 3*LTIME_UNIT_LENGTH)); | ||||
|   lt = ltime_pretty(0); | ||||
|   player_message("taking off from %s on %s", land_planet->name, lt); | ||||
|   free(lt); | ||||
| 
 | ||||
|   // Initialize the new space.
 | ||||
|   /* Initialize the new space. */ | ||||
|   h = hyperspace_target; | ||||
|   space_init(NULL); | ||||
|   hyperspace_target = h; | ||||
| 
 | ||||
|   // Cleanup.
 | ||||
|   save_all(); // Must be before cleaning up planet. Duh!
 | ||||
|   /* Cleanup. */ | ||||
|   save_all(); /* Must be before cleaning up planet. Duh! */ | ||||
|   land_planet = NULL; | ||||
|   window_destroy(land_wid); | ||||
|   landed = 0; | ||||
| @ -1129,7 +1129,7 @@ void takeoff(void) { | ||||
|   hooks_run("takeoff"); | ||||
|   hooks_run("enter"); | ||||
| 
 | ||||
|   // Cleanup mission computer.
 | ||||
|   /* Cleanup mission computer. */ | ||||
|   for(i = 0; i < mission_ncomputer; i++) | ||||
|     mission_cleanup(&mission_computer[i]); | ||||
|   free(mission_computer); | ||||
|  | ||||
							
								
								
									
										208
									
								
								src/lephisto.c
									
									
									
									
									
								
							
							
						
						
									
										208
									
								
								src/lephisto.c
									
									
									
									
									
								
							| @ -41,35 +41,35 @@ | ||||
| #define FONT_SIZE       12 | ||||
| #define FONT_SIZE_SMALL 10 | ||||
| 
 | ||||
| static int quit = 0; // Primary loop.
 | ||||
| unsigned int gtime = 0; // Calculate FPS and movement.
 | ||||
| static int quit = 0; /* Primary loop. */ | ||||
| unsigned int gtime = 0; /* Calculate FPS and movement. */ | ||||
| static char version[VERSION_LEN]; | ||||
| 
 | ||||
| // Just some default crap.
 | ||||
| /* Just some default crap. */ | ||||
| char* data = NULL; | ||||
| char dataname[DATA_NAME_LEN] = ""; | ||||
| int nosound = 0; | ||||
| int show_fps = 1; // Default - True.
 | ||||
| int show_fps = 1; /* Default - True. */ | ||||
| int max_fps = 0; | ||||
| int indjoystick = -1; | ||||
| char* namjoystick = NULL; | ||||
| 
 | ||||
| // Prototypes.
 | ||||
| /* Prototypes. */ | ||||
| static void load_all(void); | ||||
| static void unload_all(void); | ||||
| void main_loop(void); | ||||
| static void display_fps(const double dt); | ||||
| static void window_caption(void); | ||||
| static void data_name(void); | ||||
| // Update.
 | ||||
| /* Update. */ | ||||
| static void fps_control(void); | ||||
| static void update_all(void); | ||||
| static void render_all(void); | ||||
| 
 | ||||
| 
 | ||||
| // @brief The entry point of Lephisto.
 | ||||
| // @param[in] argc Number of arguments.
 | ||||
| // @param[in] argv Array of argc arguments.
 | ||||
| /* @brief The entry point of Lephisto. */ | ||||
| /* @param[in] argc Number of arguments. */ | ||||
| /* @param[in] argv Array of argc arguments. */ | ||||
| #ifdef WIN32 | ||||
| int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, | ||||
|                    int nCmdShow) { | ||||
| @ -81,42 +81,42 @@ int main(int argc, char** argv) { | ||||
| 
 | ||||
|   char buf[PATH_MAX]; | ||||
| 
 | ||||
|   // Print the version.
 | ||||
|   /* Print the version. */ | ||||
|   snprintf(version, VERSION_LEN, "%d.%d.%d", VMAJOR, VMINOR, VREV); | ||||
|   LOG(" "APPNAME" v%s", version); | ||||
| 
 | ||||
|   // Initialize SDL for possible warnings.
 | ||||
|   /* Initialize SDL for possible warnings. */ | ||||
|   SDL_Init(0); | ||||
| 
 | ||||
|   // Input must be initialized for config to work.
 | ||||
|   /* Input must be initialized for config to work. */ | ||||
|   input_init(); | ||||
| 
 | ||||
|   // Create the home directory if needed.
 | ||||
|   /* Create the home directory if needed. */ | ||||
|   if(lfile_dirMakeExist(".")) | ||||
|     WARN("Unable to create lephisto directory '%s'", lfile_basePath()); | ||||
| 
 | ||||
|   // Set the configuration.
 | ||||
|   /* Set the configuration. */ | ||||
|   snprintf(buf, PATH_MAX, "%s"CONF_FILE, lfile_basePath()); | ||||
|   conf_setDefaults(); // Default config values.
 | ||||
|   conf_loadConfig(buf); // Have Lua parse config.
 | ||||
|   conf_parseCLI(argc, argv); // Parse CLI arguments.
 | ||||
|   conf_setDefaults(); /* Default config values. */ | ||||
|   conf_loadConfig(buf); /* Have Lua parse config. */ | ||||
|   conf_parseCLI(argc, argv); /* Parse CLI arguments. */ | ||||
| 
 | ||||
|   // Load the data basics.
 | ||||
|   /* Load the data basics. */ | ||||
|   data_name(); | ||||
|   LOG(" %s", dataname); | ||||
|   DEBUG(); | ||||
| 
 | ||||
|   // Random numbers.
 | ||||
|   /* Random numbers. */ | ||||
|   rng_init(); | ||||
| 
 | ||||
|   if(gl_init()) { | ||||
|     // Initializes video output.
 | ||||
|     /* Initializes video output. */ | ||||
|     ERR("Initializing video output failed, exiting..."); | ||||
|     SDL_Quit(); | ||||
|     exit(EXIT_FAILURE); | ||||
|   } | ||||
| 
 | ||||
|   // See if the data file is valid.
 | ||||
|   /* See if the data file is valid. */ | ||||
|   if(pack_check(data)) { | ||||
|     ERR("Data file '%s' not found", DATA); | ||||
|     WARN("You can specify what data file you want to use with '-d'"); | ||||
| @ -127,7 +127,7 @@ int main(int argc, char** argv) { | ||||
| 
 | ||||
|   window_caption(); | ||||
| 
 | ||||
|   // OpenAL sound.
 | ||||
|   /* OpenAL sound. */ | ||||
|   if(nosound) | ||||
|     LOG("Sound is disabled!"); | ||||
|   else { | ||||
| @ -135,12 +135,12 @@ int main(int argc, char** argv) { | ||||
|     music_choose("load"); | ||||
|   } | ||||
| 
 | ||||
|   // Input.
 | ||||
|   /* Input. */ | ||||
|   if((indjoystick >= 0) || (namjoystick != NULL)) { | ||||
|     if(joystick_init()) | ||||
|       WARN("Error initializing joystick input"); | ||||
|     if(namjoystick != NULL) { | ||||
|       // Use a joystick name to find joystick.
 | ||||
|       /* Use a joystick name to find joystick. */ | ||||
|       if(joystick_use(joystick_get(namjoystick))) { | ||||
|         WARN("Failure to open any joystick, falling back to default keybinds"); | ||||
|         input_setDefault(); | ||||
| @ -148,78 +148,78 @@ int main(int argc, char** argv) { | ||||
|       free(namjoystick); | ||||
|     } | ||||
|     else if(indjoystick >= 0) | ||||
|       // Must be using an id instead.
 | ||||
|       /* Must be using an id instead. */ | ||||
|       if(joystick_use(indjoystick)) { | ||||
|         WARN("Failure to open any joystick, falling back to default keybinds"); | ||||
|         input_setDefault(); | ||||
|       } | ||||
|   } | ||||
| 
 | ||||
|   // Misc.
 | ||||
|   /* Misc. */ | ||||
|   if(ai_init()) | ||||
|     WARN("Error initializing AI"); | ||||
| 
 | ||||
|   // Misc openGL init stuff.
 | ||||
|   gl_fontInit(NULL, NULL, FONT_SIZE); // Init default font size.
 | ||||
|   gl_fontInit(&gl_smallFont, NULL, FONT_SIZE_SMALL); // Small font.
 | ||||
|   gui_init(); // Init the GUI crap.
 | ||||
|   toolkit_init(); // Init the toolkit.
 | ||||
|   /* Misc openGL init stuff. */ | ||||
|   gl_fontInit(NULL, NULL, FONT_SIZE); /* Init default font size. */ | ||||
|   gl_fontInit(&gl_smallFont, NULL, FONT_SIZE_SMALL); /* Small font. */ | ||||
|   gui_init(); /* Init the GUI crap. */ | ||||
|   toolkit_init(); /* Init the toolkit. */ | ||||
| 
 | ||||
|   // Data loading.
 | ||||
|   /* Data loading. */ | ||||
|   load_all(); | ||||
| 
 | ||||
|   menu_main(); | ||||
| 
 | ||||
|   gtime = SDL_GetTicks(); // Init the time.
 | ||||
|   gtime = SDL_GetTicks(); /* Init the time. */ | ||||
| 
 | ||||
|   // Main loop.
 | ||||
|   /* Main loop. */ | ||||
|   SDL_Event event; | ||||
|   // flushes the event loop, since I notices that when the joystick is loaded, it
 | ||||
|   // creates button events that results in the player starting out accelerating.
 | ||||
|   /* flushes the event loop, since I notices that when the joystick is loaded, it */ | ||||
|   /* creates button events that results in the player starting out accelerating. */ | ||||
|   while(SDL_PollEvent(&event)); | ||||
|   while(!quit) { | ||||
|     // Event loop.
 | ||||
|     /* Event loop. */ | ||||
|     while(SDL_PollEvent(&event)) { | ||||
|       if(event.type == SDL_QUIT) quit = 1; // Handle quit.
 | ||||
|       if(event.type == SDL_QUIT) quit = 1; /* Handle quit. */ | ||||
| 
 | ||||
|       input_handle(&event); // handles all the events the player keybinds.
 | ||||
|       input_handle(&event); /* handles all the events the player keybinds. */ | ||||
|     } | ||||
|     main_loop(); | ||||
|   } | ||||
| 
 | ||||
|   // Clean up some stuff.
 | ||||
|   player_cleanup(); // Cleans up the player stuff.
 | ||||
|   gui_free();       // Free up the gui.
 | ||||
|   weapon_exit();    // Destroy all active weapons.
 | ||||
|   space_exit();     // Clean up the universe!!!
 | ||||
|   pilots_free();    // Free the pilots, they where locked up D:
 | ||||
|   space_exit();     // Cleans up the universe itself.
 | ||||
|   /* Clean up some stuff. */ | ||||
|   player_cleanup(); /* Cleans up the player stuff. */ | ||||
|   gui_free();       /* Free up the gui. */ | ||||
|   weapon_exit();    /* Destroy all active weapons. */ | ||||
|   space_exit();     /* Clean up the universe!!! */ | ||||
|   pilots_free();    /* Free the pilots, they where locked up D: */ | ||||
|   space_exit();     /* Cleans up the universe itself. */ | ||||
| 
 | ||||
|   // Unload data.
 | ||||
|   /* Unload data. */ | ||||
|   unload_all(); | ||||
| 
 | ||||
|   // Cleanup opengl fonts.
 | ||||
|   /* Cleanup opengl fonts. */ | ||||
|   gl_freeFont(NULL); | ||||
|   gl_freeFont(&gl_smallFont); | ||||
| 
 | ||||
|   // Exit subsystems.
 | ||||
|   toolkit_exit();   // Kill the toolkit.
 | ||||
|   ai_exit();        // Stop the Lua AI magicness.
 | ||||
|   joystick_exit();  // Release joystick.
 | ||||
|   input_exit();     // Clean up keybindings.
 | ||||
|   gl_exit();        // Kills video output.
 | ||||
|   sound_exit();     // Kills the sound.
 | ||||
|   SDL_Quit();       // Quits SDL.
 | ||||
|   /* Exit subsystems. */ | ||||
|   toolkit_exit();   /* Kill the toolkit. */ | ||||
|   ai_exit();        /* Stop the Lua AI magicness. */ | ||||
|   joystick_exit();  /* Release joystick. */ | ||||
|   input_exit();     /* Clean up keybindings. */ | ||||
|   gl_exit();        /* Kills video output. */ | ||||
|   sound_exit();     /* Kills the sound. */ | ||||
|   SDL_Quit();       /* Quits SDL. */ | ||||
| 
 | ||||
|   // All is good.
 | ||||
|   /* All is good. */ | ||||
|   exit(EXIT_SUCCESS); | ||||
| } | ||||
| 
 | ||||
| void load_all(void) { | ||||
|   // Ordering of these is very important as they are interdependent.
 | ||||
|   /* Ordering of these is very important as they are interdependent. */ | ||||
|   commodity_load(); | ||||
|   factions_load(); // Dep for fleet, space, missions.
 | ||||
|   missions_load(); // No dep.
 | ||||
|   factions_load(); /* Dep for fleet, space, missions. */ | ||||
|   missions_load(); /* No dep. */ | ||||
|   spfx_load(); | ||||
|   outfit_load(); | ||||
|   ships_load(); | ||||
| @ -227,63 +227,63 @@ void load_all(void) { | ||||
|   space_load(); | ||||
| } | ||||
| 
 | ||||
| // @brief Unloads all data, simplifies main().
 | ||||
| /* @brief Unloads all data, simplifies main(). */ | ||||
| void unload_all(void) { | ||||
|   // Data unloading - order should not matter, but inverse load_all is good.
 | ||||
|   /* Data unloading - order should not matter, but inverse load_all is good. */ | ||||
|   fleet_free(); | ||||
|   ships_free(); | ||||
|   outfit_free(); | ||||
|   spfx_free();      // Remove the special effects.
 | ||||
|   spfx_free();      /* Remove the special effects. */ | ||||
|   missions_free(); | ||||
|   factions_free(); | ||||
|   commodity_free(); | ||||
| } | ||||
| 
 | ||||
| // @brief Slip main loop from main() for secondary loop hack in toolkit.c.
 | ||||
| /* @brief Slip main loop from main() for secondary loop hack in toolkit.c. */ | ||||
| void main_loop(void) { | ||||
|   sound_update(); // Do sound stuff.
 | ||||
|   sound_update(); /* Do sound stuff. */ | ||||
| 
 | ||||
|   glClear(GL_COLOR_BUFFER_BIT); | ||||
| 
 | ||||
|   fps_control(); // Everyone loves fps control..
 | ||||
|   if(toolkit) toolkit_update(); // To simulate key repetition.
 | ||||
|   fps_control(); /* Everyone loves fps control.. */ | ||||
|   if(toolkit) toolkit_update(); /* To simulate key repetition. */ | ||||
|   if(!menu_isOpen(MENU_MAIN)) { | ||||
|     if(!paused) update_all(); // Update game.
 | ||||
|     if(!paused) update_all(); /* Update game. */ | ||||
|     render_all(); | ||||
|   } | ||||
|   if(toolkit) toolkit_render(); | ||||
| 
 | ||||
|   gl_checkErr(); // Check error every loop.
 | ||||
|   gl_checkErr(); /* Check error every loop. */ | ||||
| 
 | ||||
|   SDL_GL_SwapBuffers(); | ||||
| } | ||||
| 
 | ||||
| static double fps_dt = 1.; | ||||
| static double dt = 0.; | ||||
| // @brief Controls the FPS.
 | ||||
| /* @brief Controls the FPS. */ | ||||
| static void fps_control(void) { | ||||
|   unsigned int t; | ||||
| 
 | ||||
|   // dt in ms/1000.
 | ||||
|   /* dt in ms/1000. */ | ||||
|   t = SDL_GetTicks(); | ||||
|   dt = (double)(t-gtime)/1000.; | ||||
|   gtime = t; | ||||
| 
 | ||||
|   if(paused) SDL_Delay(10); // Drop paused FPS to be nice to the CPU.
 | ||||
|   if(paused) SDL_Delay(10); /* Drop paused FPS to be nice to the CPU. */ | ||||
| 
 | ||||
|   // If the fps is limited..
 | ||||
|   /* If the fps is limited.. */ | ||||
|   if((max_fps != 0) && (dt < 1./max_fps)) { | ||||
|     double delay = 1./max_fps - dt; | ||||
|     SDL_Delay(delay); | ||||
|     fps_dt += delay; // Make sure it displays the propper FPS.
 | ||||
|     fps_dt += delay; /* Make sure it displays the propper FPS. */ | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // @brief Updates the game itself (player flying around etc).
 | ||||
| /* @brief Updates the game itself (player flying around etc). */ | ||||
| static void update_all(void) { | ||||
| #if 0 | ||||
|   if(dt > 1./30.) { | ||||
|     // Slow timers down and re-run calculations.
 | ||||
|     /* Slow timers down and re-run calculations. */ | ||||
|     pause_delay((unsigned int)dt*1000.); | ||||
|     return; | ||||
|   } | ||||
| @ -294,35 +294,35 @@ static void update_all(void) { | ||||
|   pilots_update(dt); | ||||
| } | ||||
| 
 | ||||
| // @brief == Renders the game. ===========================
 | ||||
| // Blitting order. (layers)
 | ||||
| //
 | ||||
| //    BG  | Stars and planets.
 | ||||
| //        | Background player stuff (planet targetting)
 | ||||
| //        | Background particles.
 | ||||
| //        | Back layer weapons.
 | ||||
| //        X
 | ||||
| //    N   | NPC ships.
 | ||||
| //        | Front layer weapons.
 | ||||
| //        | Normal layer particles (above ships).
 | ||||
| //        X
 | ||||
| //    FG  | Player.
 | ||||
| //        | Foreground particles.
 | ||||
| //        | Text and GUI.
 | ||||
| // ========================================================
 | ||||
| /* @brief == Renders the game. =========================== */ | ||||
| /* Blitting order. (layers) */ | ||||
| /* */ | ||||
| /*    BG  | Stars and planets. */ | ||||
| /*        | Background player stuff (planet targetting) */ | ||||
| /*        | Background particles. */ | ||||
| /*        | Back layer weapons. */ | ||||
| /*        X */ | ||||
| /*    N   | NPC ships. */ | ||||
| /*        | Front layer weapons. */ | ||||
| /*        | Normal layer particles (above ships). */ | ||||
| /*        X */ | ||||
| /*    FG  | Player. */ | ||||
| /*        | Foreground particles. */ | ||||
| /*        | Text and GUI. */ | ||||
| /* ======================================================== */ | ||||
| static void render_all(void) { | ||||
|   // Setup.
 | ||||
|   /* Setup. */ | ||||
|   spfx_start(dt); | ||||
|   // BG.
 | ||||
|   /* BG. */ | ||||
|   space_render(dt); | ||||
|   planets_render(); | ||||
|   player_renderBG(); | ||||
|   weapons_render(WEAPON_LAYER_BG); | ||||
|   // N.
 | ||||
|   /* N. */ | ||||
|   pilots_render(); | ||||
|   weapons_render(WEAPON_LAYER_FG); | ||||
|   spfx_render(SPFX_LAYER_BACK); | ||||
|   // FG.
 | ||||
|   /* FG. */ | ||||
|   player_render(); | ||||
|   spfx_render(SPFX_LAYER_FRONT); | ||||
|   display_fps(dt); | ||||
| @ -331,13 +331,13 @@ static void render_all(void) { | ||||
| 
 | ||||
| static double fps = 0.; | ||||
| static double fps_cur = 0.; | ||||
| // @brief Displays FPS on the screen.
 | ||||
| /* @brief Displays FPS on the screen. */ | ||||
| static void display_fps(const double dt) { | ||||
|   double x, y; | ||||
|   fps_dt += dt; | ||||
|   fps_cur += 1.; | ||||
|   if(fps_dt > 1.) { | ||||
|     // Recalculate every second.
 | ||||
|     /* Recalculate every second. */ | ||||
|     fps = fps_cur / fps_dt; | ||||
|     fps_dt = fps_cur = 0.; | ||||
|   } | ||||
| @ -348,12 +348,12 @@ static void display_fps(const double dt) { | ||||
|     gl_print(NULL, x, y, NULL, "%3.2f", fps); | ||||
| } | ||||
| 
 | ||||
| // @brief Set the data module's name.
 | ||||
| /* @brief Set the data module's name. */ | ||||
| static void data_name(void) { | ||||
|   uint32_t bufsize; | ||||
|   char* buf; | ||||
| 
 | ||||
|   // Check if data file is valid.
 | ||||
|   /* Check if data file is valid. */ | ||||
|   if(pack_check(DATA)) { | ||||
|     ERR("Data file '%s' not found", data); | ||||
|     WARN("You should specify which data file to use with '-d'"); | ||||
| @ -362,7 +362,7 @@ static void data_name(void) { | ||||
|     exit(EXIT_FAILURE); | ||||
|   } | ||||
| 
 | ||||
|   // Check the version.
 | ||||
|   /* Check the version. */ | ||||
|   buf = pack_readfile(DATA, VERSION_FILE, &bufsize); | ||||
| 
 | ||||
|   if(strncmp(buf, version, bufsize) != 0) { | ||||
| @ -372,7 +372,7 @@ static void data_name(void) { | ||||
| 
 | ||||
|   free(buf); | ||||
| 
 | ||||
|   // Load the datafiles name.
 | ||||
|   /* Load the datafiles name. */ | ||||
|   buf = pack_readfile(DATA, START_DATA, &bufsize); | ||||
| 
 | ||||
|   xmlNodePtr node; | ||||
| @ -384,7 +384,7 @@ static void data_name(void) { | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   node = node->xmlChildrenNode; // First node.
 | ||||
|   node = node->xmlChildrenNode; /* First node. */ | ||||
|   if(node == NULL) { | ||||
|     ERR("Malformed '"START_DATA"' file: does not contain elements"); | ||||
|     return; | ||||
| @ -401,7 +401,7 @@ static void data_name(void) { | ||||
|   xmlCleanupParser(); | ||||
| } | ||||
| 
 | ||||
| // @brief Set the window caption.
 | ||||
| /* @brief Set the window caption. */ | ||||
| static void window_caption(void) { | ||||
|   char tmp[DATA_NAME_LEN+10]; | ||||
| 
 | ||||
|  | ||||
| @ -12,18 +12,18 @@ | ||||
| 
 | ||||
| #define pow2(x)  ((x)*(x)) | ||||
| 
 | ||||
| #define DATA_DEF    "data"  // Default data packfile.
 | ||||
| extern char* data;          // Modifiable datafile.
 | ||||
| #define DATA        data    // Data file.
 | ||||
| #define DATA_NAME_LEN 32    // Max length of data name.
 | ||||
| #define DATA_DEF    "data"  /* Default data packfile. */ | ||||
| extern char* data;          /* Modifiable datafile. */ | ||||
| #define DATA        data    /* Data file. */ | ||||
| #define DATA_NAME_LEN 32    /* Max length of data name. */ | ||||
| extern char dataname[DATA_NAME_LEN]; | ||||
| 
 | ||||
| // Max filename path.
 | ||||
| /* Max filename path. */ | ||||
| #ifndef PATH_MAX | ||||
| #  define PATH_MAX 128 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef M_PI | ||||
| #define M_PI 3.14159265358979323846 // Pi.
 | ||||
| #define M_PI 3.14159265358979323846 /* Pi. */ | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										16
									
								
								src/lfile.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/lfile.c
									
									
									
									
									
								
							| @ -14,7 +14,7 @@ | ||||
| #include "log.h" | ||||
| #include "lfile.h" | ||||
| 
 | ||||
| // Return lephisto's base path.
 | ||||
| /* Return lephisto's base path. */ | ||||
| static char lephisto_base[128] = "\0"; | ||||
| char* lfile_basePath(void) { | ||||
|   char* home; | ||||
| @ -29,8 +29,8 @@ char* lfile_basePath(void) { | ||||
|   return lephisto_base; | ||||
| } | ||||
| 
 | ||||
| // Check if a directory exists, and create it if it doesn't.
 | ||||
| // Based on lephisto_base.
 | ||||
| /* Check if a directory exists, and create it if it doesn't. */ | ||||
| /* Based on lephisto_base. */ | ||||
| int lfile_dirMakeExist(char* path) { | ||||
|   char file[PATH_MAX]; | ||||
| 
 | ||||
| @ -54,7 +54,7 @@ int lfile_dirMakeExist(char* path) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Check if a file exists.
 | ||||
| /* Check if a file exists. */ | ||||
| int lfile_fileExists(char* path, ...) { | ||||
|   char file[PATH_MAX], name[PATH_MAX]; | ||||
|   va_list ap; | ||||
| @ -62,7 +62,7 @@ int lfile_fileExists(char* path, ...) { | ||||
| 
 | ||||
|   l = 0; | ||||
|   if(path == NULL) return -1; | ||||
|   else { // Get the message.
 | ||||
|   else { /* Get the message. */ | ||||
|     va_start(ap, path); | ||||
|     vsnprintf(name, PATH_MAX-l, path, ap); | ||||
|     l = strlen(name); | ||||
| @ -73,13 +73,13 @@ int lfile_fileExists(char* path, ...) { | ||||
| #ifdef LINUX | ||||
|   struct stat buf; | ||||
| 
 | ||||
|   if(stat(file, &buf)==0) // Stat worked, file must exist.
 | ||||
|   if(stat(file, &buf)==0) /* Stat worked, file must exist. */ | ||||
|     return 1; | ||||
| #endif | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // List all the files in a dir (besides . and ..).
 | ||||
| /* List all the files in a dir (besides . and ..). */ | ||||
| char** lfile_readDir(int* lfiles, char* path) { | ||||
|   char file[PATH_MAX]; | ||||
|   char** files; | ||||
| @ -119,7 +119,7 @@ char** lfile_readDir(int* lfiles, char* path) { | ||||
|   closedir(d); | ||||
| #endif | ||||
| 
 | ||||
|   // What if we find nothing?
 | ||||
|   /* What if we find nothing? */ | ||||
|   if((*lfiles) == 0) { | ||||
|     free(files); | ||||
|     files = NULL; | ||||
|  | ||||
							
								
								
									
										46
									
								
								src/llua.c
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								src/llua.c
									
									
									
									
									
								
							| @ -10,16 +10,16 @@ | ||||
| #include "lluadef.h" | ||||
| #include "llua.h" | ||||
| 
 | ||||
| // -- Libraries. --
 | ||||
| /* -- Libraries. -- */ | ||||
| 
 | ||||
| // Lephisto.
 | ||||
| /* Lephisto. */ | ||||
| static int lephisto_lang(lua_State* L); | ||||
| static const luaL_reg lephisto_methods[] = { | ||||
|   { "lang", lephisto_lang }, | ||||
|   { 0, 0 } | ||||
| }; | ||||
| 
 | ||||
| // Space.
 | ||||
| /* Space. */ | ||||
| static int space_getPlanet(lua_State* L); | ||||
| static int space_getSystem(lua_State* L); | ||||
| static int space_landName(lua_State* L); | ||||
| @ -34,7 +34,7 @@ static const luaL_reg space_methods[] = { | ||||
|   { 0, 0 } | ||||
| }; | ||||
| 
 | ||||
| // Time.
 | ||||
| /* Time. */ | ||||
| static int time_get(lua_State* L); | ||||
| static int time_str(lua_State* L); | ||||
| static int time_units(lua_State* L); | ||||
| @ -45,14 +45,14 @@ static const luaL_reg time_methods[] = { | ||||
|   {0, 0} | ||||
| }; | ||||
| 
 | ||||
| // RND.
 | ||||
| /* RND. */ | ||||
| static int rnd_int(lua_State*L); | ||||
| static const luaL_reg rnd_methods[] = { | ||||
|   { "int",    rnd_int }, | ||||
|   { 0, 0 } | ||||
| }; | ||||
| 
 | ||||
| // Toolkit.
 | ||||
| /* Toolkit. */ | ||||
| static int tk_msg(lua_State* L); | ||||
| static int tk_yesno(lua_State* L); | ||||
| static int tk_input(lua_State* L); | ||||
| @ -63,7 +63,7 @@ static const luaL_reg tk_methods[] = { | ||||
|   { 0, 0 } | ||||
| }; | ||||
| 
 | ||||
| // Individual libraries.
 | ||||
| /* Individual libraries. */ | ||||
| int lua_loadLephisto(lua_State* L) { | ||||
|   luaL_register(L, "lephisto", lephisto_methods); | ||||
|   return 0; | ||||
| @ -91,14 +91,14 @@ int lua_loadTk(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // -- Lephisto. --
 | ||||
| /* -- Lephisto. -- */ | ||||
| static int lephisto_lang(lua_State* L) { | ||||
|   // TODO: multilanguage stuff.
 | ||||
|   /* TODO: multilanguage stuff. */ | ||||
|   lua_pushstring(L, "en"); | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // -- Space. --
 | ||||
| /* -- Space. -- */ | ||||
| static int space_getPlanet(lua_State* L) { | ||||
|   int i; | ||||
|   int *factions; | ||||
| @ -108,7 +108,7 @@ static int space_getPlanet(lua_State* L) { | ||||
|   char* rndplanet; | ||||
| 
 | ||||
|   if(lua_gettop(L) == 0) { | ||||
|     // Get random planet.
 | ||||
|     /* Get random planet. */ | ||||
|     lua_pushstring(L, space_getRndPlanet()); | ||||
|     return 1; | ||||
|   } | ||||
| @ -121,7 +121,7 @@ static int space_getPlanet(lua_State* L) { | ||||
|     planets = space_getFactionPlanet(&nplanets, &i, 1); | ||||
|   } | ||||
|   else if(lua_istable(L, -1)) { | ||||
|     // Load up the table.
 | ||||
|     /* Load up the table. */ | ||||
|     lua_pushnil(L); | ||||
|     nfactions = (int) lua_gettop(L); | ||||
|     factions = malloc(sizeof(int) * nfactions); | ||||
| @ -130,15 +130,15 @@ static int space_getPlanet(lua_State* L) { | ||||
|       factions[i++] = (int) lua_tonumber(L, -1); | ||||
|       lua_pop(L, 1); | ||||
|     } | ||||
|     // Get the planets.
 | ||||
|     /* Get the planets. */ | ||||
|     planets = space_getFactionPlanet(&nplanets, factions, nfactions); | ||||
|     free(factions); | ||||
|   } | ||||
|   else return 0; // Nothing useful.
 | ||||
|   else return 0; /* Nothing useful. */ | ||||
| 
 | ||||
|   // Choose random planet.
 | ||||
|   /* Choose random planet. */ | ||||
|   if(nplanets == 0) { | ||||
|     // No suitable planet.
 | ||||
|     /* No suitable planet. */ | ||||
|     free(planets); | ||||
|     return 0; | ||||
|   } | ||||
| @ -197,7 +197,7 @@ static int space_jumpDist(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // -- Time. --
 | ||||
| /* -- Time. -- */ | ||||
| static int time_get(lua_State* L) { | ||||
|   lua_pushnumber(L, ltime_get()); | ||||
|   return 1; | ||||
| @ -222,32 +222,32 @@ static int time_units(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // -- RND. --
 | ||||
| /* -- RND. -- */ | ||||
| static int rnd_int(lua_State* L) { | ||||
|   int o; | ||||
| 
 | ||||
|   o = lua_gettop(L); | ||||
| 
 | ||||
|   if(o == 0) lua_pushnumber(L, RNGF()); // Random double o <= x <= 1.
 | ||||
|   if(o == 0) lua_pushnumber(L, RNGF()); /* Random double o <= x <= 1. */ | ||||
|   else if(o == 1) { | ||||
|     // Random int 0 <= x <= param.
 | ||||
|     /* Random int 0 <= x <= param. */ | ||||
|     if(lua_isnumber(L, -1)) | ||||
|       lua_pushnumber(L, RNG(0, (int)lua_tonumber(L, -1))); | ||||
|     else return 0; | ||||
|   } | ||||
|   else if(o >= 2) { | ||||
|     // Random int param 1 <= x <= param 2.
 | ||||
|     /* Random int param 1 <= x <= param 2. */ | ||||
|     if(lua_isnumber(L, -1) && lua_isnumber(L, -2)) | ||||
|       lua_pushnumber(L, RNG((int)lua_tonumber(L, -2), (int)lua_tonumber(L, -1))); | ||||
|     else return 0; | ||||
|   } | ||||
|   else return 0; | ||||
|    | ||||
|   // Unless it's returned 0 already it'll always return param.
 | ||||
|   /* Unless it's returned 0 already it'll always return param. */ | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // -- Toolkit. --
 | ||||
| /* -- Toolkit. -- */ | ||||
| 
 | ||||
| static int tk_msg(lua_State* L) { | ||||
|   char* title, *str; | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| #pragma once | ||||
| #include "lua.h" | ||||
| 
 | ||||
| // Individual libraries.
 | ||||
| int lua_loadLephisto(lua_State* L);   // Always read only.
 | ||||
| /* Individual libraries. */ | ||||
| int lua_loadLephisto(lua_State* L);   /* Always read only. */ | ||||
| int lua_loadSpace(lua_State* L, int readonly); | ||||
| int lua_loadTime(lua_State* L, int readonly); | ||||
| int lua_loadRnd(lua_State* L);        // Always read only.
 | ||||
| int lua_loadTk(lua_State* L);         // Always read only.
 | ||||
| int lua_loadRnd(lua_State* L);        /* Always read only. */ | ||||
| int lua_loadTk(lua_State* L);         /* Always read only. */ | ||||
| 
 | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| #include "lauxlib.h" | ||||
| #include "lualib.h" | ||||
| 
 | ||||
| // Debug stuff.
 | ||||
| /* Debug stuff. */ | ||||
| #define LLUA_DEBUG(str, args...) \ | ||||
|   (fprintf(stdout, "Lua: "str"\n", ## args)) | ||||
| 
 | ||||
| @ -19,7 +19,7 @@ | ||||
|     return 0; \ | ||||
|   } | ||||
| 
 | ||||
| // Comfortability macros.
 | ||||
| /* Comfortability macros. */ | ||||
| #define luaL_dobuffer(L, b, n, s) \ | ||||
|   (luaL_loadbuffer(L, b, n, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										14
									
								
								src/ltime.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/ltime.c
									
									
									
									
									
								
							| @ -7,12 +7,12 @@ | ||||
| 
 | ||||
| static unsigned int lephisto_time = 0; | ||||
| 
 | ||||
| // Get the current time.
 | ||||
| /* Get the current time. */ | ||||
| unsigned int ltime_get(void) { | ||||
|   return lephisto_time; | ||||
| } | ||||
| 
 | ||||
| // Return the time in pretty text.
 | ||||
| /* Return the time in pretty text. */ | ||||
| char* ltime_pretty(unsigned int t) { | ||||
|   unsigned int lt; | ||||
|   int maj, stu; | ||||
| @ -21,24 +21,24 @@ char* ltime_pretty(unsigned int t) { | ||||
|   if(t == 0) lt = lephisto_time; | ||||
|   else lt = t; | ||||
| 
 | ||||
|   // UST (Universal Synchronized Time) - unit is STU (Syncronized Time Unit).
 | ||||
|   /* UST (Universal Synchronized Time) - unit is STU (Syncronized Time Unit). */ | ||||
|   maj = lt / (1000*LTIME_UNIT_LENGTH); | ||||
|   stu = (lt / (LTIME_UNIT_LENGTH)) % 1000; | ||||
|   if(maj == 0) // Only STU.
 | ||||
|   if(maj == 0) /* Only STU. */ | ||||
|     snprintf(str, 128, "%03d STU", stu); | ||||
|   else // Full format.
 | ||||
|   else /* Full format. */ | ||||
|     snprintf(str, 128, "UST %d.%03d", maj, stu); | ||||
|   ret = strdup(str); | ||||
| 
 | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| // Set the time absolutely, does *not* generate an event, used at init.
 | ||||
| /* Set the time absolutely, does *not* generate an event, used at init. */ | ||||
| void ltime_set(unsigned int t) { | ||||
|   lephisto_time = t; | ||||
| } | ||||
| 
 | ||||
| // Set the time relatively.
 | ||||
| /* Set the time relatively. */ | ||||
| void ltime_inc(unsigned int t) { | ||||
|   lephisto_time += t; | ||||
| 
 | ||||
|  | ||||
| @ -1,13 +1,13 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| // How long a 'unit' of time is.
 | ||||
| /* How long a 'unit' of time is. */ | ||||
| #define LTIME_UNIT_LENGTH 1000 | ||||
| 
 | ||||
| // Get.
 | ||||
| /* Get. */ | ||||
| unsigned int ltime_get(void); | ||||
| char* ltime_pretty(unsigned int t); | ||||
| 
 | ||||
| // Set.
 | ||||
| /* Set. */ | ||||
| void ltime_set(unsigned int t); | ||||
| void ltime_inc(unsigned int t); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										86
									
								
								src/map.c
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								src/map.c
									
									
									
									
									
								
							| @ -15,20 +15,20 @@ | ||||
| #define BUTTON_HEIGHT  40 | ||||
| 
 | ||||
| static int   map_wid  = 0; | ||||
| static double map_zoom = 1.;          // Zoom of the map.
 | ||||
| static double map_xpos  = 0.;         // Map position.
 | ||||
| static double map_zoom = 1.;          /* Zoom of the map. */ | ||||
| static double map_xpos  = 0.;         /* Map position. */ | ||||
| static double map_ypos  = 0.; | ||||
| static int map_selected = -1; | ||||
| static StarSystem** map_path = NULL;  // The path to current selected system.
 | ||||
| static StarSystem** map_path = NULL;  /* The path to current selected system. */ | ||||
| static int map_npath = 0; | ||||
| 
 | ||||
| static int map_drag = 0;              // Is the user dragging the map?
 | ||||
| static int map_drag = 0;              /* Is the user dragging the map? */ | ||||
| 
 | ||||
| // Extern.
 | ||||
| // space.c
 | ||||
| /* Extern. */ | ||||
| /* space.c */ | ||||
| extern StarSystem* systems_stack; | ||||
| extern int systems_nstack; | ||||
| // player.c
 | ||||
| /* player.c */ | ||||
| extern int planet_target; | ||||
| extern int hyperspace_target; | ||||
| 
 | ||||
| @ -40,14 +40,14 @@ static void map_mouse(SDL_Event* event, double mx, double my); | ||||
| static void map_buttonZoom(char* str); | ||||
| static void map_selectCur(void); | ||||
| 
 | ||||
| // Open the map window.
 | ||||
| /* Open the map window. */ | ||||
| void map_open(void) { | ||||
|   if(map_wid) { | ||||
|     map_close(NULL); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   // Set the position to focus on current system.
 | ||||
|   /* Set the position to focus on current system. */ | ||||
|   map_xpos = cur_system->pos.x; | ||||
|   map_ypos = cur_system->pos.y; | ||||
| 
 | ||||
| @ -99,7 +99,7 @@ static void map_update(void) { | ||||
|   window_modifyText(map_wid, "txtSysname", sys->name); | ||||
| 
 | ||||
|   if(sys->nplanets == 0) | ||||
|     // No planets -> no factions.
 | ||||
|     /* No planets -> no factions. */ | ||||
|     snprintf(buf, 100, "NA"); | ||||
|   else { | ||||
|     f = -1; | ||||
| @ -108,13 +108,13 @@ static void map_update(void) { | ||||
|         f = sys->planets[i].faction; | ||||
|       else if(f != sys->planets[i].faction && | ||||
|           (sys->planets[i].faction!=0)) { | ||||
|         // TODO: more verbosity.
 | ||||
|         /* TODO: more verbosity. */ | ||||
|         snprintf(buf, 100, "Multiple"); | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|     if(i == sys->nplanets) | ||||
|       // Saw them all, and all the same.
 | ||||
|       /* Saw them all, and all the same. */ | ||||
|       snprintf(buf, 100, "%s", faction_name(f)); | ||||
|   } | ||||
| 
 | ||||
| @ -134,7 +134,7 @@ static void map_update(void) { | ||||
|   window_modifyText(map_wid, "txtPlanets", buf); | ||||
| } | ||||
| 
 | ||||
| // Return 1 if sys is part of the map_path.
 | ||||
| /* Return 1 if sys is part of the map_path. */ | ||||
| static int map_inPath(StarSystem* sys) { | ||||
|   int i, f; | ||||
| 
 | ||||
| @ -148,7 +148,7 @@ static int map_inPath(StarSystem* sys) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Render the map as a custom widget.
 | ||||
| /* Render the map as a custom widget. */ | ||||
| static void map_render(double bx, double by, double w, double h) { | ||||
|   int i, j, n, m; | ||||
|   double x, y, r, tx, ty; | ||||
| @ -158,7 +158,7 @@ static void map_render(double bx, double by, double w, double h) { | ||||
|   r = 5.; | ||||
|   x = (bx - map_xpos + w/2) * 1.; | ||||
|   y = (by - map_ypos + h/2) * 1.; | ||||
|   // Background
 | ||||
|   /* Background */ | ||||
|   COLOUR(cBlack); | ||||
|   glBegin(GL_QUADS); | ||||
|   glVertex2d(bx,   by); | ||||
| @ -167,13 +167,13 @@ static void map_render(double bx, double by, double w, double h) { | ||||
|   glVertex2d(bx+w, by); | ||||
|   glEnd(); | ||||
| 
 | ||||
|   // Render the star systems.
 | ||||
|   /* Render the star systems. */ | ||||
|   for(i = 0; i < systems_nstack; i++) { | ||||
|     sys = &systems_stack[i]; | ||||
| 
 | ||||
|     // Draw the system.
 | ||||
|     /* Draw the system. */ | ||||
|     if(sys == cur_system) COLOUR(cRadar_targ); | ||||
|     else if(sys->nplanets==0) COLOUR(cInert); // TODO: dependant on planet type.
 | ||||
|     else if(sys->nplanets==0) COLOUR(cInert); /* TODO: dependant on planet type. */ | ||||
|     else if(areEnemies(player->faction, sys->faction)) COLOUR(cRed); | ||||
|     else COLOUR(cYellow); | ||||
| 
 | ||||
| @ -181,28 +181,28 @@ static void map_render(double bx, double by, double w, double h) { | ||||
|                         y + sys->pos.y*map_zoom, | ||||
|                         r, bx, by, w, h); | ||||
| 
 | ||||
|     // Draw the system name.
 | ||||
|     /* Draw the system name. */ | ||||
|     tx = x + 7. + sys->pos.x * map_zoom; | ||||
|     ty = y - 5. + sys->pos.y * map_zoom; | ||||
|     gl_print(&gl_smallFont, | ||||
|         tx + SCREEN_W/2., ty + SCREEN_H/2., | ||||
|         &cWhite, sys->name); | ||||
| 
 | ||||
|     // Draw the hyperspace paths.
 | ||||
|     /* Draw the hyperspace paths. */ | ||||
|     glShadeModel(GL_SMOOTH); | ||||
|     // Cheaply use transparency instead of actually
 | ||||
|     // calculating from x to y the line must go. :)
 | ||||
|     /* Cheaply use transparency instead of actually */ | ||||
|     /* calculating from x to y the line must go. :) */ | ||||
|     for(j = 0; j < sys->njumps; j++) { | ||||
|       n = map_inPath(&systems_stack[sys->jumps[j]]); | ||||
|       m = map_inPath(sys); | ||||
|       // Set the colours, is the route the current one?
 | ||||
|       /* Set the colours, is the route the current one? */ | ||||
|       if((hyperspace_target != -1) && | ||||
|           (((cur_system == sys) && (j == hyperspace_target)) || | ||||
|            ((cur_system == &systems_stack[sys->jumps[j]]) && | ||||
|             (sys == &systems_stack[cur_system->jumps[hyperspace_target]])))) | ||||
|         col = &cGreen; | ||||
|       else if((n > 0) && (m > 0)) { | ||||
|         if((n == 2) || (m == 2)) // Out of fuel.
 | ||||
|         if((n == 2) || (m == 2)) /* Out of fuel. */ | ||||
|           col = &cRed; | ||||
|         else | ||||
|           col = &cYellow; | ||||
| @ -225,7 +225,7 @@ static void map_render(double bx, double by, double w, double h) { | ||||
|     } | ||||
|     glShadeModel(GL_FLAT); | ||||
|   } | ||||
|   // Selected planet.
 | ||||
|   /* Selected planet. */ | ||||
|   if(map_selected != -1) { | ||||
|     sys = &systems_stack[map_selected]; | ||||
|     COLOUR(cRed); | ||||
| @ -234,13 +234,13 @@ static void map_render(double bx, double by, double w, double h) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Map event handling.
 | ||||
| /* Map event handling. */ | ||||
| static void map_mouse(SDL_Event* event, double mx, double my) { | ||||
|   int i, j; | ||||
|   double x, y, t; | ||||
|   StarSystem* sys; | ||||
| 
 | ||||
|   t = 13.*15.; // Threshold.
 | ||||
|   t = 13.*15.; /* Threshold. */ | ||||
| 
 | ||||
|   mx -= MAP_WIDTH/2 - map_xpos; | ||||
|   my -= MAP_HEIGHT/2 - map_ypos; | ||||
| @ -252,17 +252,17 @@ static void map_mouse(SDL_Event* event, double mx, double my) { | ||||
|     else if(event->button.button == SDL_BUTTON_WHEELDOWN) | ||||
|       map_buttonZoom("btnZoomIn"); | ||||
| 
 | ||||
|     // Selecting star system.
 | ||||
|     /* Selecting star system. */ | ||||
|     else { | ||||
|       for(i = 0; i < systems_nstack; i++) { | ||||
|         sys = &systems_stack[i]; | ||||
| 
 | ||||
|         // Get position.
 | ||||
|         /* Get position. */ | ||||
|         x = systems_stack[i].pos.x * map_zoom; | ||||
|         y = systems_stack[i].pos.y * map_zoom; | ||||
| 
 | ||||
|         if((pow2(mx-x)+pow2(my-y)) < t) { | ||||
|           // Select the current system and make a path to it.
 | ||||
|           /* Select the current system and make a path to it. */ | ||||
|           map_selected = i; | ||||
|           if(map_path) | ||||
|             free(map_path); | ||||
| @ -272,10 +272,10 @@ static void map_mouse(SDL_Event* event, double mx, double my) { | ||||
|           if(map_npath == 0) | ||||
|             hyperspace_target = -1; | ||||
|           else | ||||
|             // See if it a valid hyperspace target.
 | ||||
|             /* See if it a valid hyperspace target. */ | ||||
|             for(j = 0; j < cur_system->njumps; j++) { | ||||
|               if(map_path[0] == &systems_stack[cur_system->jumps[j]]) { | ||||
|                 planet_target = -1; // Override planet_target.
 | ||||
|                 planet_target = -1; /* Override planet_target. */ | ||||
|                 hyperspace_target = j; | ||||
|                 break; | ||||
|               } | ||||
| @ -294,7 +294,7 @@ static void map_mouse(SDL_Event* event, double mx, double my) { | ||||
| 
 | ||||
|   case SDL_MOUSEMOTION: | ||||
|     if(map_drag) { | ||||
|       // Axis is inverted.
 | ||||
|       /* Axis is inverted. */ | ||||
|       map_xpos -= event->motion.xrel; | ||||
|       map_ypos += event->motion.yrel; | ||||
|     } | ||||
| @ -314,7 +314,7 @@ static void map_buttonZoom(char* str) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Set the map to sane defaults.
 | ||||
| /* Set the map to sane defaults. */ | ||||
| void map_clear(void) { | ||||
|   map_zoom = 1.; | ||||
|   if(cur_system != NULL) { | ||||
| @ -330,7 +330,7 @@ void map_clear(void) { | ||||
|     map_npath = 0; | ||||
|   } | ||||
| 
 | ||||
|   // Default system is current system.
 | ||||
|   /* Default system is current system. */ | ||||
|   map_selectCur(); | ||||
| } | ||||
| 
 | ||||
| @ -344,37 +344,37 @@ static void map_selectCur(void) { | ||||
|       } | ||||
|     } | ||||
|   } else { | ||||
|     // Probably going to seg fault now..
 | ||||
|     /* Probably going to seg fault now.. */ | ||||
|     map_selected = -1; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Update the map after a jump.
 | ||||
| /* Update the map after a jump. */ | ||||
| void map_jump(void) { | ||||
|   int j; | ||||
| 
 | ||||
|   // Set selected system to self.
 | ||||
|   /* Set selected system to self. */ | ||||
|   map_selectCur(); | ||||
| 
 | ||||
|   map_xpos = cur_system->pos.x; | ||||
|   map_ypos = cur_system->pos.y; | ||||
| 
 | ||||
|   // Update path if set.
 | ||||
|   /* Update path if set. */ | ||||
|   if(map_path != NULL) { | ||||
|     map_npath--; | ||||
|     if(map_npath == 0) { | ||||
|       // Path is empty.
 | ||||
|       /* Path is empty. */ | ||||
|       free(map_path); | ||||
|       map_path = NULL; | ||||
|     } else { | ||||
|       // Get rid of bottom of the path.
 | ||||
|       /* Get rid of bottom of the path. */ | ||||
|       memcpy(&map_path[0], &map_path[1], sizeof(StarSystem*) * map_npath); | ||||
|       map_path = realloc(map_path, sizeof(StarSystem*) * map_npath); | ||||
| 
 | ||||
|       // Set the next jump to be the next in path.
 | ||||
|       /* Set the next jump to be the next in path. */ | ||||
|       for(j = 0; j < cur_system->njumps; j++) { | ||||
|         if(map_path[0] == &systems_stack[cur_system->jumps[j]]) { | ||||
|           planet_target = -1; // Override planet_target.
 | ||||
|           planet_target = -1; /* Override planet_target. */ | ||||
|           hyperspace_target = j; | ||||
|           break; | ||||
|         } | ||||
|  | ||||
| @ -1,9 +1,9 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| // Open the map window.
 | ||||
| /* Open the map window. */ | ||||
| void map_open(void); | ||||
| 
 | ||||
| // Misc.
 | ||||
| /* Misc. */ | ||||
| void map_clear(void); | ||||
| void map_jump(void); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										58
									
								
								src/menu.c
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								src/menu.c
									
									
									
									
									
								
							| @ -41,27 +41,27 @@ | ||||
| 
 | ||||
| int menu_open = 0; | ||||
| 
 | ||||
| // Main menu.
 | ||||
| /* Main menu. */ | ||||
| void menu_main_close(void); | ||||
| static void menu_main_load(char* str); | ||||
| static void menu_main_new(char* str); | ||||
| // Small menu.
 | ||||
| /* Small menu. */ | ||||
| static void menu_small_close(char* str); | ||||
| static void edit_options(char* str); | ||||
| static void menu_small_exit(char* str); | ||||
| static void exit_game(void); | ||||
| // Information menu.
 | ||||
| /* Information menu. */ | ||||
| static void menu_info_close(char* str); | ||||
| // Outfits submenu.
 | ||||
| /* Outfits submenu. */ | ||||
| static void info_outfits_menu(char* str); | ||||
| // Mission submenu.
 | ||||
| /* Mission submenu. */ | ||||
| static void info_missions_menu(char* str); | ||||
| static void mission_menu_abort(char* str); | ||||
| static void mission_menu_genList(int first); | ||||
| static void mission_menu_update(char* str); | ||||
| // Death menu.
 | ||||
| /* Death menu. */ | ||||
| static void menu_death_main(char* str); | ||||
| // Generic.
 | ||||
| /* Generic. */ | ||||
| static void menu_generic_close(char* str); | ||||
| 
 | ||||
| void menu_main(void) { | ||||
| @ -70,13 +70,13 @@ void menu_main(void) { | ||||
| 
 | ||||
|   tex = pf_genFractal(SCREEN_W, SCREEN_H, 5.); | ||||
| 
 | ||||
|   // Create background image window.
 | ||||
|   /* Create background image window. */ | ||||
|   bwid = window_create("BG", -1, -1, SCREEN_W, SCREEN_H); | ||||
|   window_addRect(bwid, 0, 0, SCREEN_W, SCREEN_H, "rctBG", &cBlack, 0); | ||||
|   window_addImage(bwid, 0, 0, "imgBG", tex, 0); | ||||
|   window_imgColour(bwid, "imgBG", &cPurple); | ||||
| 
 | ||||
|   // Create menu window.
 | ||||
|   /* Create menu window. */ | ||||
|   wid = window_create("Main Menu", -1, -1, MAIN_WIDTH, MAIN_HEIGHT); | ||||
|   window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*3, | ||||
|                    BUTTON_WIDTH, BUTTON_HEIGHT, | ||||
| @ -115,13 +115,13 @@ static void menu_main_new(char* str) { | ||||
|   player_new(); | ||||
| } | ||||
| 
 | ||||
| // Ze ingame menu.
 | ||||
| // Small ingame menu.
 | ||||
| /* Ze ingame menu. */ | ||||
| /* Small ingame menu. */ | ||||
| void menu_small(void) { | ||||
|   if(menu_isOpen(MENU_MAIN) || | ||||
|      menu_isOpen(MENU_SMALL) || | ||||
|      menu_isOpen(MENU_DEATH)) | ||||
|     return; // It's already open..
 | ||||
|     return; /* It's already open.. */ | ||||
| 
 | ||||
|   unsigned int wid; | ||||
| 
 | ||||
| @ -155,17 +155,17 @@ static void menu_small_exit(char* str) { | ||||
|   menu_main(); | ||||
| } | ||||
| 
 | ||||
| // Edit the options.
 | ||||
| /* Edit the options. */ | ||||
| static void edit_options(char* str) { | ||||
|   (void)str; | ||||
|   // TODO
 | ||||
|   /* TODO */ | ||||
| } | ||||
| 
 | ||||
| // Exit the game.
 | ||||
| /* Exit the game. */ | ||||
| static void exit_game(void) { | ||||
|   // If landed we must save anyways.
 | ||||
|   /* If landed we must save anyways. */ | ||||
|   if(landed) { | ||||
|     // Increment time to match takeoff.
 | ||||
|     /* Increment time to match takeoff. */ | ||||
|     ltime_inc(RNG(2*LTIME_UNIT_LENGTH, 3*LTIME_UNIT_LENGTH)); | ||||
|     save_all(); | ||||
|   } | ||||
| @ -174,7 +174,7 @@ static void exit_game(void) { | ||||
|   SDL_PushEvent(&quit); | ||||
| } | ||||
| 
 | ||||
| // Info menu.
 | ||||
| /* Info menu. */ | ||||
| void menu_info(void) { | ||||
|   if(menu_isOpen(MENU_INFO)) return; | ||||
| 
 | ||||
| @ -183,7 +183,7 @@ void menu_info(void) { | ||||
|   unsigned int wid; | ||||
|   wid = window_create("Info", -1, -1, INFO_WIDTH, INFO_HEIGHT); | ||||
| 
 | ||||
|   // Pilot generics.
 | ||||
|   /* Pilot generics. */ | ||||
|   lt = ltime_pretty(ltime_get()); | ||||
|   window_addText(wid, 20, 20, 120, INFO_HEIGHT-60, | ||||
|                  0, "txtDPilot", &gl_smallFont, &cDConsole, | ||||
| @ -211,7 +211,7 @@ void menu_info(void) { | ||||
|                  0, "txtPilot", &gl_smallFont, &cBlack, str); | ||||
|   free(lt); | ||||
| 
 | ||||
|   // Menu.
 | ||||
|   /* Menu. */ | ||||
|   window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*4 + 20, | ||||
|                    BUTTON_WIDTH, BUTTON_HEIGHT, | ||||
|                    player->ship->name, "Ship", ship_view); | ||||
| @ -261,14 +261,14 @@ static void info_outfits_menu(char* str) { | ||||
|                    "closeOutfits", "Close", menu_generic_close); | ||||
| } | ||||
| 
 | ||||
| // Show the player's active missions.
 | ||||
| /* Show the player's active missions. */ | ||||
| static void info_missions_menu(char* str) { | ||||
|   (void)str; | ||||
|   unsigned int wid; | ||||
| 
 | ||||
|   wid = window_create("Missions", -1, -1, MISSIONS_WIDTH, MISSIONS_HEIGHT); | ||||
| 
 | ||||
|   // Buttons.
 | ||||
|   /* Buttons. */ | ||||
|   window_addButton(wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, | ||||
|                    "closeMissions", "Back", menu_generic_close); | ||||
| 
 | ||||
| @ -276,7 +276,7 @@ static void info_missions_menu(char* str) { | ||||
|                    BUTTON_WIDTH, BUTTON_HEIGHT, "btnAbortMission", "Abort", | ||||
|                    mission_menu_abort); | ||||
| 
 | ||||
|   // Text.
 | ||||
|   /* Text. */ | ||||
|   window_addText(wid, 300+40, -60, | ||||
|                  200, 40, 0, "txtSReward", | ||||
|                  &gl_smallFont, &cDConsole, "Reward:"); | ||||
| @ -288,7 +288,7 @@ static void info_missions_menu(char* str) { | ||||
|                  200, MISSIONS_HEIGHT - BUTTON_WIDTH - 120, 0, | ||||
|                  "txtDesc", &gl_smallFont, &cBlack, NULL); | ||||
| 
 | ||||
|   // List.
 | ||||
|   /* List. */ | ||||
|   mission_menu_genList(1); | ||||
| } | ||||
| 
 | ||||
| @ -302,14 +302,14 @@ static void mission_menu_genList(int first) { | ||||
|   if(!first) | ||||
|     window_destroyWidget(wid, "lstMission"); | ||||
| 
 | ||||
|   // List.
 | ||||
|   /* List. */ | ||||
|   misn_names = malloc(sizeof(char*) * MISSION_MAX); | ||||
|   j = 0; | ||||
|   for(i = 0; i < MISSION_MAX; i++) | ||||
|     if(player_missions[i].id != 0) | ||||
|       misn_names[j++] = strdup(player_missions[i].title); | ||||
|   if(j == 0) { | ||||
|     // No missions.
 | ||||
|     /* No missions. */ | ||||
|     free(misn_names); | ||||
|     misn_names = malloc(sizeof(char*)); | ||||
|     misn_names[0] = strdup("No Missions"); | ||||
| @ -366,7 +366,7 @@ static void mission_menu_abort(char* str) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Pilot dead.
 | ||||
| /* Pilot dead. */ | ||||
| void menu_death(void) { | ||||
|   unsigned int wid; | ||||
|   wid = window_create("Death", -1, -1, DEATH_WIDTH, DEATH_HEIGHT); | ||||
| @ -391,8 +391,8 @@ static void menu_death_main(char* str) { | ||||
|   menu_main(); | ||||
| } | ||||
| 
 | ||||
| // Generic close approach.
 | ||||
| /* Generic close approach. */ | ||||
| static void menu_generic_close(char* str) { | ||||
|   window_destroy(window_get(str+5)); // closeFoo -> Foo.
 | ||||
|   window_destroy(window_get(str+5)); /* closeFoo -> Foo. */ | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										116
									
								
								src/misn_lua.c
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								src/misn_lua.c
									
									
									
									
									
								
							| @ -22,7 +22,7 @@ | ||||
| #include "xml.h" | ||||
| #include "misn_lua.h" | ||||
| 
 | ||||
| // Similar to lua vars, but with less variety.
 | ||||
| /* Similar to lua vars, but with less variety. */ | ||||
| #define MISN_VAR_NIL    0 | ||||
| #define MISN_VAR_NUM    1 | ||||
| #define MISN_VAR_BOOL   2 | ||||
| @ -37,27 +37,27 @@ typedef struct misn_var_ { | ||||
|   } d; | ||||
| } misn_var; | ||||
| 
 | ||||
| // Variable stack.
 | ||||
| /* Variable stack. */ | ||||
| static misn_var* var_stack = NULL; | ||||
| static int var_nstack = 0; | ||||
| static int var_mstack = 0; | ||||
| 
 | ||||
| // Current mission.
 | ||||
| /* Current mission. */ | ||||
| static Mission* cur_mission = NULL; | ||||
| static int misn_delete = 0; // If 1 delete current mission.
 | ||||
| static int misn_delete = 0; /* If 1 delete current mission. */ | ||||
| 
 | ||||
| // Static.
 | ||||
| /* Static. */ | ||||
| static int var_add(misn_var* var); | ||||
| static void var_free(misn_var* var); | ||||
| static unsigned int  hook_generic(lua_State* L, char* stack); | ||||
| // Extern.
 | ||||
| /* Extern. */ | ||||
| int misn_run(Mission* misn, char* func); | ||||
| int var_save(xmlTextWriterPtr writer); | ||||
| int var_load(xmlNodePtr parent); | ||||
| 
 | ||||
| // -- Libraries. --
 | ||||
| /* -- Libraries. -- */ | ||||
| 
 | ||||
| // Mission.
 | ||||
| /* Mission. */ | ||||
| static int misn_setTitle(lua_State* L); | ||||
| static int misn_setDesc(lua_State* L); | ||||
| static int misn_setReward(lua_State* L); | ||||
| @ -74,7 +74,7 @@ static const luaL_reg misn_methods[] = { | ||||
|   { 0, 0 } | ||||
| }; | ||||
| 
 | ||||
| // Var.
 | ||||
| /* Var. */ | ||||
| static int var_peek(lua_State* L); | ||||
| static int var_pop(lua_State* L); | ||||
| static int var_push(lua_State* L); | ||||
| @ -85,13 +85,13 @@ static const luaL_reg var_methods[] = { | ||||
|   {0, 0} | ||||
| }; | ||||
| 
 | ||||
| // Only conditional.
 | ||||
| /* Only conditional. */ | ||||
| static const luaL_reg var_cond_methods[] = { | ||||
|   { "peek", var_peek }, | ||||
|   {0, 0 } | ||||
| }; | ||||
| 
 | ||||
| // Player.
 | ||||
| /* Player. */ | ||||
| static int player_getname(lua_State* L); | ||||
| static int player_shipname(lua_State* L); | ||||
| static int player_freeSpace(lua_State* L); | ||||
| @ -114,7 +114,7 @@ static const luaL_reg player_methods[] = { | ||||
|   { 0, 0 } | ||||
| }; | ||||
| 
 | ||||
| // Hooks.
 | ||||
| /* Hooks. */ | ||||
| static int hook_land(lua_State* L); | ||||
| static int hook_takeoff(lua_State* L); | ||||
| static int hook_time(lua_State* L); | ||||
| @ -129,7 +129,7 @@ static const luaL_reg hook_methods[] = { | ||||
|   { 0, 0 } | ||||
| }; | ||||
| 
 | ||||
| // Pilots.
 | ||||
| /* Pilots. */ | ||||
| static int pilot_addFleet(lua_State* L); | ||||
| static int pilot_rename(lua_State* L); | ||||
| static const luaL_reg pilot_methods[] = { | ||||
| @ -138,7 +138,7 @@ static const luaL_reg pilot_methods[] = { | ||||
|   { 0, 0 } | ||||
| }; | ||||
| 
 | ||||
| // Register all the libaries.
 | ||||
| /* Register all the libaries. */ | ||||
| int misn_loadLibs(lua_State* L) { | ||||
|   lua_loadLephisto(L); | ||||
|   lua_loadMisn(L); | ||||
| @ -159,7 +159,7 @@ int misn_loadCondLibs(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Individual libarary loading.
 | ||||
| /* Individual libarary loading. */ | ||||
| int lua_loadMisn(lua_State* L) { | ||||
|   luaL_register(L, "misn",      misn_methods); | ||||
|   return 0; | ||||
| @ -188,9 +188,9 @@ int lua_loadPilot(lua_State* L) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Run a mission function.
 | ||||
| //
 | ||||
| // -1 on error, 1 on misn.finish() call and 0 normally.
 | ||||
| /* Run a mission function. */ | ||||
| /* */ | ||||
| /* -1 on error, 1 on misn.finish() call and 0 normally. */ | ||||
| int misn_run(Mission* misn, char* func) { | ||||
|   int i, ret; | ||||
|   char* err; | ||||
| @ -200,7 +200,7 @@ int misn_run(Mission* misn, char* func) { | ||||
| 
 | ||||
|   lua_getglobal(misn->L, func); | ||||
|   if((ret = lua_pcall(misn->L, 0, 0, 0))) { | ||||
|     // Did an oops.
 | ||||
|     /* Did an oops. */ | ||||
|     err = (lua_isstring(misn->L, -1)) ? (char*) lua_tostring(misn->L, -1) : NULL; | ||||
|     if(strcmp(err, "Mission Done")) | ||||
|       WARN("Mission '%s' -> '%s' : %s", | ||||
| @ -208,7 +208,7 @@ int misn_run(Mission* misn, char* func) { | ||||
|     else ret = 1; | ||||
|   } | ||||
| 
 | ||||
|   // Mission is finished.
 | ||||
|   /* Mission is finished. */ | ||||
|   if(misn_delete) { | ||||
|     mission_cleanup(cur_mission); | ||||
|     for(i = 0; i < MISSION_MAX; i++) | ||||
| @ -223,7 +223,7 @@ int misn_run(Mission* misn, char* func) { | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| // Save the mission variables.
 | ||||
| /* Save the mission variables. */ | ||||
| int var_save(xmlTextWriterPtr writer) { | ||||
|   int i; | ||||
| 
 | ||||
| @ -251,14 +251,14 @@ int var_save(xmlTextWriterPtr writer) { | ||||
|         xmlw_str(writer, var_stack[i].d.str); | ||||
|         break; | ||||
|     } | ||||
|     xmlw_endElem(writer); // var.
 | ||||
|     xmlw_endElem(writer); /* var. */ | ||||
|   } | ||||
|   xmlw_endElem(writer); // vars.
 | ||||
|   xmlw_endElem(writer); /* vars. */ | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Load the vars.
 | ||||
| /* Load the vars. */ | ||||
| int var_load(xmlNodePtr parent) { | ||||
|   char* str; | ||||
|   xmlNodePtr node, cur; | ||||
| @ -290,7 +290,7 @@ int var_load(xmlNodePtr parent) { | ||||
|             var.type = MISN_VAR_STR; | ||||
|             var.d.str = atoi(xml_get(cur)); | ||||
|           } else { | ||||
|             // Supeh error checking.
 | ||||
|             /* Supeh error checking. */ | ||||
|             WARN("Unknown var type '%s'", str); | ||||
|             free(var.name); | ||||
|             continue; | ||||
| @ -305,17 +305,17 @@ int var_load(xmlNodePtr parent) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Add a var to the stack, strings will be SHARED, don't free!!!
 | ||||
| /* Add a var to the stack, strings will be SHARED, don't free!!! */ | ||||
| static int var_add(misn_var* new_var) { | ||||
|   int i; | ||||
| 
 | ||||
|   if(var_nstack+1 > var_mstack) { | ||||
|     // More memory.
 | ||||
|     var_mstack += 64; // Overkill much??
 | ||||
|     /* More memory. */ | ||||
|     var_mstack += 64; /* Overkill much?? */ | ||||
|     var_stack = realloc(var_stack, var_mstack * sizeof(misn_var)); | ||||
|   } | ||||
| 
 | ||||
|   // Check if already exists.
 | ||||
|   /* Check if already exists. */ | ||||
|   for(i = 0; i < var_nstack; i++) | ||||
|     if(strcmp(new_var->name, var_stack[i].name)==0) { | ||||
|       var_free(&var_stack[i]); | ||||
| @ -329,13 +329,13 @@ static int var_add(misn_var* new_var) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // -- Mission. --
 | ||||
| /* -- Mission. -- */ | ||||
| 
 | ||||
| static int misn_setTitle(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(1); | ||||
|   if(lua_isstring(L, -1)) { | ||||
|     if(cur_mission->title) | ||||
|       // Cleanup the old title.
 | ||||
|       /* Cleanup the old title. */ | ||||
|       free(cur_mission->title); | ||||
|     cur_mission->title = strdup((char*)lua_tostring(L, -1)); | ||||
|   } | ||||
| @ -346,7 +346,7 @@ static int misn_setDesc(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(1); | ||||
|   if(lua_isstring(L, -1)) { | ||||
|     if(cur_mission->desc) | ||||
|       // Cleanup the old description.
 | ||||
|       /* Cleanup the old description. */ | ||||
|       free(cur_mission->desc); | ||||
|     cur_mission->desc = strdup((char*)lua_tostring(L, -1)); | ||||
|   } | ||||
| @ -357,7 +357,7 @@ static int misn_setReward(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(1); | ||||
|   if(lua_isstring(L, -1)) { | ||||
|     if(cur_mission->reward) | ||||
|       // Cleanup the old reward.
 | ||||
|       /* Cleanup the old reward. */ | ||||
|       free(cur_mission->reward); | ||||
|     cur_mission->reward = strdup((char*)lua_tostring(L, -1)); | ||||
|   } | ||||
| @ -370,12 +370,12 @@ static int misn_factions(lua_State* L) { | ||||
| 
 | ||||
|   dat = cur_mission->data; | ||||
| 
 | ||||
|   // We'll push all the factions in table form.
 | ||||
|   /* We'll push all the factions in table form. */ | ||||
|   lua_newtable(L); | ||||
|   for(i = 0; i < dat->avail.nfactions; i++) { | ||||
|     lua_pushnumber(L, i+1);   // Index, starts with 1.
 | ||||
|     lua_pushnumber(L, dat->avail.factions[i]); // Value.
 | ||||
|     lua_rawset(L, -3);  // Store the value in the table.
 | ||||
|     lua_pushnumber(L, i+1);   /* Index, starts with 1. */ | ||||
|     lua_pushnumber(L, dat->avail.factions[i]); /* Value. */ | ||||
|     lua_rawset(L, -3);  /* Store the value in the table. */ | ||||
|   } | ||||
|   return 1; | ||||
| } | ||||
| @ -385,18 +385,18 @@ static int misn_accept(lua_State* L) { | ||||
| 
 | ||||
|   ret = 0; | ||||
| 
 | ||||
|   // Find the last mission.
 | ||||
|   /* Find the last mission. */ | ||||
|   for(i = 0; i < MISSION_MAX; i++) | ||||
|     if(player_missions[i].data == NULL) break; | ||||
| 
 | ||||
|   // No missions left.
 | ||||
|   /* No missions left. */ | ||||
|   if(i >= MISSION_MAX) ret = 1; | ||||
|   else { | ||||
|     memcpy(&player_missions[i], cur_mission, sizeof(Mission)); | ||||
|     memset(cur_mission, 0, sizeof(Mission)); | ||||
|     cur_mission = &player_missions[i]; | ||||
|   } | ||||
|   lua_pushboolean(L, !ret); // We'll convert C style return to lua.
 | ||||
|   lua_pushboolean(L, !ret); /* We'll convert C style return to lua. */ | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| @ -406,7 +406,7 @@ static int misn_finish(lua_State* L) { | ||||
|   if(lua_isboolean(L, -1)) b = lua_toboolean(L, -1); | ||||
|   else { | ||||
|     lua_pushstring(L, "Mission Done"); | ||||
|     lua_error(L); // THERE IS NO RETURN!
 | ||||
|     lua_error(L); /* THERE IS NO RETURN! */ | ||||
|     return 0; | ||||
|   } | ||||
|    | ||||
| @ -416,14 +416,14 @@ static int misn_finish(lua_State* L) { | ||||
|     player_missionFinished(mission_getID(cur_mission->data->name)); | ||||
| 
 | ||||
|   lua_pushstring(L, "Mission Done"); | ||||
|   lua_error(L); // Should not return..
 | ||||
|   lua_error(L); /* Should not return.. */ | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // -- Var. --
 | ||||
| /* -- Var. -- */ | ||||
| 
 | ||||
| // Check if a variable exists.
 | ||||
| /* Check if a variable exists. */ | ||||
| int var_checkflag(char* str) { | ||||
|   int i; | ||||
|   for(i = 0; i < var_nstack; i++) | ||||
| @ -500,7 +500,7 @@ static int var_push(lua_State* L) { | ||||
| 
 | ||||
|   var.name = strdup(str); | ||||
| 
 | ||||
|   // Store appropriate data.
 | ||||
|   /* Store appropriate data. */ | ||||
|   if(lua_isnil(L, -1)) | ||||
|     var.type = MISN_VAR_NIL; | ||||
|   else if(lua_isnumber(L, -1)) { | ||||
| @ -554,7 +554,7 @@ void var_cleanup(void) { | ||||
|   var_mstack = 0; | ||||
| } | ||||
| 
 | ||||
| // -- Player. --
 | ||||
| /* -- Player. -- */ | ||||
| 
 | ||||
| static int player_getname(lua_State* L) { | ||||
|   lua_pushstring(L, player_name); | ||||
| @ -655,14 +655,14 @@ static int player_getFaction(lua_State* L) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // -- HOOK --
 | ||||
| /* -- HOOK -- */ | ||||
| static unsigned int hook_generic(lua_State* L, char* stack) { | ||||
|   int i; | ||||
|   char* func; | ||||
|    | ||||
|   LLUA_MIN_ARGS(1); | ||||
|    | ||||
|   // Make sure mission is a player mission.
 | ||||
|   /* Make sure mission is a player mission. */ | ||||
|   for(i = 0; i < MISSION_MAX; i++) | ||||
|     if(player_missions[i].id == cur_mission->id) | ||||
|       break; | ||||
| @ -707,13 +707,13 @@ static int hook_pilotDeath(lua_State* L) { | ||||
|   if(lua_isnumber(L, -2)) p = (unsigned int) lua_tonumber(L, -2); | ||||
|   else LLUA_INVALID_PARAMETER(); | ||||
| 
 | ||||
|   h = hook_generic(L, "death"); // We won't actually call the death stack directly.
 | ||||
|   h = hook_generic(L, "death"); /* We won't actually call the death stack directly. */ | ||||
|   pilot_addHook(pilot_get(p), PILOT_HOOK_DEATH, h); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // -- Pilot. --
 | ||||
| /* -- Pilot. -- */ | ||||
| static int pilot_addFleet(lua_State* L) { | ||||
|   LLUA_MIN_ARGS(1); | ||||
|   Fleet* flt; | ||||
| @ -726,23 +726,23 @@ static int pilot_addFleet(lua_State* L) { | ||||
|   if(lua_isstring(L, -1)) fltname = (char*) lua_tostring(L, -1); | ||||
|   else LLUA_INVALID_PARAMETER(); | ||||
| 
 | ||||
|   // Pull the fleet.
 | ||||
|   /* Pull the fleet. */ | ||||
|   flt = fleet_get(fltname); | ||||
|   if(flt == NULL) { | ||||
|     LLUA_DEBUG("Fleet not found!"); | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   // This should probably be done better..
 | ||||
|   /* This should probably be done better.. */ | ||||
|   vect_pset(&vp, RNG(MIN_HYPERSPACE_DIST, MIN_HYPERSPACE_DIST*1.5), | ||||
|       RNG(0, 360)*M_PI/180.); | ||||
|   vectnull(&vn); | ||||
| 
 | ||||
|   // Now we start adding pilots and toss ids into the table we return.
 | ||||
|   /* Now we start adding pilots and toss ids into the table we return. */ | ||||
|   j = 0; | ||||
|   for(i = 0; i < flt->npilots; i++) { | ||||
|     if(RNG(0, 100) <= flt->pilots[i].chance) { | ||||
|       // Fleet displacement.
 | ||||
|       /* Fleet displacement. */ | ||||
|       vect_cadd(&vp, RNG(75, 150) & (RNG(0, 1) ? 1: -1), | ||||
|           RNG(75, 150) * (RNG(0, 1) ? 1 : -1)); | ||||
| 
 | ||||
| @ -757,10 +757,10 @@ static int pilot_addFleet(lua_State* L) { | ||||
|           &vv, | ||||
|           0); | ||||
| 
 | ||||
|       // We push each pilot created into a table and return it.
 | ||||
|       lua_pushnumber(L, ++j); // Index start with 1.
 | ||||
|       lua_pushnumber(L, p);   // value = pilot id.
 | ||||
|       lua_rawset(L, -3);      // Store the value in the table.
 | ||||
|       /* We push each pilot created into a table and return it. */ | ||||
|       lua_pushnumber(L, ++j); /* Index start with 1. */ | ||||
|       lua_pushnumber(L, p);   /* value = pilot id. */ | ||||
|       lua_rawset(L, -3);      /* Store the value in the table. */ | ||||
|     } | ||||
|   } | ||||
|   return 1; | ||||
|  | ||||
| @ -2,15 +2,15 @@ | ||||
| 
 | ||||
| #include "lua.h" | ||||
| 
 | ||||
| // Check if a flag exists on the variable stack.
 | ||||
| /* Check if a flag exists on the variable stack. */ | ||||
| int var_checkflag(char* str); | ||||
| void var_cleanup(void); | ||||
| 
 | ||||
| // Load the libraries for a lua state.
 | ||||
| /* Load the libraries for a lua state. */ | ||||
| int misn_loadLibs(lua_State* L); | ||||
| int misn_loadCondLibs(lua_State* L); // Safe read only stuff.
 | ||||
| int misn_loadCondLibs(lua_State* L); /* Safe read only stuff. */ | ||||
| 
 | ||||
| // Individual library stuff.
 | ||||
| /* Individual library stuff. */ | ||||
| int lua_loadMisn(lua_State* L); | ||||
| int lua_loadVar(lua_State* L, int readonly); | ||||
| int lua_loadPlayer(lua_State* L); | ||||
|  | ||||
							
								
								
									
										142
									
								
								src/mission.c
									
									
									
									
									
								
							
							
						
						
									
										142
									
								
								src/mission.c
									
									
									
									
									
								
							| @ -14,24 +14,24 @@ | ||||
| #include "player.h" | ||||
| #include "mission.h" | ||||
| 
 | ||||
| #define XML_MISSION_ID    "Missions"  // XML section identifier.
 | ||||
| #define XML_MISSION_ID    "Missions"  /* XML section identifier. */ | ||||
| #define XML_MISSION_TAG   "mission" | ||||
| 
 | ||||
| #define MISSION_DATA      "../dat/mission.xml" | ||||
| #define MISSION_LUA_PATH  "../dat/missions/" | ||||
| 
 | ||||
| // Current player missions.
 | ||||
| /* Current player missions. */ | ||||
| static unsigned int mission_id = 0; | ||||
| Mission player_missions[MISSION_MAX]; | ||||
| 
 | ||||
| // Mission stack.
 | ||||
| static MissionData* mission_stack = NULL; // Unmuteable after creation.
 | ||||
| /* Mission stack. */ | ||||
| static MissionData* mission_stack = NULL; /* Unmuteable after creation. */ | ||||
| static int mission_nstack = 0; | ||||
| 
 | ||||
| // Extern.
 | ||||
| /* Extern. */ | ||||
| extern int misn_run(Mission* misn, char* func); | ||||
| 
 | ||||
| // Static.
 | ||||
| /* Static. */ | ||||
| static unsigned int mission_genID(void); | ||||
| static int  mission_init(Mission* mission, MissionData* misn, int load); | ||||
| static void mission_freeData(MissionData* mission); | ||||
| @ -44,24 +44,24 @@ static MissionData* mission_parse(const xmlNodePtr parent); | ||||
| static int  missions_parseActive(xmlNodePtr parent); | ||||
| static int  mission_persistData(lua_State* L, xmlTextWriterPtr writer); | ||||
| static int  mission_unpersistData(lua_State* L, xmlNodePtr parent); | ||||
| // Extern.
 | ||||
| /* Extern. */ | ||||
| int missions_saveActive(xmlTextWriterPtr writer); | ||||
| int missions_loadActive(xmlNodePtr parent); | ||||
| 
 | ||||
| // Generate a new id for the mission.
 | ||||
| /* Generate a new id for the mission. */ | ||||
| static unsigned int mission_genID(void) { | ||||
|   unsigned int id; | ||||
|   int i; | ||||
|   id = ++mission_id; // Default id, not safe if loading.
 | ||||
|   id = ++mission_id; /* Default id, not safe if loading. */ | ||||
| 
 | ||||
|   // We save mission id's, so check for collisions with players missions.
 | ||||
|   /* We save mission id's, so check for collisions with players missions. */ | ||||
|   for(i = 0; i < MISSION_MAX; i++) | ||||
|     if(id == player_missions[i].id)   // Mission id was loaded from save.
 | ||||
|       return mission_genID();         // Recursive try again.
 | ||||
|     if(id == player_missions[i].id)   /* Mission id was loaded from save. */ | ||||
|       return mission_genID();         /* Recursive try again. */ | ||||
|   return id; | ||||
| } | ||||
| 
 | ||||
| // Gets the ID from mission name.
 | ||||
| /* Gets the ID from mission name. */ | ||||
| int mission_getID(char* name) { | ||||
|   int i; | ||||
|   for(i = 0; i < mission_nstack; i++) | ||||
| @ -72,13 +72,13 @@ int mission_getID(char* name) { | ||||
|   return -1; | ||||
| } | ||||
| 
 | ||||
| // Get a MissionData based on ID.
 | ||||
| /* Get a MissionData based on ID. */ | ||||
| MissionData* mission_get(int id) { | ||||
|   if((id <= 0) || (mission_nstack < id)) return NULL; | ||||
|   return &mission_stack[id]; | ||||
| } | ||||
| 
 | ||||
| // Initialize a mission.
 | ||||
| /* Initialize a mission. */ | ||||
| static int mission_init(Mission* mission, MissionData* misn, int load) { | ||||
|   char* buf; | ||||
|   uint32_t bufsize; | ||||
| @ -90,23 +90,23 @@ static int mission_init(Mission* mission, MissionData* misn, int load) { | ||||
| 
 | ||||
|   mission->data = misn; | ||||
| 
 | ||||
|   // Sane defaults.
 | ||||
|   /* Sane defaults. */ | ||||
|   mission->title    = NULL; | ||||
|   mission->desc     = NULL; | ||||
|   mission->reward   = NULL; | ||||
|   mission->cargo    = NULL; | ||||
|   mission->ncargo   = 0; | ||||
| 
 | ||||
|   // Init lua.
 | ||||
|   /* Init lua. */ | ||||
|   mission->L = luaL_newstate(); | ||||
|   if(mission->L == NULL) { | ||||
|     ERR("Unable to create a new lua state."); | ||||
|     return -1; | ||||
|   } | ||||
|    | ||||
|   //luaopen_base(mission->L);   // Can be useful.
 | ||||
|   luaopen_string(mission->L); // string.format can be very useful.
 | ||||
|   misn_loadLibs(mission->L);  // Load our custom libraries.
 | ||||
|   /*luaopen_base(mission->L);   // Can be useful. */ | ||||
|   luaopen_string(mission->L); /* string.format can be very useful. */ | ||||
|   misn_loadLibs(mission->L);  /* Load our custom libraries. */ | ||||
| 
 | ||||
|   buf = pack_readfile(DATA, misn->lua, &bufsize); | ||||
|   if(luaL_dobuffer(mission->L, buf, bufsize, misn->lua) != 0) { | ||||
| @ -117,14 +117,14 @@ static int mission_init(Mission* mission, MissionData* misn, int load) { | ||||
|   } | ||||
|   free(buf); | ||||
| 
 | ||||
|   // Run create function.
 | ||||
|   if(load == 0) // Never run when loading.
 | ||||
|   /* Run create function. */ | ||||
|   if(load == 0) /* Never run when loading. */ | ||||
|     misn_run(mission, "create"); | ||||
| 
 | ||||
|   return mission->id; | ||||
| } | ||||
| 
 | ||||
| // Small wrapper for misn_run.
 | ||||
| /* Small wrapper for misn_run. */ | ||||
| int mission_accept(Mission* mission) { | ||||
|   int ret; | ||||
|   ret = misn_run(mission, "accept"); | ||||
| @ -132,7 +132,7 @@ int mission_accept(Mission* mission) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Check to see if mission is already running.
 | ||||
| /* Check to see if mission is already running. */ | ||||
| static int mission_alreadyRunning(MissionData* misn) { | ||||
|   int i; | ||||
|   for (i = 0; i < MISSION_MAX; i++) | ||||
| @ -142,14 +142,14 @@ static int mission_alreadyRunning(MissionData* misn) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Is the lua condition for misn met?
 | ||||
| /* Is the lua condition for misn met? */ | ||||
| static lua_State* mission_cond_L = NULL; | ||||
| static int mission_meetCond(MissionData* misn) { | ||||
|   int ret; | ||||
|   char buf[256]; | ||||
| 
 | ||||
|   if(mission_cond_L == NULL) { | ||||
|     // Must create the conditional environment.
 | ||||
|     /* Must create the conditional environment. */ | ||||
|     mission_cond_L = luaL_newstate(); | ||||
|     misn_loadCondLibs(mission_cond_L); | ||||
|   } | ||||
| @ -196,31 +196,31 @@ static int mission_meetCond(MissionData* misn) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Does the mission meet the minimum requirements?
 | ||||
| /* Does the mission meet the minimum requirements? */ | ||||
| static int mission_meetReq(int mission, int faction, char* planet, char* system) { | ||||
|   MissionData* misn; | ||||
| 
 | ||||
|   misn = &mission_stack[mission]; | ||||
|    | ||||
|   // Must match planet, system or faction.
 | ||||
|   /* Must match planet, system or faction. */ | ||||
|   if(!(((misn->avail.planet && strcmp(misn->avail.planet, planet)==0)) || | ||||
|         (misn->avail.system && (strcmp(misn->avail.system, system)==0)) || | ||||
|       mission_matchFaction(misn, faction))) | ||||
|     return 0; | ||||
| 
 | ||||
|   if(mis_isFlag(misn, MISSION_UNIQUE) && // Mission done, or running.
 | ||||
|   if(mis_isFlag(misn, MISSION_UNIQUE) && /* Mission done, or running. */ | ||||
|       (player_missionAlreadyDone(mission) || | ||||
|        mission_alreadyRunning(misn))) | ||||
|     return 0; | ||||
| 
 | ||||
|   if((misn->avail.cond != NULL) && // Mission doesn't meet the requirement.
 | ||||
|   if((misn->avail.cond != NULL) && /* Mission doesn't meet the requirement. */ | ||||
|       !mission_meetCond(misn)) | ||||
|     return 0; | ||||
| 
 | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Runs bar missions, all lua side and one-shot.
 | ||||
| /* Runs bar missions, all lua side and one-shot. */ | ||||
| void missions_bar(int faction, char* planet, char* system) { | ||||
|   MissionData* misn; | ||||
|   Mission mission; | ||||
| @ -237,20 +237,20 @@ void missions_bar(int faction, char* planet, char* system) { | ||||
| 
 | ||||
|       if(RNGF() < chance) { | ||||
|         mission_init(&mission, misn, 0); | ||||
|         mission_cleanup(&mission); // It better clean up for itself or we do it.
 | ||||
|         mission_cleanup(&mission); /* It better clean up for itself or we do it. */ | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Links cargo to the mission for posterior cleanup.
 | ||||
| /* Links cargo to the mission for posterior cleanup. */ | ||||
| void mission_linkCargo(Mission* misn, unsigned int cargo_id) { | ||||
|   misn->ncargo++; | ||||
|   misn->cargo = realloc(misn->cargo, sizeof(unsigned int) * misn->ncargo); | ||||
|   misn->cargo[misn->ncargo-1] = cargo_id; | ||||
| } | ||||
| 
 | ||||
| // Unlink cargo from the mission, removes it from the player.
 | ||||
| /* Unlink cargo from the mission, removes it from the player. */ | ||||
| void mission_unlinkCargo(Mission* misn, unsigned int cargo_id) { | ||||
|   int i; | ||||
| 
 | ||||
| @ -258,13 +258,13 @@ void mission_unlinkCargo(Mission* misn, unsigned int cargo_id) { | ||||
|     if(misn->cargo[i] == cargo_id) | ||||
|       break; | ||||
| 
 | ||||
|   if(i >= misn->ncargo) { // Not found.
 | ||||
|   if(i >= misn->ncargo) { /* Not found. */ | ||||
|     DEBUG("Mission '%s' attempting to unlink in existant cargo %d.", | ||||
|         misn->title, cargo_id); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   // Shrink cargo size - No need to realloc.
 | ||||
|   /* Shrink cargo size - No need to realloc. */ | ||||
|   memmove(&misn->cargo[i], &misn->cargo[i+1], | ||||
|       sizeof(unsigned int) * (misn->ncargo-i-1)); | ||||
| 
 | ||||
| @ -272,11 +272,11 @@ void mission_unlinkCargo(Mission* misn, unsigned int cargo_id) { | ||||
|   player_rmMissionCargo(cargo_id); | ||||
| } | ||||
| 
 | ||||
| // Clean up a mission.
 | ||||
| /* Clean up a mission. */ | ||||
| void mission_cleanup(Mission* misn) { | ||||
|   int i; | ||||
|   if(misn->id != 0) { | ||||
|     hook_rmParent(misn->id); // Remove existing hooks.
 | ||||
|     hook_rmParent(misn->id); /* Remove existing hooks. */ | ||||
|     misn->id = 0; | ||||
|   } | ||||
|   if(misn->title != NULL) { | ||||
| @ -304,7 +304,7 @@ void mission_cleanup(Mission* misn) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Free a mission.
 | ||||
| /* Free a mission. */ | ||||
| static void mission_freeData(MissionData* mission) { | ||||
|   if(mission->name)           free(mission->name); | ||||
|   if(mission->lua)            free(mission->lua); | ||||
| @ -314,7 +314,7 @@ static void mission_freeData(MissionData* mission) { | ||||
|   memset(mission, 0, sizeof(MissionData)); | ||||
| } | ||||
| 
 | ||||
| // Does mission match faction requirement?
 | ||||
| /* Does mission match faction requirement? */ | ||||
| static int mission_matchFaction(MissionData* misn, int faction) { | ||||
|   int i; | ||||
| 
 | ||||
| @ -328,7 +328,7 @@ static int mission_matchFaction(MissionData* misn, int faction) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Generate missions for the computer - special case.
 | ||||
| /* Generate missions for the computer - special case. */ | ||||
| Mission* missions_computer(int* n, int faction, char* planet, char* system) { | ||||
|   int i, j, m; | ||||
|   double chance; | ||||
| @ -348,7 +348,7 @@ Mission* missions_computer(int* n, int faction, char* planet, char* system) { | ||||
|       rep = misn->avail.chance/100; | ||||
| 
 | ||||
|       for(j = 0; j < rep; j++) | ||||
|         // Random chance of rep appearances.
 | ||||
|         /* Random chance of rep appearances. */ | ||||
|         if(RNGF() < chance) { | ||||
|           tmp = realloc(tmp, sizeof(Mission) * ++m); | ||||
|           mission_init(&tmp[m-1], misn, 0); | ||||
| @ -359,7 +359,7 @@ Mission* missions_computer(int* n, int faction, char* planet, char* system) { | ||||
|   return tmp; | ||||
| } | ||||
| 
 | ||||
| // Return location based on string.
 | ||||
| /* Return location based on string. */ | ||||
| static int mission_location(char* loc) { | ||||
|   if(strcmp(loc,      "None")==0)       return MIS_AVAIL_NONE; | ||||
|   else if(strcmp(loc, "Computer")==0)   return MIS_AVAIL_COMPUTER; | ||||
| @ -371,7 +371,7 @@ static int mission_location(char* loc) { | ||||
|   return -1; | ||||
| } | ||||
| 
 | ||||
| // Parse a node of a mission.
 | ||||
| /* Parse a node of a mission. */ | ||||
| static MissionData* mission_parse(const xmlNodePtr parent) { | ||||
|   MissionData* tmp; | ||||
|   xmlNodePtr cur, node; | ||||
| @ -379,7 +379,7 @@ static MissionData* mission_parse(const xmlNodePtr parent) { | ||||
|   tmp = malloc(sizeof(MissionData)); | ||||
|   memset(tmp, 0, sizeof(MissionData)); | ||||
| 
 | ||||
|   // Get the name.
 | ||||
|   /* Get the name. */ | ||||
|   tmp->name = xml_nodeProp(parent, "name"); | ||||
|   if(tmp->name == NULL) WARN("Mission in "MISSION_DATA" has invalid or no name"); | ||||
| 
 | ||||
| @ -387,21 +387,21 @@ static MissionData* mission_parse(const xmlNodePtr parent) { | ||||
| 
 | ||||
|   char str[PATH_MAX] = "\0"; | ||||
| 
 | ||||
|   // Load all the data.
 | ||||
|   /* Load all the data. */ | ||||
|   do { | ||||
|     if(xml_isNode(node, "lua")) { | ||||
|       snprintf(str, PATH_MAX, MISSION_LUA_PATH"%s.lua", xml_get(node)); | ||||
|       tmp->lua = strdup(str); | ||||
|       str[0] = '\0'; | ||||
|     } | ||||
|     else if(xml_isNode(node, "flags")) { // Set the various flags.
 | ||||
|     else if(xml_isNode(node, "flags")) { /* Set the various flags. */ | ||||
|       cur = node->children; | ||||
|       do { | ||||
|         if(xml_isNode(cur, "unique")) | ||||
|           mis_setFlag(tmp, MISSION_UNIQUE); | ||||
|       } while(xml_nextNode(cur)); | ||||
|     } | ||||
|     else if(xml_isNode(node, "avail")) { // Mission availability.
 | ||||
|     else if(xml_isNode(node, "avail")) { /* Mission availability. */ | ||||
|       cur = node->children; | ||||
|       do { | ||||
|         if(xml_isNode(cur, "location")) | ||||
| @ -438,7 +438,7 @@ static MissionData* mission_parse(const xmlNodePtr parent) { | ||||
|   return tmp; | ||||
| } | ||||
| 
 | ||||
| // Load/Free.
 | ||||
| /* Load/Free. */ | ||||
| int missions_load(void) { | ||||
|   uint32_t bufsize; | ||||
|   char* buf = pack_readfile(DATA, MISSION_DATA, &bufsize); | ||||
| @ -455,7 +455,7 @@ int missions_load(void) { | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   node = node->xmlChildrenNode; // First mission node.
 | ||||
|   node = node->xmlChildrenNode; /* First mission node. */ | ||||
|   if(node == NULL) { | ||||
|     ERR("Malformed '"MISSION_DATA"' file: does not contain elements"); | ||||
|     return -1; | ||||
| @ -483,7 +483,7 @@ int missions_load(void) { | ||||
| void missions_free(void) { | ||||
|   int i; | ||||
| 
 | ||||
|   // Free the mission data.
 | ||||
|   /* Free the mission data. */ | ||||
|   for(i = 0; i < mission_nstack; i++) | ||||
|     mission_freeData(&mission_stack[i]); | ||||
|   free(mission_stack); | ||||
| @ -503,7 +503,7 @@ void missions_cleanup(void) { | ||||
|     mission_cleanup(&player_missions[i]); | ||||
| } | ||||
| 
 | ||||
| // Persists partial lua data.
 | ||||
| /* Persists partial lua data. */ | ||||
| static int mission_saveData(xmlTextWriterPtr writer, char* type, | ||||
|     char* name, char* value) { | ||||
| 
 | ||||
| @ -513,16 +513,16 @@ static int mission_saveData(xmlTextWriterPtr writer, char* type, | ||||
|   xmlw_attr(writer, "name", name); | ||||
|   xmlw_str(writer, "%s", value); | ||||
|    | ||||
|   xmlw_endElem(writer); // data.
 | ||||
|   xmlw_endElem(writer); /* data. */ | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| static int mission_persistData(lua_State* L, xmlTextWriterPtr writer) { | ||||
|   lua_pushnil(L); | ||||
|   // nil.
 | ||||
|   /* nil. */ | ||||
|   while(lua_next(L, LUA_GLOBALSINDEX) != 0) { | ||||
|     // key, value.
 | ||||
|     /* key, value. */ | ||||
|     switch(lua_type(L, -1)) { | ||||
|       case LUA_TNUMBER: | ||||
|         mission_saveData(writer, "number", | ||||
| @ -540,12 +540,12 @@ static int mission_persistData(lua_State* L, xmlTextWriterPtr writer) { | ||||
|         break; | ||||
|     } | ||||
|     lua_pop(L, 1); | ||||
|     // Key.
 | ||||
|     /* Key. */ | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Unpersist lua data.
 | ||||
| /* Unpersist lua data. */ | ||||
| static int mission_unpersistData(lua_State* L, xmlNodePtr parent) { | ||||
|   xmlNodePtr node; | ||||
|   char* name, *type; | ||||
| @ -556,7 +556,7 @@ static int mission_unpersistData(lua_State* L, xmlNodePtr parent) { | ||||
|       xmlr_attr(node, "name", name); | ||||
|       xmlr_attr(node, "type", type); | ||||
| 
 | ||||
|       // Handle data types.
 | ||||
|       /* Handle data types. */ | ||||
|       if(strcmp(type, "number")==0) | ||||
|         lua_pushnumber(L, xml_getFloat(node)); | ||||
|       else if(strcmp(type, "bool")==0) | ||||
| @ -587,7 +587,7 @@ int missions_saveActive(xmlTextWriterPtr writer) { | ||||
|     if(player_missions[i].id != 0) { | ||||
|       xmlw_startElem(writer, "mission"); | ||||
| 
 | ||||
|       // Data and id are attributes because they must be loaded first.
 | ||||
|       /* Data and id are attributes because they must be loaded first. */ | ||||
|       xmlw_attr(writer, "data", player_missions[i].data->name); | ||||
|       xmlw_attr(writer, "id", "%u", player_missions[i].id); | ||||
| 
 | ||||
| @ -598,20 +598,20 @@ int missions_saveActive(xmlTextWriterPtr writer) { | ||||
|       xmlw_startElem(writer, "cargos"); | ||||
|       for(j = 0; j < player_missions[i].ncargo; j++) | ||||
|         xmlw_elem(writer, "cargo", "%u", player_missions[i].cargo[j]); | ||||
|       xmlw_endElem(writer); // Cargo.
 | ||||
|       xmlw_endElem(writer); /* Cargo. */ | ||||
| 
 | ||||
|       // Write lua magic.
 | ||||
|       /* Write lua magic. */ | ||||
|       xmlw_startElem(writer, "lua"); | ||||
| 
 | ||||
|       // Prepare the data.
 | ||||
|       /* Prepare the data. */ | ||||
|       mission_persistData(player_missions[i].L, writer); | ||||
| 
 | ||||
|       xmlw_endElem(writer); // Lua.
 | ||||
|       xmlw_endElem(writer); /* Lua. */ | ||||
|        | ||||
|       xmlw_endElem(writer); // Mission.
 | ||||
|       xmlw_endElem(writer); /* Mission. */ | ||||
|     } | ||||
|   } | ||||
|   xmlw_endElem(writer); // Missions.
 | ||||
|   xmlw_endElem(writer); /* Missions. */ | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| @ -619,7 +619,7 @@ int missions_saveActive(xmlTextWriterPtr writer) { | ||||
| int missions_loadActive(xmlNodePtr parent) { | ||||
|   xmlNodePtr node; | ||||
| 
 | ||||
|   // Cleanup old missions.
 | ||||
|   /* Cleanup old missions. */ | ||||
|   missions_cleanup(); | ||||
| 
 | ||||
|   node = parent->xmlChildrenNode; | ||||
| @ -638,18 +638,18 @@ static int missions_parseActive(xmlNodePtr parent) { | ||||
| 
 | ||||
|   xmlNodePtr node, cur, nest; | ||||
| 
 | ||||
|   m = 0; // Start with mission 0.
 | ||||
|   m = 0; /* Start with mission 0. */ | ||||
|   node = parent->xmlChildrenNode; | ||||
|   do { | ||||
|     if(xml_isNode(node, "mission")) { | ||||
|       misn = &player_missions[m]; | ||||
| 
 | ||||
|       // Process the attributes to create the mission.
 | ||||
|       /* Process the attributes to create the mission. */ | ||||
|       xmlr_attr(node, "data", buf); | ||||
|       mission_init(misn, mission_get(mission_getID(buf)), 1); | ||||
|       free(buf); | ||||
| 
 | ||||
|       // This will orphan an identifier.
 | ||||
|       /* This will orphan an identifier. */ | ||||
|       xmlr_attr(node, "id", buf); | ||||
|       misn->id = atol(buf); | ||||
|       free(buf); | ||||
| @ -669,12 +669,12 @@ static int missions_parseActive(xmlNodePtr parent) { | ||||
|         } | ||||
| 
 | ||||
|         if(xml_isNode(cur, "lua")) | ||||
|           // Start the unpersist routine.
 | ||||
|           /* Start the unpersist routine. */ | ||||
|           mission_unpersistData(misn->L, cur); | ||||
|       } while(xml_nextNode(cur)); | ||||
| 
 | ||||
|       m++; | ||||
|       if(m >= MISSION_MAX) break; // Full of missions, must be an error.
 | ||||
|       if(m >= MISSION_MAX) break; /* Full of missions, must be an error. */ | ||||
|     } | ||||
|   } while(xml_nextNode(node)); | ||||
| 
 | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| #pragma once | ||||
| #include "misn_lua.h" | ||||
| 
 | ||||
| // Availability by location.
 | ||||
| /* Availability by location. */ | ||||
| #define MIS_AVAIL_NONE        0 | ||||
| #define MIS_AVAIL_COMPUTER    1 | ||||
| #define MIS_AVAIL_BAR         2 | ||||
| @ -9,73 +9,73 @@ | ||||
| #define MIS_AVAIL_SHIPYARD    4 | ||||
| #define MIS_AVAIL_LAND        5 | ||||
| 
 | ||||
| // Flags.
 | ||||
| /* Flags. */ | ||||
| #define mis_isFlag(m,f)   ((m)->flags  & (f)) | ||||
| #define mis_setFlag(m,f)  ((m)->flags |= (f)) | ||||
| #define mis_rmFlag(m,f)   ((m)->flags ^= (f)) | ||||
| 
 | ||||
| #define MISSION_UNIQUE        1 // Unique missions can't be repeated.
 | ||||
| #define MISSION_UNIQUE        1 /* Unique missions can't be repeated. */ | ||||
| 
 | ||||
| // Static mission data.
 | ||||
| /* Static mission data. */ | ||||
| typedef struct MissionData_ { | ||||
|   char* name; // the name of the mission.
 | ||||
|   char* name; /* the name of the mission. */ | ||||
| 
 | ||||
|   // Availability.
 | ||||
|   /* Availability. */ | ||||
|   struct { | ||||
|     int loc;      // Location.
 | ||||
|     int chance;   // Chance of it appearing.
 | ||||
|     int loc;      /* Location. */ | ||||
|     int chance;   /* Chance of it appearing. */ | ||||
| 
 | ||||
|     // For specific cases.
 | ||||
|     /* For specific cases. */ | ||||
|     char* planet; | ||||
|     char* system; | ||||
| 
 | ||||
|     // For generic cases.
 | ||||
|     /* For generic cases. */ | ||||
|     int* factions; | ||||
|     int nfactions; | ||||
| 
 | ||||
|     char* cond;   // Conditional that must be met.
 | ||||
|     char* cond;   /* Conditional that must be met. */ | ||||
|   } avail; | ||||
| 
 | ||||
|   unsigned int flags; // Flags to store binary properties.
 | ||||
|   unsigned int flags; /* Flags to store binary properties. */ | ||||
| 
 | ||||
|   char* lua; | ||||
| } MissionData; | ||||
| 
 | ||||
| // Active mission.
 | ||||
| /* Active mission. */ | ||||
| typedef struct Mission_ { | ||||
|   MissionData* data; | ||||
|   // Unique mission identifier, used for keeping track of hooks.
 | ||||
|   /* Unique mission identifier, used for keeping track of hooks. */ | ||||
|   unsigned int id; | ||||
| 
 | ||||
|   char* title;  // Not to be confused with name..
 | ||||
|   char* desc;   // Description of the mission.
 | ||||
|   char* reward; // Rewards - in text.
 | ||||
|   char* title;  /* Not to be confused with name.. */ | ||||
|   char* desc;   /* Description of the mission. */ | ||||
|   char* reward; /* Rewards - in text. */ | ||||
| 
 | ||||
|   // Mission cargo give to the player - Need to cleanup.
 | ||||
|   /* Mission cargo give to the player - Need to cleanup. */ | ||||
|   unsigned int* cargo; | ||||
|   int ncargo; | ||||
| 
 | ||||
|   lua_State* L; // The state of the running lua code.
 | ||||
|   lua_State* L; /* The state of the running lua code. */ | ||||
| } Mission; | ||||
| 
 | ||||
| #define MISSION_MAX 6 // No sense in the player having unlimited missions..
 | ||||
| #define MISSION_MAX 6 /* No sense in the player having unlimited missions.. */ | ||||
| extern Mission player_missions[MISSION_MAX]; | ||||
| 
 | ||||
| // For mission computer.
 | ||||
| /* For mission computer. */ | ||||
| Mission* missions_computer(int* n, int faction, char* planet, char* system); | ||||
| // Player accepted mission - mission computer.
 | ||||
| /* Player accepted mission - mission computer. */ | ||||
| int mission_accept(Mission* mission); | ||||
| void missions_bar(int faction, char* planet, char* system); | ||||
| 
 | ||||
| // Misc.
 | ||||
| /* Misc. */ | ||||
| int mission_getID(char* name); | ||||
| MissionData* mission_get(int id); | ||||
| 
 | ||||
| // Cargo stuff.
 | ||||
| /* Cargo stuff. */ | ||||
| void mission_linkCargo(Mission* misn, unsigned int cargo_id); | ||||
| void mission_unlinkCargo(Mission* misn, unsigned int cargo_id); | ||||
| 
 | ||||
| // Load/Quit.
 | ||||
| /* Load/Quit. */ | ||||
| int missions_load(void); | ||||
| void mission_cleanup(Mission* misn); | ||||
| void missions_free(void); | ||||
|  | ||||
							
								
								
									
										132
									
								
								src/music.c
									
									
									
									
									
								
							
							
						
						
									
										132
									
								
								src/music.c
									
									
									
									
									
								
							| @ -32,12 +32,12 @@ | ||||
| 
 | ||||
| #define MUSIC_LUA_PATH  "../snd/music.lua" | ||||
| 
 | ||||
| // Gobal sound mutex.
 | ||||
| /* Gobal sound mutex. */ | ||||
| extern SDL_mutex* sound_lock; | ||||
| 
 | ||||
| // Global music lua.
 | ||||
| /* Global music lua. */ | ||||
| static lua_State* music_lua = NULL; | ||||
| // Functions.
 | ||||
| /* Functions. */ | ||||
| static int musicL_load(lua_State* L); | ||||
| static int musicL_play(lua_State* L); | ||||
| static int musicL_stop(lua_State* L); | ||||
| @ -50,36 +50,36 @@ static const luaL_reg music_methods[] = { | ||||
|   {0, 0} | ||||
| }; | ||||
| 
 | ||||
| // Saves the music to ram in this structure.
 | ||||
| /* Saves the music to ram in this structure. */ | ||||
| typedef struct alMusic_ { | ||||
|   char name[64]; // Name.
 | ||||
|   char name[64]; /* Name. */ | ||||
|   Packfile file; | ||||
|   OggVorbis_File stream; | ||||
|   vorbis_info* info; | ||||
|   ALenum format; | ||||
| } alMusic; | ||||
| 
 | ||||
| // Song currently playing.
 | ||||
| /* Song currently playing. */ | ||||
| static SDL_mutex* music_vorbis_lock; | ||||
| static alMusic music_vorbis; | ||||
| static ALuint music_buffer[2]; // Front and back buffer.
 | ||||
| static ALuint music_buffer[2]; /* Front and back buffer. */ | ||||
| static ALuint music_source = 0; | ||||
| 
 | ||||
| // What is available?
 | ||||
| /* What is available? */ | ||||
| static char** music_selection = NULL; | ||||
| static int nmusic_selection = 0; | ||||
| 
 | ||||
| // Volume
 | ||||
| /* Volume */ | ||||
| static ALfloat mvolume = 1.; | ||||
| 
 | ||||
| // Vorbis suff.
 | ||||
| /* Vorbis suff. */ | ||||
| static size_t ovpack_read(void* ptr, size_t size, | ||||
|                           size_t nmemb, void* datasource) { | ||||
|   return (ssize_t) pack_read(datasource, ptr, size*nmemb); | ||||
| } | ||||
| 
 | ||||
| static int ovpack_retneg(void) { return -1; } // Must return -1.
 | ||||
| static int ovpack_retzero(void) { return 0; } // Must return 0.
 | ||||
| static int ovpack_retneg(void) { return -1; } /* Must return -1. */ | ||||
| static int ovpack_retzero(void) { return 0; } /* Must return 0. */ | ||||
| ov_callbacks ovcall = { | ||||
|   .read_func  = ovpack_read, | ||||
|   .seek_func  = (int(*)(void*, ogg_int64_t, int)) ovpack_retneg, | ||||
| @ -87,24 +87,24 @@ ov_callbacks ovcall = { | ||||
|   .tell_func = (long(*)(void*))ovpack_retneg | ||||
| }; | ||||
| 
 | ||||
| // Music stuff.
 | ||||
| /* Music stuff. */ | ||||
| static int stream_loadBuffer(ALuint buffer); | ||||
| static int music_find(void); | ||||
| static int music_loadOGG(const char* filename); | ||||
| static void music_free(void); | ||||
| // Lua stuff.
 | ||||
| /* Lua stuff. */ | ||||
| static int music_luaInit(void); | ||||
| static void music_luaQuit(void); | ||||
| 
 | ||||
| // The thread.
 | ||||
| /* The thread. */ | ||||
| static unsigned int music_state = 0; | ||||
| int music_thread(void* unused) { | ||||
|   (void)unused; | ||||
| 
 | ||||
|   int active; // Active buffer.
 | ||||
|   int active; /* Active buffer. */ | ||||
|   ALint stat; | ||||
| 
 | ||||
|   // Main loop.
 | ||||
|   /* Main loop. */ | ||||
|   while(!music_is(MUSIC_KILL)) { | ||||
|     if(music_is(MUSIC_PLAYING)) { | ||||
|       if(music_vorbis.file.end == 0) | ||||
| @ -112,18 +112,18 @@ int music_thread(void* unused) { | ||||
|       else { | ||||
|         music_rm(MUSIC_STOPPED); | ||||
| 
 | ||||
|         musicLock(); // Lock the mutex.
 | ||||
|         musicLock(); /* Lock the mutex. */ | ||||
|         soundLock(); | ||||
| 
 | ||||
|         // Start playing current song.
 | ||||
|         active = 0; // Load first buffer.
 | ||||
|         /* Start playing current song. */ | ||||
|         active = 0; /* Load first buffer. */ | ||||
|         if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING); | ||||
|         alSourceQueueBuffers(music_source, 1, &music_buffer[active]); | ||||
| 
 | ||||
|         // Start playing with buffer laoaded.
 | ||||
|         /* Start playing with buffer laoaded. */ | ||||
|         alSourcePlay(music_source); | ||||
| 
 | ||||
|         active = 1; // Load the second buffer.
 | ||||
|         active = 1; /* Load the second buffer. */ | ||||
|         if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING); | ||||
|         alSourceQueueBuffers(music_source, 1, &music_buffer[active]); | ||||
| 
 | ||||
| @ -136,7 +136,7 @@ int music_thread(void* unused) { | ||||
| 
 | ||||
|         alGetSourcei(music_source, AL_BUFFERS_PROCESSED, &stat); | ||||
|         if(stat > 0) { | ||||
|           // Refill active buffer.
 | ||||
|           /* Refill active buffer. */ | ||||
|           alSourceUnqueueBuffers(music_source, 1, &music_buffer[active]); | ||||
|           if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING); | ||||
|           alSourceQueueBuffers(music_source, 1, &music_buffer[active]); | ||||
| @ -156,26 +156,26 @@ int music_thread(void* unused) { | ||||
|       musicUnlock(); | ||||
|     } | ||||
|     music_set(MUSIC_STOPPED); | ||||
|     SDL_Delay(0); // We must not kill resources.
 | ||||
|     SDL_Delay(0); /* We must not kill resources. */ | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| static int stream_loadBuffer(ALuint buffer) { | ||||
|   int size, section, result; | ||||
|   char data[BUFFER_SIZE]; // Buffer to hold the data.
 | ||||
|   char data[BUFFER_SIZE]; /* Buffer to hold the data. */ | ||||
| 
 | ||||
|   size = 0; | ||||
|   while(size < BUFFER_SIZE) { | ||||
|     // Fill up the entire data buffer.
 | ||||
|     /* Fill up the entire data buffer. */ | ||||
|     result = ov_read( | ||||
|           &music_vorbis.stream,  // Stream.
 | ||||
|           data + size,      // Data.
 | ||||
|           BUFFER_SIZE - size,   // Amount to read.
 | ||||
|           0,           // Big endian?.
 | ||||
|           2,           // 16 bit.
 | ||||
|           1,           // Signed.
 | ||||
|           §ion);       // Current bitstream.
 | ||||
|           &music_vorbis.stream,  /* Stream. */ | ||||
|           data + size,      /* Data. */ | ||||
|           BUFFER_SIZE - size,   /* Amount to read. */ | ||||
|           0,           /* Big endian?. */ | ||||
|           2,           /* 16 bit. */ | ||||
|           1,           /* Signed. */ | ||||
|           §ion);       /* Current bitstream. */ | ||||
| 
 | ||||
|     if(result == 0) return 1; | ||||
|     else if(result == OV_HOLE) { | ||||
| @ -188,19 +188,19 @@ static int stream_loadBuffer(ALuint buffer) { | ||||
|     } | ||||
| 
 | ||||
|     size += result; | ||||
|     if(size == BUFFER_SIZE) break; // Buffer is full.
 | ||||
|     if(size == BUFFER_SIZE) break; /* Buffer is full. */ | ||||
|   } | ||||
|   // Load the buffer.
 | ||||
|   /* Load the buffer. */ | ||||
|   alBufferData(buffer, music_vorbis.format, data, BUFFER_SIZE, | ||||
|                music_vorbis.info->rate); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Init/Exit.
 | ||||
| /* Init/Exit. */ | ||||
| int music_init(void) { | ||||
|   music_vorbis_lock = SDL_CreateMutex(); | ||||
|   music_vorbis.file.end = 0; // Indication that it's not loaded..
 | ||||
|   music_vorbis.file.end = 0; /* Indication that it's not loaded.. */ | ||||
| 
 | ||||
|   soundLock(); | ||||
| 
 | ||||
| @ -210,7 +210,7 @@ int music_init(void) { | ||||
|   alSourcef(music_source, AL_ROLLOFF_FACTOR, 0.); | ||||
|   alSourcei(music_source, AL_SOURCE_RELATIVE, AL_FALSE); | ||||
| 
 | ||||
|   // Start the lua music stuff.
 | ||||
|   /* Start the lua music stuff. */ | ||||
|   music_luaInit(); | ||||
| 
 | ||||
|   soundUnlock(); | ||||
| @ -225,34 +225,34 @@ int music_makeList(void) { | ||||
| void music_exit(void) { | ||||
|   int i; | ||||
| 
 | ||||
|   // Free the music.
 | ||||
|   /* Free the music. */ | ||||
|   alDeleteBuffers(2, music_buffer); | ||||
|   alDeleteSources(1, &music_source); | ||||
|   music_free(); | ||||
| 
 | ||||
|   // Free selection
 | ||||
|   /* Free selection */ | ||||
|   for(i = 0; i < nmusic_selection; i++) | ||||
|     free(music_selection[i]); | ||||
|   free(music_selection); | ||||
| 
 | ||||
|   // Bye bye Lua.
 | ||||
|   /* Bye bye Lua. */ | ||||
|   music_luaQuit(); | ||||
| 
 | ||||
|   SDL_DestroyMutex(music_vorbis_lock); | ||||
| } | ||||
| 
 | ||||
| // Internal music loading ruitines.
 | ||||
| /* Internal music loading ruitines. */ | ||||
| static int music_loadOGG(const char* filename) { | ||||
|   // Free currently loaded ogg.
 | ||||
|   /* Free currently loaded ogg. */ | ||||
|   music_free(); | ||||
| 
 | ||||
|   musicLock(); | ||||
| 
 | ||||
|   // Set the new name.
 | ||||
|   /* Set the new name. */ | ||||
|   strncpy(music_vorbis.name, filename, 64); | ||||
|   music_vorbis.name[64-1] = '\0'; | ||||
| 
 | ||||
|   // Load the new ogg.
 | ||||
|   /* Load the new ogg. */ | ||||
|   pack_open(&music_vorbis.file, DATA, filename); | ||||
|   ov_open_callbacks(&music_vorbis.file, &music_vorbis.stream, NULL, 0, ovcall); | ||||
|   music_vorbis.info = ov_info(&music_vorbis.stream, -1); | ||||
| @ -271,26 +271,26 @@ static int music_find(void) { | ||||
|   char tmp[64]; | ||||
|   int len; | ||||
| 
 | ||||
|   // Get the file list.
 | ||||
|   /* Get the file list. */ | ||||
|   files = pack_listfiles(data, &nfiles); | ||||
| 
 | ||||
|   // Load the profiles.
 | ||||
|   /* Load the profiles. */ | ||||
|   for(i = 0; i < nfiles; i++) | ||||
|     if((strncmp(files[i], MUSIC_PREFIX, strlen(MUSIC_PREFIX))==0) && | ||||
|        (strncmp(files[i] + strlen(files[i]) - strlen(MUSIC_SUFFIX), | ||||
|                 MUSIC_SUFFIX, strlen(MUSIC_SUFFIX))==0)) { | ||||
| 
 | ||||
|       // Grow the selection size.
 | ||||
|       /* Grow the selection size. */ | ||||
|       music_selection = realloc(music_selection,++nmusic_selection*sizeof(char*)); | ||||
| 
 | ||||
|       // Remove the prefix and suffix.
 | ||||
|       /* Remove the prefix and suffix. */ | ||||
|       len = strlen(files[i]) - strlen(MUSIC_SUFFIX MUSIC_PREFIX); | ||||
|       strncpy(tmp, files[i]  + strlen(MUSIC_PREFIX), len); | ||||
|       tmp[MIN(len, 64-1)] = '\0'; | ||||
| 
 | ||||
|       music_selection[nmusic_selection-1] = strdup(tmp); | ||||
|     } | ||||
|   // Free the char* allocated by pack.
 | ||||
|   /* Free the char* allocated by pack. */ | ||||
|   for(i = 0; i < nfiles; i++) | ||||
|     free(files[i]); | ||||
|   free(files); | ||||
| @ -306,7 +306,7 @@ static void music_free(void) { | ||||
|   if(music_vorbis.file.end != 0) { | ||||
|     ov_clear(&music_vorbis.stream); | ||||
|     pack_close(&music_vorbis.file); | ||||
|     music_vorbis.file.end = 0; // Somewhat ended.
 | ||||
|     music_vorbis.file.end = 0; /* Somewhat ended. */ | ||||
|   } | ||||
| 
 | ||||
|   musicUnlock(); | ||||
| @ -315,13 +315,13 @@ static void music_free(void) { | ||||
| void music_volume(const double vol) { | ||||
|   if(sound_lock == NULL) return; | ||||
| 
 | ||||
|   // Sanity check!
 | ||||
|   /* Sanity check! */ | ||||
|   ALfloat fvol = ABS(vol); | ||||
|   if(fvol > 1.) fvol = 1.; | ||||
| 
 | ||||
|   mvolume = fvol; | ||||
| 
 | ||||
|   // Only needed if playing!
 | ||||
|   /* Only needed if playing! */ | ||||
|   if(music_set(MUSIC_PLAYING)) { | ||||
|     soundLock(); | ||||
|     alSourcef(music_source, AL_GAIN, fvol); | ||||
| @ -329,7 +329,7 @@ void music_volume(const double vol) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Music control functions.
 | ||||
| /* Music control functions. */ | ||||
| void music_load(const char* name) { | ||||
|   if(sound_lock == NULL) return; | ||||
| 
 | ||||
| @ -360,9 +360,9 @@ void music_kill(void) { | ||||
|   if(!music_is(MUSIC_KILL)) music_set(MUSIC_KILL); | ||||
| } | ||||
| 
 | ||||
| // Music lua stuff.
 | ||||
| /* Music lua stuff. */ | ||||
| 
 | ||||
| // Initialize.
 | ||||
| /* Initialize. */ | ||||
| static int music_luaInit(void) { | ||||
|   char* buf; | ||||
|   uint32_t bufsize; | ||||
| @ -372,15 +372,15 @@ static int music_luaInit(void) { | ||||
| 
 | ||||
|   music_lua = luaL_newstate(); | ||||
| 
 | ||||
|   //luaL_openlibs(music_lua);
 | ||||
|   /*luaL_openlibs(music_lua); */ | ||||
| 
 | ||||
|   lua_loadSpace(music_lua, 1);  // Space and time are readonly.
 | ||||
|   lua_loadSpace(music_lua, 1);  /* Space and time are readonly. */ | ||||
|   lua_loadTime(music_lua, 1); | ||||
|   lua_loadRnd(music_lua); | ||||
|   lua_loadVar(music_lua, 1);    // Also read only.
 | ||||
|   lua_loadMusic(music_lua, 0);  // Write it.
 | ||||
|   lua_loadVar(music_lua, 1);    /* Also read only. */ | ||||
|   lua_loadMusic(music_lua, 0);  /* Write it. */ | ||||
| 
 | ||||
|   // Load the actual lua music code.
 | ||||
|   /* Load the actual lua music code. */ | ||||
|   buf = pack_readfile(DATA, MUSIC_LUA_PATH, &bufsize); | ||||
|   if(luaL_dobuffer(music_lua, buf, bufsize, MUSIC_LUA_PATH) != 0) { | ||||
|     ERR("Error loading music file: %s" MUSIC_LUA_PATH); | ||||
| @ -393,7 +393,7 @@ static int music_luaInit(void) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Destroy.
 | ||||
| /* Destroy. */ | ||||
| static void music_luaQuit(void) { | ||||
|   if(music_lua == NULL) | ||||
|     return; | ||||
| @ -403,7 +403,7 @@ static void music_luaQuit(void) { | ||||
| } | ||||
| 
 | ||||
| int lua_loadMusic(lua_State* L, int read_only) { | ||||
|   (void)read_only; // Future proof.
 | ||||
|   (void)read_only; /* Future proof. */ | ||||
|   luaL_register(L, "music", music_methods); | ||||
|   return 0; | ||||
| } | ||||
| @ -414,18 +414,18 @@ int music_choose(char* situation) { | ||||
|   lua_getglobal(music_lua, "choose"); | ||||
|   lua_pushstring(music_lua, situation); | ||||
|   if(lua_pcall(music_lua, 1, 0, 0)) { | ||||
|     // Error occured.
 | ||||
|     /* Error occured. */ | ||||
|     WARN("Error while choosing music: %s", (char*)lua_tostring(music_lua, -1)); | ||||
|     return -1; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // The music lua functions.
 | ||||
| /* The music lua functions. */ | ||||
| static int musicL_load(lua_State* L) { | ||||
|   char* str; | ||||
| 
 | ||||
|   // Check parameters.
 | ||||
|   /* Check parameters. */ | ||||
|   LLUA_MIN_ARGS(1); | ||||
|   if(lua_isstring(L, 1)) str = (char*)lua_tostring(L, 1); | ||||
|   else LLUA_INVALID_PARAMETER(); | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| #pragma once | ||||
| #include "lua.h" | ||||
| 
 | ||||
| // Thread.
 | ||||
| /* Thread. */ | ||||
| int music_thread(void* unused); | ||||
| void music_kill(void); | ||||
| 
 | ||||
| // Init/Exit.
 | ||||
| /* Init/Exit. */ | ||||
| int music_init(void); | ||||
| int music_makeList(void); | ||||
| void music_exit(void); | ||||
| 
 | ||||
| // Music control.
 | ||||
| /* Music control. */ | ||||
| void music_volume(const double vol); | ||||
| void music_load(const char* name); | ||||
| void music_play(void); | ||||
| void music_stop(void); | ||||
| 
 | ||||
| // Lua control.
 | ||||
| /* Lua control. */ | ||||
| int lua_loadMusic(lua_State* L, int read_only); | ||||
| int music_choose(char* situation); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										256
									
								
								src/opengl.c
									
									
									
									
									
								
							
							
						
						
									
										256
									
								
								src/opengl.c
									
									
									
									
									
								
							| @ -14,39 +14,39 @@ | ||||
| #include "pack.h" | ||||
| #include "opengl.h" | ||||
| 
 | ||||
| // offsets to Adjust the pilot's place onscreen
 | ||||
| //to be in the middle, even with the GUI.
 | ||||
| /* offsets to Adjust the pilot's place onscreen */ | ||||
| /*to be in the middle, even with the GUI. */ | ||||
| extern double gui_xoff; | ||||
| extern double gui_yoff; | ||||
| 
 | ||||
| // The screen info, gives data of current opengl settings.
 | ||||
| /* The screen info, gives data of current opengl settings. */ | ||||
| glInfo gl_screen; | ||||
| 
 | ||||
| // Our precious camera.
 | ||||
| /* Our precious camera. */ | ||||
| Vec2* gl_camera; | ||||
| 
 | ||||
| // Misc.
 | ||||
| /* Misc. */ | ||||
| static int SDL_VFlipSurface(SDL_Surface* surface); | ||||
| static int SDL_IsTrans(SDL_Surface* s, int x, int y); | ||||
| static uint8_t* SDL_MapTrans(SDL_Surface* s); | ||||
| static int pot(int n); | ||||
| // glTexture.
 | ||||
| /* glTexture. */ | ||||
| static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh); | ||||
| static void gl_blitTexture(const glTexture* texture, | ||||
|     const double x, const double y, | ||||
|     const double tx, const double ty, const glColour* c); | ||||
| 
 | ||||
| // PNG.
 | ||||
| /* PNG. */ | ||||
| int write_png(const char* file_name, png_bytep* rows, int w, int h, | ||||
|               int colourtype, int bitdepth); | ||||
| // Global.
 | ||||
| /* Global. */ | ||||
| static GLboolean gl_hasExt(char* name); | ||||
| 
 | ||||
| // ================
 | ||||
| // MISC!
 | ||||
| // ================
 | ||||
| /* ================ */ | ||||
| /* MISC! */ | ||||
| /* ================ */ | ||||
| 
 | ||||
| // Get the closest power of two.
 | ||||
| /* Get the closest power of two. */ | ||||
| static int pot(int n) { | ||||
|   int i = 1; | ||||
|   while(i < n) | ||||
| @ -54,9 +54,9 @@ static int pot(int n) { | ||||
|   return i; | ||||
| } | ||||
| 
 | ||||
| // Flips the surface vertically. Return 0 on success.
 | ||||
| /* Flips the surface vertically. Return 0 on success. */ | ||||
| static int SDL_VFlipSurface(SDL_Surface* surface) { | ||||
|   // Flip the image.
 | ||||
|   /* Flip the image. */ | ||||
|   Uint8* rowhi, *rowlo, *tmpbuf; | ||||
|   int y; | ||||
| 
 | ||||
| @ -76,14 +76,14 @@ static int SDL_VFlipSurface(SDL_Surface* surface) { | ||||
|     rowlo -= surface->pitch; | ||||
|   } | ||||
|   free(tmpbuf); | ||||
|   // Might be obvious, but I'm done flipping.
 | ||||
|   /* Might be obvious, but I'm done flipping. */ | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Return true if position (x,y) of s is transparent.
 | ||||
| /* Return true if position (x,y) of s is transparent. */ | ||||
| static int SDL_IsTrans(SDL_Surface* s, int x, int y) { | ||||
|   int bpp = s->format->BytesPerPixel; | ||||
|   // p is the address to the pixel we want to retrieve.
 | ||||
|   /* p is the address to the pixel we want to retrieve. */ | ||||
|   Uint8* p = (Uint8*)s->pixels + y * s->pitch + x*bpp; | ||||
| 
 | ||||
|   Uint32 pixelcolour = 0; | ||||
| @ -105,18 +105,18 @@ static int SDL_IsTrans(SDL_Surface* s, int x, int y) { | ||||
|     pixelcolour = *(Uint32*)p; | ||||
|     break; | ||||
|   } | ||||
|   // Test whetehr the pixels color is equal to color of
 | ||||
|   //transparent pixels for that surface.
 | ||||
|   /* Test whetehr the pixels color is equal to color of */ | ||||
|   /*transparent pixels for that surface. */ | ||||
|   return (pixelcolour == s->format->colorkey); | ||||
| } | ||||
| 
 | ||||
| // Map the surface transparancy.
 | ||||
| // Return 0 on success.
 | ||||
| /* Map the surface transparancy. */ | ||||
| /* Return 0 on success. */ | ||||
| static uint8_t* SDL_MapTrans(SDL_Surface* s) { | ||||
|   // Allocate memory for just enough bits to hold all the data we need.
 | ||||
|   /* Allocate memory for just enough bits to hold all the data we need. */ | ||||
|   int size = s->w*s->h/8 + ((s->w*s->h%8)?1:0); | ||||
|   uint8_t* t = malloc(size); | ||||
|   memset(t, 0, size); // *must* be set to zero.
 | ||||
|   memset(t, 0, size); /* *must* be set to zero. */ | ||||
| 
 | ||||
|   if(t == NULL) { | ||||
|     WARN("Out of memeory"); | ||||
| @ -125,13 +125,13 @@ static uint8_t* SDL_MapTrans(SDL_Surface* s) { | ||||
| 
 | ||||
|   int i, j; | ||||
|   for(i = 0; i < s->h; i++) | ||||
|     for(j = 0; j < s->w; j++) // Set each bit to be 1 if not transparent or 0 if it is.
 | ||||
|     for(j = 0; j < s->w; j++) /* Set each bit to be 1 if not transparent or 0 if it is. */ | ||||
|       t[(i*s->w+j)/8] |= (SDL_IsTrans(s,j,i)) ? 0 : (1<<((i*s->w+j)%8)); | ||||
| 
 | ||||
|   return t; | ||||
| } | ||||
| 
 | ||||
| // Take a screenshot.
 | ||||
| /* Take a screenshot. */ | ||||
| void gl_screenshot(const char* filename) { | ||||
|   SDL_Surface* screen = SDL_GetVideoSurface(); | ||||
|   unsigned rowbytes = screen->w * 3; | ||||
| @ -146,12 +146,12 @@ void gl_screenshot(const char* filename) { | ||||
|   gl_checkErr(); | ||||
| } | ||||
| 
 | ||||
| // ================
 | ||||
| // TEXTURE!
 | ||||
| // ================
 | ||||
| /* ================ */ | ||||
| /* TEXTURE! */ | ||||
| /* ================ */ | ||||
| 
 | ||||
| // Returns the texture ID.
 | ||||
| // Stores real sizes in rw/rh (from POT padding).
 | ||||
| /* Returns the texture ID. */ | ||||
| /* Stores real sizes in rw/rh (from POT padding). */ | ||||
| static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) { | ||||
|   GLuint texture; | ||||
|   SDL_Surface* tmp; | ||||
| @ -160,7 +160,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) { | ||||
|   int potw, poth; | ||||
|   SDL_Rect rtemp; | ||||
| 
 | ||||
|   // Make size power of two.
 | ||||
|   /* Make size power of two. */ | ||||
|   potw = pot(surface->w); | ||||
|   poth = pot(surface->h); | ||||
|   if(rw)*rw = potw; | ||||
| @ -170,7 +170,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) { | ||||
|   rtemp.w = surface->w; | ||||
|   rtemp.h = surface->h; | ||||
| 
 | ||||
|   // Save alpha.
 | ||||
|   /* Save alpha. */ | ||||
|   saved_flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); | ||||
|   saved_alpha = surface->format->alpha; | ||||
|   if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) | ||||
| @ -178,7 +178,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) { | ||||
|   if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA) | ||||
|     SDL_SetColorKey(surface, 0, surface->format->colorkey); | ||||
| 
 | ||||
|   // Create the temp POT surface.
 | ||||
|   /* Create the temp POT surface. */ | ||||
|   tmp = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, | ||||
|       potw, poth, surface->format->BytesPerPixel*8, RGBMASK); | ||||
|   if(tmp == NULL) { | ||||
| @ -191,30 +191,30 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) { | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   // Change the surface to the new blitted one.
 | ||||
|   /* Change the surface to the new blitted one. */ | ||||
|   SDL_BlitSurface(surface, &rtemp, tmp, &rtemp); | ||||
|   SDL_FreeSurface(surface); | ||||
|   surface = tmp; | ||||
| 
 | ||||
|   // Set saved alpha.
 | ||||
|   /* Set saved alpha. */ | ||||
|   if((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)  | ||||
|     SDL_SetAlpha(surface, 0, 0); | ||||
| 
 | ||||
|   // Opengl texture binding.
 | ||||
|   glGenTextures(1, &texture); // Create the texure.
 | ||||
|   glBindTexture(GL_TEXTURE_2D, texture); // Load the texture.
 | ||||
|   /* Opengl texture binding. */ | ||||
|   glGenTextures(1, &texture); /* Create the texure. */ | ||||
|   glBindTexture(GL_TEXTURE_2D, texture); /* Load the texture. */ | ||||
| 
 | ||||
|   // Filtering, LINEAR is better for scaling, nearest looks nicer, LINEAR
 | ||||
|   // also seems to create a bit of artifacts around the edges.
 | ||||
|   /* Filtering, LINEAR is better for scaling, nearest looks nicer, LINEAR */ | ||||
|   /* also seems to create a bit of artifacts around the edges. */ | ||||
|   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
|   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||
| 
 | ||||
|   // Now lead the texture data up.
 | ||||
|   /* Now lead the texture data up. */ | ||||
|   SDL_LockSurface(surface); | ||||
|   glTexImage2D(GL_TEXTURE_2D, 0, surface->format->BytesPerPixel, | ||||
|                surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels); | ||||
| 
 | ||||
|   // Cleanup.
 | ||||
|   /* Cleanup. */ | ||||
|   SDL_UnlockSurface(surface); | ||||
|   SDL_FreeSurface(surface); | ||||
| 
 | ||||
| @ -223,11 +223,11 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) { | ||||
|   return texture; | ||||
| } | ||||
| 
 | ||||
| // Load the SDL_Surface to an openGL texture.
 | ||||
| /* Load the SDL_Surface to an openGL texture. */ | ||||
| glTexture* gl_loadImage(SDL_Surface* surface) { | ||||
|   int rw, rh; | ||||
| 
 | ||||
|   // Set up the texture defaults.
 | ||||
|   /* Set up the texture defaults. */ | ||||
|   glTexture* texture = MALLOC_L(glTexture); | ||||
|   texture->w = (double)surface->w; | ||||
|   texture->h = (double)surface->h; | ||||
| @ -246,7 +246,7 @@ glTexture* gl_loadImage(SDL_Surface* surface) { | ||||
|   return texture; | ||||
| } | ||||
| 
 | ||||
| // Load the image directly as an opengl texture.
 | ||||
| /* Load the image directly as an opengl texture. */ | ||||
| glTexture* gl_newImage(const char* path) { | ||||
|   SDL_Surface* tmp, *surface; | ||||
|   glTexture* t; | ||||
| @ -266,21 +266,21 @@ glTexture* gl_newImage(const char* path) { | ||||
|     return NULL; | ||||
|   } | ||||
| 
 | ||||
|   surface = SDL_DisplayFormatAlpha(tmp); // Sets the surface to what we use.
 | ||||
|   surface = SDL_DisplayFormatAlpha(tmp); /* Sets the surface to what we use. */ | ||||
|   if(surface == 0) { | ||||
|     WARN("Error converting image to screen format: %s", SDL_GetError()); | ||||
|     return NULL; | ||||
|   } | ||||
| 
 | ||||
|   SDL_FreeSurface(tmp); // Free the temp surface.
 | ||||
|   SDL_FreeSurface(tmp); /* Free the temp surface. */ | ||||
| 
 | ||||
|   // We have to flip our surfaces to match the ortho.
 | ||||
|   /* We have to flip our surfaces to match the ortho. */ | ||||
|   if(SDL_VFlipSurface(surface)) { | ||||
|     WARN("Error flipping surface"); | ||||
|     return NULL; | ||||
|   } | ||||
| 
 | ||||
|   // Do after flipping for collision detection.
 | ||||
|   /* Do after flipping for collision detection. */ | ||||
|   SDL_LockSurface(surface); | ||||
|   trans = SDL_MapTrans(surface); | ||||
|   SDL_UnlockSurface(surface); | ||||
| @ -290,7 +290,7 @@ glTexture* gl_newImage(const char* path) { | ||||
|   return t; | ||||
| } | ||||
| 
 | ||||
| // Load the texture immediately, but also set is as a sprite.
 | ||||
| /* Load the texture immediately, but also set is as a sprite. */ | ||||
| glTexture* gl_newSprite(const char* path, const int sx, const int sy) { | ||||
|   glTexture* texture; | ||||
|   if((texture = gl_newImage(path)) == NULL) | ||||
| @ -302,45 +302,45 @@ glTexture* gl_newSprite(const char* path, const int sx, const int sy) { | ||||
|   return texture; | ||||
| } | ||||
| 
 | ||||
| // Free the texture.
 | ||||
| /* Free the texture. */ | ||||
| void gl_freeTexture(glTexture* texture) { | ||||
|   glDeleteTextures(1, &texture->texture); | ||||
|   if(texture->trans) free(texture->trans); | ||||
|   free(texture); | ||||
| } | ||||
| 
 | ||||
| // Return true if pixel at pos (x,y) is transparent.
 | ||||
| /* Return true if pixel at pos (x,y) is transparent. */ | ||||
| int gl_isTrans(const glTexture* t, const int x, const int y) { | ||||
|   return !(t->trans[(y*(int)(t->w)+x)/8] & (1<<((y*(int)(t->w)+x)%8))); | ||||
| } | ||||
| 
 | ||||
| // Set x and y to be the appropriate sprite for glTexture using dir.
 | ||||
| /* Set x and y to be the appropriate sprite for glTexture using dir. */ | ||||
| void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir) { | ||||
|   int s, sx, sy; | ||||
| 
 | ||||
|   double shard, rdir; | ||||
| 
 | ||||
|   // What each image represents in angle.
 | ||||
|   /* What each image represents in angle. */ | ||||
|   shard = 2.0*M_PI / (t->sy*t->sx); | ||||
| 
 | ||||
|   rdir = dir + shard/2.; | ||||
|   if(rdir < 0.) rdir = 0.; | ||||
| 
 | ||||
|   // Now calculate the sprite we need.
 | ||||
|   /* Now calculate the sprite we need. */ | ||||
|   s = (int)(rdir / shard); | ||||
|   sx = t->sx; | ||||
|   sy = t->sy; | ||||
| 
 | ||||
|   // Make sure the sprite is "in range".
 | ||||
|   /* Make sure the sprite is "in range". */ | ||||
|   if(s > (sy*sx-1)) s = s % (sy*sx); | ||||
| 
 | ||||
|   (*x) = s % sx; | ||||
|   (*y) = s / sx; | ||||
| } | ||||
| 
 | ||||
| // ================
 | ||||
| // BLITTING!
 | ||||
| // ================
 | ||||
| /* ================ */ | ||||
| /* BLITTING! */ | ||||
| /* ================ */ | ||||
| 
 | ||||
| static void gl_blitTexture(const glTexture* texture, | ||||
|     const double x, const double y, | ||||
| @ -348,14 +348,14 @@ static void gl_blitTexture(const glTexture* texture, | ||||
| 
 | ||||
|   double tw, th; | ||||
| 
 | ||||
|   // Texture dimensions.
 | ||||
|   /* Texture dimensions. */ | ||||
|   tw = texture->sw / texture->rw; | ||||
|   th = texture->sh / texture->rh; | ||||
| 
 | ||||
|   glEnable(GL_TEXTURE_2D); | ||||
|   glBindTexture(GL_TEXTURE_2D, texture->texture); | ||||
|   glBegin(GL_QUADS); | ||||
|     // Set colour or default if not set.
 | ||||
|     /* Set colour or default if not set. */ | ||||
|     if(c == NULL) glColor4d(1., 1., 1., 1.); | ||||
|     else COLOUR(*c); | ||||
| 
 | ||||
| @ -373,46 +373,46 @@ static void gl_blitTexture(const glTexture* texture, | ||||
|   glEnd(); | ||||
|   glDisable(GL_TEXTURE_2D); | ||||
| 
 | ||||
|   // Did anything fail?
 | ||||
|   /* Did anything fail? */ | ||||
|   gl_checkErr(); | ||||
| } | ||||
| 
 | ||||
| // Blit the sprite at given position.
 | ||||
| /* Blit the sprite at given position. */ | ||||
| void gl_blitSprite(const glTexture* sprite, const double bx, const double by, | ||||
|                    const int sx, const int sy, const glColour* c) { | ||||
| 
 | ||||
|   double x, y, tx, ty; | ||||
| 
 | ||||
|   // Calculate position - we'll use relative coords to player.
 | ||||
|   /* Calculate position - we'll use relative coords to player. */ | ||||
|   x = bx - VX(*gl_camera) - sprite->sw/2. + gui_xoff; | ||||
|   y = by - VY(*gl_camera) - sprite->sh/2. + gui_yoff; | ||||
| 
 | ||||
|   // Don't draw if offscreen.
 | ||||
|   /* Don't draw if offscreen. */ | ||||
|   if((fabs(x) > SCREEN_W/2 + sprite->sw) || | ||||
|       (fabs(y) > SCREEN_H/2 + sprite->sh)) | ||||
|     return; | ||||
| 
 | ||||
|   // Texture coords.
 | ||||
|   /* Texture coords. */ | ||||
|   tx = sprite->sw * (double)(sx)/sprite->rw; | ||||
|   ty = sprite->sh * (sprite->sy-(double)sy-1)/sprite->rh; | ||||
| 
 | ||||
|   // Actual blitting.
 | ||||
|   /* Actual blitting. */ | ||||
|   gl_blitTexture(sprite, x, y, tx, ty, c); | ||||
| } | ||||
| 
 | ||||
| // Like gl_blitSprite but will use the actual direction, for things that
 | ||||
| // can just rotate around.
 | ||||
| /* Like gl_blitSprite but will use the actual direction, for things that */ | ||||
| /* can just rotate around. */ | ||||
| void gl_blitRotate(const glTexture* texture, | ||||
|     const double bx, const double by, | ||||
|     const double dir, const glColour* c) { | ||||
| 
 | ||||
|   double x, y; | ||||
| 
 | ||||
|   // Calculate position - we'll use relative coords to player.
 | ||||
|   /* Calculate position - we'll use relative coords to player. */ | ||||
|   x = bx - VX(*gl_camera) - texture->sw/2. + gui_xoff; | ||||
|   y = by - VY(*gl_camera) - texture->sh/2. + gui_yoff; | ||||
| 
 | ||||
|   // Don't draw if offscreen.
 | ||||
|   /* Don't draw if offscreen. */ | ||||
|   if((fabs(x) > SCREEN_W/2 + texture->sw) || | ||||
|       (fabs(y) > SCREEN_H/2 + texture->sh)) | ||||
|     return; | ||||
| @ -421,31 +421,31 @@ void gl_blitRotate(const glTexture* texture, | ||||
|   glPushMatrix(); | ||||
|   glRotated(dir, 0., 0., 1.); | ||||
| 
 | ||||
|   // Blit.
 | ||||
|   /* Blit. */ | ||||
|   gl_blitTexture(texture, x, y, 0, 0, c); | ||||
| 
 | ||||
|   glPopMatrix(); // GL_PROJECTION.
 | ||||
|   glPopMatrix(); /* GL_PROJECTION. */ | ||||
| } | ||||
| 
 | ||||
| // Just straight out blit the thing at position.
 | ||||
| /* Just straight out blit the thing at position. */ | ||||
| void gl_blitStatic(const glTexture* texture, const double bx, const double by, | ||||
|                    const glColour* c) { | ||||
|   double x, y; | ||||
| 
 | ||||
|   // Here we use absolute coords.
 | ||||
|   /* Here we use absolute coords. */ | ||||
|   x = bx - (double)SCREEN_W/2.; | ||||
|   y = by - (double)SCREEN_H/2.; | ||||
| 
 | ||||
|   // Actual blitting..
 | ||||
|   /* Actual blitting.. */ | ||||
|   gl_blitTexture(texture, x, y, 0, 0, c); | ||||
| } | ||||
| 
 | ||||
| // Bind our precious camera to a vector.
 | ||||
| /* Bind our precious camera to a vector. */ | ||||
| void gl_bindCamera(const Vec2* pos) { | ||||
|   gl_camera = (Vec2*)pos; | ||||
| } | ||||
| 
 | ||||
| // Draw circles.
 | ||||
| /* Draw circles. */ | ||||
| void gl_drawCircle(const double cx, const double cy, const double r) { | ||||
|   double x, y, p; | ||||
| 
 | ||||
| @ -492,7 +492,7 @@ void gl_drawCircle(const double cx, const double cy, const double r) { | ||||
|   gl_checkErr(); | ||||
| } | ||||
| 
 | ||||
| // Draw a cirlce in a rect.
 | ||||
| /* Draw a cirlce in a rect. */ | ||||
| #define PIXEL(x,y) \ | ||||
|   if((x>rx) && (y>ry) && (x<rxw) && (y<ryh)) \ | ||||
|   glVertex2d(x,y) | ||||
| @ -505,10 +505,10 @@ void gl_drawCircleInRect(const double cx, const double cy, const double r, | ||||
|   rxw = rx+rw; | ||||
|   ryh = ry+rh; | ||||
| 
 | ||||
|   // Are we offscreen?
 | ||||
|   /* Are we offscreen? */ | ||||
|   if((cx+r < rx) || (cy+r < ry) || (cx-r > rxw) || (cy-r > ryh)) | ||||
|     return; | ||||
|   // Can be drawn normally.
 | ||||
|   /* Can be drawn normally. */ | ||||
|   else if((cx-r > rx) && (cy-r > ry) && (cx+r < rxw) && (cy+r < ryh)) { | ||||
|     gl_drawCircle(cx, cy, r); | ||||
|     return; | ||||
| @ -558,18 +558,18 @@ void gl_drawCircleInRect(const double cx, const double cy, const double r, | ||||
| } | ||||
| #undef PIXEL | ||||
| 
 | ||||
| // ================
 | ||||
| // GLOBAL.
 | ||||
| // ================
 | ||||
| /* ================ */ | ||||
| /* GLOBAL. */ | ||||
| /* ================ */ | ||||
| 
 | ||||
| // Check for extensions.
 | ||||
| /* Check for extensions. */ | ||||
| static GLboolean gl_hasExt(char* name) { | ||||
|   // ======================================================
 | ||||
|   // Search for name in the extensions string. Use of strstr()
 | ||||
|   // is not sufficient because extensions names can be prefixes of
 | ||||
|   // other extension names. Could use strtol() but the constant
 | ||||
|   // string returned by glGetString can be in read-only memory.
 | ||||
|   // ======================================================
 | ||||
|   /* ====================================================== */ | ||||
|   /* Search for name in the extensions string. Use of strstr() */ | ||||
|   /* is not sufficient because extensions names can be prefixes of */ | ||||
|   /* other extension names. Could use strtol() but the constant */ | ||||
|   /* string returned by glGetString can be in read-only memory. */ | ||||
|   /* ====================================================== */ | ||||
| 
 | ||||
|   char* p, *end; | ||||
|   size_t len, n; | ||||
| @ -588,8 +588,8 @@ static GLboolean gl_hasExt(char* name) { | ||||
|   return GL_FALSE; | ||||
| } | ||||
| 
 | ||||
| // Check and report if there's been an error.
 | ||||
| //#ifndef gl_checkErr // I know, I know, it's a little hackish.
 | ||||
| /* Check and report if there's been an error. */ | ||||
| /*#ifndef gl_checkErr // I know, I know, it's a little hackish. */ | ||||
| void gl_checkErr(void) { | ||||
| #ifdef DEBUG | ||||
|   GLenum err; | ||||
| @ -597,7 +597,7 @@ void gl_checkErr(void) { | ||||
| 
 | ||||
|   err = glGetError(); | ||||
| 
 | ||||
|   if(err == GL_NO_ERROR) return; // No error.
 | ||||
|   if(err == GL_NO_ERROR) return; /* No error. */ | ||||
| 
 | ||||
|   switch(err) { | ||||
|     case GL_INVALID_ENUM: | ||||
| @ -628,9 +628,9 @@ void gl_checkErr(void) { | ||||
|   WARN("OpenGL error: %s", errstr); | ||||
| #endif | ||||
| } | ||||
| //#endif
 | ||||
| /*#endif */ | ||||
| 
 | ||||
| // Initialize SDL/OpenGL etc.
 | ||||
| /* Initialize SDL/OpenGL etc. */ | ||||
| int gl_init(void) { | ||||
|   int doublebuf, depth, i, j, off, toff, supported; | ||||
|   SDL_Rect** modes; | ||||
| @ -639,16 +639,16 @@ int gl_init(void) { | ||||
| 
 | ||||
|   supported  = 0; | ||||
| 
 | ||||
|   // Initializes video.
 | ||||
|   /* Initializes video. */ | ||||
|   if(SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { | ||||
|     WARN("Unable to initialize SDL Video: %s", SDL_GetError()); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   // Get available fullscreen modes.
 | ||||
|   /* Get available fullscreen modes. */ | ||||
|   if(gl_has(OPENGL_FULLSCREEN)) { | ||||
|     modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN); | ||||
|     if(modes == NULL) { // Could happen, but rare.
 | ||||
|     if(modes == NULL) { /* Could happen, but rare. */ | ||||
|       WARN("No fullscreen modes available"); | ||||
|       if(flags & SDL_FULLSCREEN) { | ||||
|         WARN("Disabling fullscreen mode"); | ||||
| @ -663,13 +663,13 @@ int gl_init(void) { | ||||
|         DEBUG("\t%dx%d", modes[i]->w, modes[i]->h); | ||||
|         if((flags & SDL_FULLSCREEN) && (modes[i]->w == SCREEN_W) && | ||||
|            (modes[i]->h == SCREEN_H)) | ||||
|           supported = 1; // Mode we asked for is supported.
 | ||||
|           supported = 1; /* Mode we asked for is supported. */ | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     // Make sure fullscreen mode is supported.
 | ||||
|     /* Make sure fullscreen mode is supported. */ | ||||
|     if((flags & SDL_FULLSCREEN) && !supported) { | ||||
|       // Try to get the closest aproximation to mode we asked for.
 | ||||
|       /* Try to get the closest aproximation to mode we asked for. */ | ||||
|       off = -1; | ||||
|       j = 0; | ||||
|       for(i = 0; modes[i]; i++) { | ||||
| @ -689,7 +689,7 @@ int gl_init(void) { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Test the setup - aim for 32.
 | ||||
|   /* Test the setup - aim for 32. */ | ||||
|   depth = SDL_VideoModeOK(SCREEN_W, SCREEN_H, gl_screen.depth, flags); | ||||
|   if(depth == 0) | ||||
|      WARN("Video mode %dx%d @ %d bpp not supported" | ||||
| @ -700,13 +700,13 @@ int gl_init(void) { | ||||
| 
 | ||||
|   gl_screen.depth = depth; | ||||
| 
 | ||||
|   // Actually creating the screen.
 | ||||
|   /* Actually creating the screen. */ | ||||
|   if(SDL_SetVideoMode(SCREEN_W, SCREEN_H, gl_screen.depth, flags) == NULL) { | ||||
|     ERR("Unable to create OpenGL window: %s", SDL_GetError()); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   // Grab some info.
 | ||||
|   /* Grab some info. */ | ||||
|   SDL_GL_GetAttribute(SDL_GL_RED_SIZE,      &gl_screen.r); | ||||
|   SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE,    &gl_screen.g); | ||||
|   SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE,     &gl_screen.b); | ||||
| @ -715,16 +715,16 @@ int gl_init(void) { | ||||
|   if(doublebuf) gl_screen.flags |= OPENGL_DOUBLEBUF; | ||||
|   gl_screen.depth = gl_screen.r + gl_screen.g + gl_screen.b + gl_screen.a; | ||||
| 
 | ||||
|   // Get info about some extensions.
 | ||||
|   /* Get info about some extensions. */ | ||||
|   if(gl_hasExt("GL_ARB_vertex_shader")==GL_TRUE) | ||||
|     gl_screen.flags |= OPENGL_VERT_SHADER; | ||||
|   if(gl_hasExt("GL_ARB_fragment_shader")==GL_TRUE) | ||||
|     gl_screen.flags |= OPENGL_FRAG_SHADER; | ||||
| 
 | ||||
|   // Max texture size.
 | ||||
|   /* Max texture size. */ | ||||
|   glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_screen.tex_max); | ||||
| 
 | ||||
|   // Debug heaven.
 | ||||
|   /* Debug heaven. */ | ||||
|   DEBUG("OpenGL Window Created: %dx%d@%dbpp %s", SCREEN_W, SCREEN_H, | ||||
|         gl_screen.depth, (gl_has(OPENGL_FULLSCREEN)) ? "fullscreen" : "window"); | ||||
| 
 | ||||
| @ -739,43 +739,43 @@ int gl_init(void) { | ||||
|     DEBUG("No fragment shader extension detected"); | ||||
|   DEBUG(""); | ||||
| 
 | ||||
|   // Some openGL options.
 | ||||
|   /* Some openGL options. */ | ||||
|   glClearColor(0., 0., 0., 1.); | ||||
| 
 | ||||
|   // Enable/Disable.
 | ||||
|   glDisable(GL_DEPTH_TEST);   // Set for doing 2D shidazles.
 | ||||
|   //glEnable(GL_TEXTURE_2D);  // Don't enable globally, it will break non-texture blits.
 | ||||
|   glDisable(GL_LIGHTING);     // No lighting, it is done when rendered.
 | ||||
|   glEnable(GL_BLEND);         // Alpha blending ftw.
 | ||||
|   /* Enable/Disable. */ | ||||
|   glDisable(GL_DEPTH_TEST);   /* Set for doing 2D shidazles. */ | ||||
|   /*glEnable(GL_TEXTURE_2D);  // Don't enable globally, it will break non-texture blits. */ | ||||
|   glDisable(GL_LIGHTING);     /* No lighting, it is done when rendered. */ | ||||
|   glEnable(GL_BLEND);         /* Alpha blending ftw. */ | ||||
| 
 | ||||
|   // Models.
 | ||||
|   glShadeModel(GL_FLAT);      // Default shade model. Functions should keep this when done..
 | ||||
|   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Good blend model.
 | ||||
|   /* Models. */ | ||||
|   glShadeModel(GL_FLAT);      /* Default shade model. Functions should keep this when done.. */ | ||||
|   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* Good blend model. */ | ||||
| 
 | ||||
|   // Set up the matrix.
 | ||||
|   /* Set up the matrix. */ | ||||
|   glMatrixMode(GL_PROJECTION); | ||||
|   glLoadIdentity(); | ||||
|   glOrtho(-SCREEN_W /2,   // Left edge.
 | ||||
|           SCREEN_W  /2,   // Right edge.
 | ||||
|           -SCREEN_H /2,   // Bottom edge.
 | ||||
|           SCREEN_H  /2,   // Top edge.
 | ||||
|           -1.,            // Near.
 | ||||
|           1.);            // Far.
 | ||||
|   glOrtho(-SCREEN_W /2,   /* Left edge. */ | ||||
|           SCREEN_W  /2,   /* Right edge. */ | ||||
|           -SCREEN_H /2,   /* Bottom edge. */ | ||||
|           SCREEN_H  /2,   /* Top edge. */ | ||||
|           -1.,            /* Near. */ | ||||
|           1.);            /* Far. */ | ||||
| 
 | ||||
| 
 | ||||
|   // Finishing touches.
 | ||||
|   glClear(GL_COLOR_BUFFER_BIT); // Must clear the buffer first.
 | ||||
|   /* Finishing touches. */ | ||||
|   glClear(GL_COLOR_BUFFER_BIT); /* Must clear the buffer first. */ | ||||
|   gl_checkErr(); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Clean up our mess.
 | ||||
| /* Clean up our mess. */ | ||||
| void gl_exit(void) { | ||||
|   SDL_QuitSubSystem(SDL_INIT_VIDEO); | ||||
| } | ||||
| 
 | ||||
| // Saves a png.
 | ||||
| /* Saves a png. */ | ||||
| int write_png(const char* file_name, png_bytep* rows, int w, int h, | ||||
|               int colourtype, int bitdepth) { | ||||
|   png_structp png_ptr; | ||||
|  | ||||
							
								
								
									
										60
									
								
								src/opengl.h
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								src/opengl.h
									
									
									
									
									
								
							| @ -5,7 +5,7 @@ | ||||
| #include "colour.h" | ||||
| #include "physics.h" | ||||
| 
 | ||||
| // Recommended for compatibility bullshit.
 | ||||
| /* Recommended for compatibility bullshit. */ | ||||
| #if SDL_BYTEORDER == SDL_BIG_ENDIAN | ||||
| #  define RMASK 0xff000000 | ||||
| #  define GMASK 0x00ff0000 | ||||
| @ -19,7 +19,7 @@ | ||||
| #endif | ||||
| #define RGBMASK RMASK,GMASK,BMASK,AMASK | ||||
| 
 | ||||
| // Info about opengl screen.
 | ||||
| /* Info about opengl screen. */ | ||||
| #define OPENGL_FULLSCREEN   (1<<0) | ||||
| #define OPENGL_DOUBLEBUF    (1<<1) | ||||
| #define OPENGL_AA_POINT     (1<<2) | ||||
| @ -27,15 +27,15 @@ | ||||
| #define OPENGL_AA_POLYGON   (1<<4) | ||||
| #define OPENGL_FRAG_SHADER  (1<<5) | ||||
| #define OPENGL_VERT_SHADER  (1<<6) | ||||
| #define gl_has(f)           (gl_screen.flags & (f)) // Check for the flag.
 | ||||
| #define gl_has(f)           (gl_screen.flags & (f)) /* Check for the flag. */ | ||||
| typedef struct glInfo_ { | ||||
|   int w, h;         // Window dimensions.
 | ||||
|   int depth;        // Depth in bpp.
 | ||||
|   int r, g, b, a;   // Framebuffer values in bits.
 | ||||
|   int flags;        // Store different properties.
 | ||||
|   int tex_max;      // Max texture size.
 | ||||
|   int w, h;         /* Window dimensions. */ | ||||
|   int depth;        /* Depth in bpp. */ | ||||
|   int r, g, b, a;   /* Framebuffer values in bits. */ | ||||
|   int flags;        /* Store different properties. */ | ||||
|   int tex_max;      /* Max texture size. */ | ||||
| } glInfo; | ||||
| extern glInfo gl_screen; // Local structure set with gl_init etc.
 | ||||
| extern glInfo gl_screen; /* Local structure set with gl_init etc. */ | ||||
| 
 | ||||
| #define SCREEN_W  gl_screen.w | ||||
| #define SCREEN_H  gl_screen.h | ||||
| @ -43,56 +43,56 @@ extern glInfo gl_screen; // Local structure set with gl_init etc. | ||||
| #define COLOUR(x)   glColor4d((x).r, (x).g, (x).b, (x).a) | ||||
| #define ACOLOUR(x,a) glColor4d((x).r, (x).g, (x).b, a) | ||||
| 
 | ||||
| // Spritesheet info.
 | ||||
| /* Spritesheet info. */ | ||||
| typedef struct glTexture_ { | ||||
|   double w, h;        // Real size of the image (excluding POT buffer.
 | ||||
|   double rw, rh;      // Size of POT surface.
 | ||||
|   double sx, sy;      // Number of sprites on x and y axes.
 | ||||
|   double sw, sh;      // Size of each sprite.
 | ||||
|   GLuint texture;     // The opengl texture itself.
 | ||||
|   uint8_t* trans;     // Maps the transparency.
 | ||||
|   double w, h;        /* Real size of the image (excluding POT buffer. */ | ||||
|   double rw, rh;      /* Size of POT surface. */ | ||||
|   double sx, sy;      /* Number of sprites on x and y axes. */ | ||||
|   double sw, sh;      /* Size of each sprite. */ | ||||
|   GLuint texture;     /* The opengl texture itself. */ | ||||
|   uint8_t* trans;     /* Maps the transparency. */ | ||||
| } glTexture; | ||||
| 
 | ||||
| // gl_texute loading/freeing.
 | ||||
| glTexture* gl_loadImage(SDL_Surface* surface); // Frees the surface.
 | ||||
| /* gl_texute loading/freeing. */ | ||||
| glTexture* gl_loadImage(SDL_Surface* surface); /* Frees the surface. */ | ||||
| glTexture* gl_newImage(const char* path); | ||||
| glTexture* gl_newSprite(const char* path, const int sx, const int sy); | ||||
| void gl_freeTexture(glTexture* texture); | ||||
| 
 | ||||
| // Rendering.
 | ||||
| // Blits a sprite, relative pos.
 | ||||
| /* Rendering. */ | ||||
| /* Blits a sprite, relative pos. */ | ||||
| void gl_blitSprite(const glTexture* sprite, const double bx, const double by, | ||||
|                    const int sx, const int sy, const glColour* c); | ||||
| 
 | ||||
| // Blits a texture rotated, relative pos.
 | ||||
| /* Blits a texture rotated, relative pos. */ | ||||
| void gl_blitRotate(const glTexture* texture, | ||||
|     const double bx, const double by, | ||||
|     const double dir, const glColour* c); | ||||
| 
 | ||||
| // Blit the entire image, absolute pos.
 | ||||
| /* Blit the entire image, absolute pos. */ | ||||
| void gl_blitStatic(const glTexture* texture, const double bx, const double by, | ||||
|                    const glColour* c); | ||||
| 
 | ||||
| // Bind the camera to a vector.
 | ||||
| /* Bind the camera to a vector. */ | ||||
| void gl_bindCamera(const Vec2* pos); | ||||
| 
 | ||||
| // Circle drawing.
 | ||||
| /* Circle drawing. */ | ||||
| void gl_drawCircle(const double x, const double y, const double r); | ||||
| void gl_drawCircleInRect(const double x, const double y, const double r, | ||||
|                          const double rc, const double ry, const double rw, | ||||
|                          const double rh); | ||||
| 
 | ||||
| // Initialize/cleanup.
 | ||||
| /* Initialize/cleanup. */ | ||||
| int gl_init(void); | ||||
| void gl_exit(void); | ||||
| 
 | ||||
| // Misc.
 | ||||
| /* Misc. */ | ||||
| int gl_isTrans(const glTexture* t, const int x, const int y); | ||||
| void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir); | ||||
| void gl_screenshot(const char* filename); | ||||
| //#if DEBUG == 1
 | ||||
| /*#if DEBUG == 1 */ | ||||
| void gl_checkErr(void); | ||||
| //#else
 | ||||
| //#define gl_checkErr()
 | ||||
| //#endif
 | ||||
| /*#else */ | ||||
| /*#define gl_checkErr() */ | ||||
| /*#endif */ | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										78
									
								
								src/outfit.c
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								src/outfit.c
									
									
									
									
									
								
							| @ -18,15 +18,15 @@ | ||||
| #define OUTFIT_DATA     "../dat/outfit.xml" | ||||
| #define OUTFIT_GFX      "../gfx/outfit/" | ||||
| 
 | ||||
| extern SDL_mutex* sound_lock; // Sound.c
 | ||||
| extern SDL_mutex* sound_lock; /* Sound.c */ | ||||
| 
 | ||||
| // The Stack.
 | ||||
| /* The Stack. */ | ||||
| static Outfit* outfit_stack = NULL; | ||||
| static int outfits = 0; | ||||
| 
 | ||||
| // Misc.
 | ||||
| /* Misc. */ | ||||
| static DamageType outfit_strToDamageType(char* buf); | ||||
| // Parsing.
 | ||||
| /* Parsing. */ | ||||
| static int outfit_parseDamage(DamageType* dtype, double* dmg, xmlNodePtr node); | ||||
| static Outfit* outfit_parse(const xmlNodePtr parent); | ||||
| static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent); | ||||
| @ -35,7 +35,7 @@ static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent); | ||||
| static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent); | ||||
| static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent); | ||||
| 
 | ||||
| // Return an outfit.
 | ||||
| /* Return an outfit. */ | ||||
| Outfit* outfit_get(const char* name) { | ||||
|   int i; | ||||
|   for(i = 0; i < outfits; i++) | ||||
| @ -44,7 +44,7 @@ Outfit* outfit_get(const char* name) { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| // Return all the outfits.
 | ||||
| /* Return all the outfits. */ | ||||
| char** outfit_getTech(int* n, const int* tech, const int techmax) { | ||||
|   int i, j; | ||||
|   char** outfitnames = malloc(sizeof(Outfit*) * outfits); | ||||
| @ -62,7 +62,7 @@ char** outfit_getTech(int* n, const int* tech, const int techmax) { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   // Actual size is bigger, but it'll just get freed ;).
 | ||||
|   /* Actual size is bigger, but it'll just get freed ;). */ | ||||
|   return outfitnames; | ||||
| } | ||||
| 
 | ||||
| @ -84,12 +84,12 @@ defualt: | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Return 1 if outfit is a weapon (beam/bolt).
 | ||||
| /* Return 1 if outfit is a weapon (beam/bolt). */ | ||||
| int outfit_isWeapon(const Outfit* o) { | ||||
|   return ((o->type == OUTFIT_TYPE_BOLT) || (o->type == OUTFIT_TYPE_BEAM)); | ||||
| } | ||||
| 
 | ||||
| // Return 1 if outfit is a launcher.
 | ||||
| /* Return 1 if outfit is a launcher. */ | ||||
| int outfit_isLauncher(const Outfit* o) { | ||||
|   return((o->type == OUTFIT_TYPE_MISSILE_DUMB) || | ||||
|          (o->type == OUTFIT_TYPE_MISSILE_SEEK) || | ||||
| @ -98,7 +98,7 @@ int outfit_isLauncher(const Outfit* o) { | ||||
|          (o->type == OUTFIT_TYPE_MISSILE_SWARM_SMART)); | ||||
| } | ||||
| 
 | ||||
| // Return 1 if outfit is weapon ammunition.
 | ||||
| /* Return 1 if outfit is weapon ammunition. */ | ||||
| int outfit_isAmmo(const Outfit* o) { | ||||
|   return((o->type == OUTFIT_TYPE_MISSILE_DUMB_AMMO) || | ||||
|          (o->type == OUTFIT_TYPE_MISSILE_SEEK_AMMO) || | ||||
| @ -113,17 +113,17 @@ int outfit_isTurret(const Outfit* o) { | ||||
|           (o->type == OUTFIT_TYPE_TURRET_BEAM)); | ||||
| } | ||||
| 
 | ||||
| // Return 1 if o is a modification.
 | ||||
| /* Return 1 if o is a modification. */ | ||||
| int outfit_isMod(const Outfit* o) { | ||||
|   return (o->type == OUTFIT_TYPE_MODIFICATION); | ||||
| } | ||||
| 
 | ||||
| // Return 1 if o is an afterburner.
 | ||||
| /* Return 1 if o is an afterburner. */ | ||||
| int outfit_isAfterburner(const Outfit* o) { | ||||
|   return (o->type == OUTFIT_TYPE_AFTERBURNER); | ||||
| } | ||||
| 
 | ||||
| // Get the outfit graphics.
 | ||||
| /* Get the outfit graphics. */ | ||||
| glTexture* outfit_gfx(const Outfit* o) { | ||||
|   if(outfit_isWeapon(o)) return o->u.blt.gfx_space; | ||||
|   else if(outfit_isAmmo(o)) return o->u.amm.gfx_space; | ||||
| @ -131,7 +131,7 @@ glTexture* outfit_gfx(const Outfit* o) { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| // Get the outfit spfx if applicable.
 | ||||
| /* Get the outfit spfx if applicable. */ | ||||
| int outfit_spfx(const Outfit* o) { | ||||
|   if(outfit_isWeapon(o)) return o->u.blt.spfx; | ||||
|   else if(outfit_isAmmo(o)) return o->u.amm.spfx; | ||||
| @ -191,7 +191,7 @@ const char* outfit_getType(const Outfit* o) { | ||||
|   return outfit_typename[o->type]; | ||||
| } | ||||
| 
 | ||||
| // Return the broad outfit type.
 | ||||
| /* Return the broad outfit type. */ | ||||
| const char* outfit_typenamebroad[] = { | ||||
|   "NULL", | ||||
|   "Weapon", | ||||
| @ -214,7 +214,7 @@ const char* outfit_getTypeBroad(const Outfit* o) { | ||||
|   return outfit_typenamebroad[i]; | ||||
| } | ||||
| 
 | ||||
| // Return the damage type from a str.
 | ||||
| /* Return the damage type from a str. */ | ||||
| static DamageType outfit_strToDamageType(char* buf) { | ||||
|   if(strcmp(buf, "energy")==0)        return DAMAGE_TYPE_ENERGY; | ||||
|   else if(strcmp(buf, "kinetic")==0)  return DAMAGE_TYPE_KINETIC; | ||||
| @ -241,14 +241,14 @@ static int outfit_parseDamage(DamageType* dtype, double* dmg, xmlNodePtr node) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Parses the specific area for a weapon and loads it into outfit.
 | ||||
| /* Parses the specific area for a weapon and loads it into outfit. */ | ||||
| static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent) { | ||||
|   xmlNodePtr node; | ||||
|   char str[PATH_MAX] = "\0"; | ||||
| 
 | ||||
|   node = parent->xmlChildrenNode; | ||||
|   do { | ||||
|     // Load all the things.
 | ||||
|     /* Load all the things. */ | ||||
|     xmlr_float(node, "speed",     tmp->u.blt.speed); | ||||
|     xmlr_float(node, "delay",     tmp->u.blt.delay); | ||||
|     xmlr_float(node, "range",     tmp->u.blt.range); | ||||
| @ -280,13 +280,13 @@ static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent) { | ||||
| #undef MELEMENT | ||||
| } | ||||
| 
 | ||||
| // Parse the specific area for a launcher and loads it into Outfit.
 | ||||
| /* Parse the specific area for a launcher and loads it into Outfit. */ | ||||
| static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent) { | ||||
|   xmlNodePtr node; | ||||
|   node = parent->xmlChildrenNode; | ||||
| 
 | ||||
|   do { | ||||
|     // Load the dataz.
 | ||||
|     /* Load the dataz. */ | ||||
|     if(xml_isNode(node, "delay")) tmp->u.lau.delay = xml_getInt(node); | ||||
|     else if(xml_isNode(node, "ammo")) tmp->u.lau.ammo = strdup(xml_get(node)); | ||||
|   } while((node = node->next)); | ||||
| @ -297,7 +297,7 @@ static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent) { | ||||
| #undef MELEMENT | ||||
| } | ||||
| 
 | ||||
| // Parse the specific area for a weapon and load it into Outfit.
 | ||||
| /* Parse the specific area for a weapon and load it into Outfit. */ | ||||
| static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent) { | ||||
|   xmlNodePtr node; | ||||
|   node = parent->xmlChildrenNode; | ||||
| @ -341,13 +341,13 @@ static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent) { | ||||
|   xmlNodePtr node; | ||||
|   node = parent->children; | ||||
| 
 | ||||
|   // Load all the data.
 | ||||
|   /* Load all the data. */ | ||||
|   do { | ||||
|     // Movement.
 | ||||
|     /* Movement. */ | ||||
|     xmlr_float(node, "thrust", tmp->u.mod.thrust); | ||||
|     xmlr_float(node, "turn", tmp->u.mod.turn); | ||||
|     xmlr_float(node, "speed", tmp->u.mod.speed); | ||||
|     // Health.
 | ||||
|     /* Health. */ | ||||
|     xmlr_float(node, "armour", tmp->u.mod.armour); | ||||
|     xmlr_float(node, "shield", tmp->u.mod.shield); | ||||
|     xmlr_float(node, "energy", tmp->u.mod.energy); | ||||
| @ -359,18 +359,18 @@ static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent) { | ||||
|     else if(xml_isNode(node, "energy_regen")) | ||||
|       tmp->u.mod.energy_regen = xml_getFloat(node)/60.0; | ||||
| 
 | ||||
|     // Misc.
 | ||||
|     /* Misc. */ | ||||
|     xmlr_int(node, "cargo", tmp->u.mod.cargo); | ||||
| 
 | ||||
|   } while((node = node->next)); | ||||
| } | ||||
| 
 | ||||
| // Parses the afterburner tidbits of the outfit.
 | ||||
| /* Parses the afterburner tidbits of the outfit. */ | ||||
| static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent) { | ||||
|   xmlNodePtr node; | ||||
|   node = parent->children; | ||||
| 
 | ||||
|   // Must be >= 1.
 | ||||
|   /* Must be >= 1. */ | ||||
|   tmp->u.afb.thrust_perc  = 1.; | ||||
|   tmp->u.afb.speed_perc  = 1.; | ||||
| 
 | ||||
| @ -388,19 +388,19 @@ static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent) { | ||||
|   } while((node = node->next)); | ||||
| } | ||||
| 
 | ||||
| // Parse and return Outfits from parent node.
 | ||||
| /* Parse and return Outfits from parent node. */ | ||||
| static Outfit* outfit_parse(const xmlNodePtr parent) { | ||||
|   Outfit* tmp = CALLOC_L(Outfit); | ||||
|   xmlNodePtr cur, node; | ||||
|   char* prop; | ||||
|   char str[PATH_MAX] = "\0"; | ||||
| 
 | ||||
|   tmp->name = xml_nodeProp(parent, "name"); // Already malloced.
 | ||||
|   tmp->name = xml_nodeProp(parent, "name"); /* Already malloced. */ | ||||
|   if(tmp->name == NULL) WARN("Outfit in "OUTFIT_DATA" has invalid or no name"); | ||||
| 
 | ||||
|   node = parent->xmlChildrenNode; | ||||
|   do { | ||||
|     // Load all the things.
 | ||||
|     /* Load all the things. */ | ||||
|     if(xml_isNode(node, "general")) { | ||||
|       cur = node->children; | ||||
|       do { | ||||
| @ -417,16 +417,16 @@ static Outfit* outfit_parse(const xmlNodePtr parent) { | ||||
|       } while((cur = cur->next)); | ||||
|     } | ||||
|     else if(xml_isNode(node, "specific")) { | ||||
|       // Has to be processed seperately.
 | ||||
|       /* Has to be processed seperately. */ | ||||
| 
 | ||||
|       // Get the type.
 | ||||
|       /* Get the type. */ | ||||
|       prop = xml_nodeProp(node, "type"); | ||||
|       if(prop == NULL) | ||||
|         ERR("Outfit '%s' element 'specific' missing property 'type'", tmp->name); | ||||
|       tmp->type = atoi(prop); | ||||
|       free(prop); | ||||
| 
 | ||||
|       // Is this the secondary weapon?
 | ||||
|       /* Is this the secondary weapon? */ | ||||
|       prop = xml_nodeProp(node, "secondary"); | ||||
|       if(prop != NULL) { | ||||
|         if((int)atoi(prop)) outfit_setProp(tmp, OUTFIT_PROP_WEAP_SECONDARY); | ||||
| @ -453,7 +453,7 @@ static Outfit* outfit_parse(const xmlNodePtr parent) { | ||||
|   MELEMENT(tmp->max==0,        "max"); | ||||
|   MELEMENT(tmp->tech==0,       "tech"); | ||||
|   MELEMENT(tmp->gfx_store==NULL,  "gfx_store"); | ||||
|   //MELEMENT(tmp->mass==0,      "mass");
 | ||||
|   /*MELEMENT(tmp->mass==0,      "mass"); */ | ||||
|   MELEMENT(tmp->type==0,       "type"); | ||||
|   MELEMENT(tmp->price==0,      "price"); | ||||
|   MELEMENT(tmp->description==NULL,  "description"); | ||||
| @ -462,7 +462,7 @@ static Outfit* outfit_parse(const xmlNodePtr parent) { | ||||
|   return tmp; | ||||
| } | ||||
| 
 | ||||
| // Load all the outfits into the outfit stack.
 | ||||
| /* Load all the outfits into the outfit stack. */ | ||||
| int outfit_load(void) { | ||||
|   uint32_t bufsize; | ||||
|   char* buf = pack_readfile(DATA, OUTFIT_DATA, &bufsize); | ||||
| @ -478,7 +478,7 @@ int outfit_load(void) { | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   node = node->xmlChildrenNode; // First system node.
 | ||||
|   node = node->xmlChildrenNode; /* First system node. */ | ||||
|   if(node == NULL) { | ||||
|     ERR("Malformed "OUTFIT_DATA" file: does not contain elements"); | ||||
|     return -1; | ||||
| @ -502,15 +502,15 @@ int outfit_load(void) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Frees the outfit stack.
 | ||||
| /* Frees the outfit stack. */ | ||||
| void outfit_free(void) { | ||||
|   int i; | ||||
|   for(i = 0; i < outfits; i++) { | ||||
|     // Free graphics.
 | ||||
|     /* Free graphics. */ | ||||
|     if(outfit_gfx(&outfit_stack[i])) | ||||
|       gl_freeTexture(outfit_gfx(&outfit_stack[i])); | ||||
| 
 | ||||
|     // Strings.
 | ||||
|     /* Strings. */ | ||||
|     if(outfit_isLauncher(&outfit_stack[i]) && outfit_stack[i].u.lau.ammo) | ||||
|       free(outfit_stack[i].u.lau.ammo); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										102
									
								
								src/outfit.h
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								src/outfit.h
									
									
									
									
									
								
							| @ -3,10 +3,10 @@ | ||||
| #include "sound.h" | ||||
| 
 | ||||
| #define outfit_isProp(o,p)  ((o)->properties & p) | ||||
| // Property flags.
 | ||||
| /* Property flags. */ | ||||
| #define OUTFIT_PROP_WEAP_SECONDARY (1<<0) | ||||
| 
 | ||||
| // Outfit types.
 | ||||
| /* Outfit types. */ | ||||
| typedef enum OutfitType_ { | ||||
|   OUTFIT_TYPE_NULL                      = 0, | ||||
|   OUTFIT_TYPE_BOLT                      = 1, | ||||
| @ -33,94 +33,94 @@ typedef enum DamageType_ { | ||||
|   DAMAGE_TYPE_KINETIC = 2 | ||||
| } DamageType; | ||||
| 
 | ||||
| // An outfit depends a lot on the type.
 | ||||
| /* An outfit depends a lot on the type. */ | ||||
| typedef struct Outfit_ { | ||||
|   char* name; | ||||
| 
 | ||||
|   // General specs.
 | ||||
|   /* General specs. */ | ||||
|   int max; | ||||
|   int tech; | ||||
|   int mass; | ||||
| 
 | ||||
|   // Store stuff.
 | ||||
|   /* Store stuff. */ | ||||
|   unsigned int price; | ||||
|   char* description; | ||||
| 
 | ||||
|   glTexture* gfx_store; // Store graphic.
 | ||||
|   glTexture* gfx_store; /* Store graphic. */ | ||||
| 
 | ||||
|   int properties; // Properties stored bitwise.
 | ||||
|   int properties; /* Properties stored bitwise. */ | ||||
| 
 | ||||
|   // Type dependant.
 | ||||
|   /* Type dependant. */ | ||||
|   OutfitType type; | ||||
|   union { | ||||
|     struct { // Bolt.
 | ||||
|       unsigned int delay; // Delay between shots.
 | ||||
|       double speed;       // Speed of shot. (not applicable to beam.
 | ||||
|     struct { /* Bolt. */ | ||||
|       unsigned int delay; /* Delay between shots. */ | ||||
|       double speed;       /* Speed of shot. (not applicable to beam. */ | ||||
|       double range; | ||||
|       double accuracy;    // Desviation accuracy.
 | ||||
|       double energy;      // Energy usage.
 | ||||
|       DamageType dtype;   // Damage type.
 | ||||
|       double damage;      // Damage.
 | ||||
|       double accuracy;    /* Desviation accuracy. */ | ||||
|       double energy;      /* Energy usage. */ | ||||
|       DamageType dtype;   /* Damage type. */ | ||||
|       double damage;      /* Damage. */ | ||||
| 
 | ||||
|       glTexture* gfx_space; | ||||
|       ALuint sound; // Sound to play.
 | ||||
|       int spfx;     // Special effect on hit.
 | ||||
|       ALuint sound; /* Sound to play. */ | ||||
|       int spfx;     /* Special effect on hit. */ | ||||
|     } blt; | ||||
|     struct { // Beam.
 | ||||
|       double range;     // Distance it travels.
 | ||||
|       glColour colour;  // Beam colour.
 | ||||
|       double energy;    // Energy drained.
 | ||||
|       double damage_armour, damage_shield; // Damage.
 | ||||
|     struct { /* Beam. */ | ||||
|       double range;     /* Distance it travels. */ | ||||
|       glColour colour;  /* Beam colour. */ | ||||
|       double energy;    /* Energy drained. */ | ||||
|       double damage_armour, damage_shield; /* Damage. */ | ||||
|     } bem; | ||||
|     struct { // Launcher.
 | ||||
|       unsigned int delay; // Delay between shots.
 | ||||
|     struct { /* Launcher. */ | ||||
|       unsigned int delay; /* Delay between shots. */ | ||||
|       char* ammo; | ||||
|     } lau; | ||||
|     struct { // Ammo.
 | ||||
|       unsigned int duration;  // Duration.
 | ||||
|       double speed;           // Max speed.
 | ||||
|       double turn;            // Turn vel.
 | ||||
|       double thrust;          // Acceleration.
 | ||||
|       double energy;          // Energy usage.
 | ||||
|       DamageType dtype;       // Damage type.
 | ||||
|       double damage;          // Damage.
 | ||||
|     struct { /* Ammo. */ | ||||
|       unsigned int duration;  /* Duration. */ | ||||
|       double speed;           /* Max speed. */ | ||||
|       double turn;            /* Turn vel. */ | ||||
|       double thrust;          /* Acceleration. */ | ||||
|       double energy;          /* Energy usage. */ | ||||
|       DamageType dtype;       /* Damage type. */ | ||||
|       double damage;          /* Damage. */ | ||||
| 
 | ||||
|       glTexture* gfx_space; | ||||
|       ALuint sound;         // Sound to play.
 | ||||
|       int spfx;             // Special effect on hit.
 | ||||
|       unsigned int lockon;  // Time taken to lock on the target.
 | ||||
|       ALuint sound;         /* Sound to play. */ | ||||
|       int spfx;             /* Special effect on hit. */ | ||||
|       unsigned int lockon;  /* Time taken to lock on the target. */ | ||||
|     } amm; | ||||
|     struct { // Modification.
 | ||||
|       // Movement.
 | ||||
|     struct { /* Modification. */ | ||||
|       /* Movement. */ | ||||
|       double thrust, turn, speed; | ||||
| 
 | ||||
|       // Health.
 | ||||
|       /* Health. */ | ||||
|       double armour, armour_regen; | ||||
|       double shield, shield_regen; | ||||
|       double energy, energy_regen; | ||||
|       double fuel; | ||||
| 
 | ||||
|       // Misc.
 | ||||
|       int cargo; // Cargo space to add.
 | ||||
|       /* Misc. */ | ||||
|       int cargo; /* Cargo space to add. */ | ||||
|     } mod; | ||||
|     struct { // Afterburner.
 | ||||
|       double rumble;                    // Percent of rumble.
 | ||||
|       ALuint sound;                     // Sound of the afterburner.
 | ||||
|       double thrust_perc, thrust_abs;   // Percent and absolute thrust bonus.
 | ||||
|       double speed_perc, speed_abs;     // Percent and absolute speed bonus.
 | ||||
|       double energy;                    // Energy used while active.
 | ||||
|     struct { /* Afterburner. */ | ||||
|       double rumble;                    /* Percent of rumble. */ | ||||
|       ALuint sound;                     /* Sound of the afterburner. */ | ||||
|       double thrust_perc, thrust_abs;   /* Percent and absolute thrust bonus. */ | ||||
|       double speed_perc, speed_abs;     /* Percent and absolute speed bonus. */ | ||||
|       double energy;                    /* Energy used while active. */ | ||||
|     } afb; | ||||
|   } u; | ||||
| } Outfit; | ||||
| 
 | ||||
| // Misc.
 | ||||
| /* Misc. */ | ||||
| void outfit_calcDamage(double* dshield, double* darmour, | ||||
|     DamageType dtype, double dmg); | ||||
| 
 | ||||
| // Get.
 | ||||
| /* Get. */ | ||||
| Outfit* outfit_get(const char* name); | ||||
| char** outfit_getTech(int* n, const int* tech, const int techmax); | ||||
| // Outfit types.
 | ||||
| /* Outfit types. */ | ||||
| int outfit_isWeapon(const Outfit* o); | ||||
| int outfit_isLauncher(const Outfit* o); | ||||
| int outfit_isAmmo(const Outfit* o); | ||||
| @ -130,7 +130,7 @@ int outfit_isAfterburner(const Outfit* o); | ||||
| const char* outfit_getType(const Outfit* o); | ||||
| const char* outfit_getTypeBroad(const Outfit* o); | ||||
| 
 | ||||
| // Get data from outfit.
 | ||||
| /* Get data from outfit. */ | ||||
| glTexture* outfit_gfx(const Outfit* o); | ||||
| int outfit_spfx(const Outfit* o); | ||||
| double outfit_damage(const Outfit* o); | ||||
| @ -138,7 +138,7 @@ DamageType outfit_damageType(const Outfit* o); | ||||
| int outfit_delay(const Outfit* o); | ||||
| double outfit_energy(const Outfit* o); | ||||
| 
 | ||||
| // Load/free outfit stack.
 | ||||
| /* Load/free outfit stack. */ | ||||
| int outfit_load(void); | ||||
| void outfit_free(void); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										126
									
								
								src/pack.c
									
									
									
									
									
								
							
							
						
						
									
										126
									
								
								src/pack.c
									
									
									
									
									
								
							| @ -1,5 +1,5 @@ | ||||
| #include <stdio.h> | ||||
| #include <sys/stat.h> // S_IRUSR | ||||
| #include <sys/stat.h> /* S_IRUSR */ | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <string.h> | ||||
| @ -9,39 +9,39 @@ | ||||
| #include "log.h" | ||||
| #include "md5.h" | ||||
| 
 | ||||
| // == Store data in a funky format. =======================
 | ||||
| // Format:
 | ||||
| //  -- Index.
 | ||||
| //    -- Magic number (16 bytes).
 | ||||
| //    -- Number of files (uint32_t).
 | ||||
| //    -- Files in format name/location.
 | ||||
| //      -- File name (128 bytes max, ending in \0).
 | ||||
| //      -- File location (uint32_t).
 | ||||
| //  -- File data in format Size/Data.
 | ||||
| //    -- File size (uint32_t).
 | ||||
| //    -- File data (char*).
 | ||||
| //    -- File MD5 (16 byte char*).
 | ||||
| //  -- EOF
 | ||||
| //
 | ||||
| // -- Write magic number and number of files.
 | ||||
| // -- Write the index.
 | ||||
| // -- Pack the files.
 | ||||
| // ========================================================
 | ||||
| /* == Store data in a funky format. ======================= */ | ||||
| /* Format: */ | ||||
| /*  -- Index. */ | ||||
| /*    -- Magic number (16 bytes). */ | ||||
| /*    -- Number of files (uint32_t). */ | ||||
| /*    -- Files in format name/location. */ | ||||
| /*      -- File name (128 bytes max, ending in \0). */ | ||||
| /*      -- File location (uint32_t). */ | ||||
| /*  -- File data in format Size/Data. */ | ||||
| /*    -- File size (uint32_t). */ | ||||
| /*    -- File data (char*). */ | ||||
| /*    -- File MD5 (16 byte char*). */ | ||||
| /*  -- EOF */ | ||||
| /* */ | ||||
| /* -- Write magic number and number of files. */ | ||||
| /* -- Write the index. */ | ||||
| /* -- Pack the files. */ | ||||
| /* ======================================================== */ | ||||
| 
 | ||||
| #undef DEBUG // this will be spammy.
 | ||||
| #undef DEBUG /* this will be spammy. */ | ||||
| #define DEBUG(str, args...) do{;} while(0) | ||||
| 
 | ||||
| // The read/write block size.
 | ||||
| /* The read/write block size. */ | ||||
| #define BLOCKSIZE 128*1024 | ||||
| 
 | ||||
| // Max filename length.
 | ||||
| /* Max filename length. */ | ||||
| #define MAX_FILENAME 100 | ||||
| 
 | ||||
| #define PERMS S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | ||||
| 
 | ||||
| const uint64_t magic = 0x25524573; // sER%
 | ||||
| const uint64_t magic = 0x25524573; /* sER% */ | ||||
| 
 | ||||
| // Grab the filesize.
 | ||||
| /* Grab the filesize. */ | ||||
| static off_t getfilesize(const char* filename) { | ||||
| #ifdef _POSIX_SOURCE | ||||
|   struct stat file; | ||||
| @ -65,7 +65,7 @@ static off_t getfilesize(const char* filename) { | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| // Return true if filename is a Packfile.
 | ||||
| /* Return true if filename is a Packfile. */ | ||||
| int pack_check(const char* filename) { | ||||
|   int ret; | ||||
|   char* buf; | ||||
| @ -108,7 +108,7 @@ int pack_check(const char* filename) { | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| // Pack nfiles, infiles into outfile.
 | ||||
| /* Pack nfiles, infiles into outfile. */ | ||||
| #ifdef _POSIX_SOURCE | ||||
| #define WRITE(b,n) if(write(outfd, b, n)==-1) { \ | ||||
|   ERR("Error writing to file: %s", strerror(errno)); \ | ||||
| @ -133,7 +133,7 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles) | ||||
|   const uint8_t b = '\0'; | ||||
| 
 | ||||
|   for(namesize = 0, i = 0; i < nfiles; i++) { | ||||
|     // Make sure file exists before writing.
 | ||||
|     /* Make sure file exists before writing. */ | ||||
| #ifdef _POSIX_SOURCE | ||||
|     if(stat(infiles[i], &file)) { | ||||
| #else | ||||
| @ -150,12 +150,12 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles) | ||||
|     namesize += strlen(infiles[i]); | ||||
|   } | ||||
| 
 | ||||
|   indexsize = (sizeof(magic) + 4 + // Magic number and number of files.
 | ||||
|                namesize + // Total length of file names.
 | ||||
|                (1+4)*nfiles);  // File size and extra end of string char '\0'.
 | ||||
|   indexsize = (sizeof(magic) + 4 + /* Magic number and number of files. */ | ||||
|                namesize + /* Total length of file names. */ | ||||
|                (1+4)*nfiles);  /* File size and extra end of string char '\0'. */ | ||||
|   DEBUG("Index size is %d", indexsize); | ||||
| 
 | ||||
|   // Create the output file.
 | ||||
|   /* Create the output file. */ | ||||
| #ifdef _POSIX_SOURCE | ||||
|   outfd = creat(outfile, PERMS); | ||||
|   if(outfd == -1) { | ||||
| @ -167,31 +167,31 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles) | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   // Index!
 | ||||
|   /* Index! */ | ||||
|   buf = malloc(BLOCKSIZE); | ||||
| 
 | ||||
|   // Magic number.
 | ||||
|   /* Magic number. */ | ||||
|   WRITE(&magic, sizeof(magic)); | ||||
|   DEBUG("Wrote magic number"); | ||||
|   // Number of files.
 | ||||
|   /* Number of files. */ | ||||
|   WRITE(&nfiles, sizeof(nfiles)); | ||||
|   DEBUG("Wrote number of files: %d", nfiles); | ||||
|   // Create file dependent index part.
 | ||||
|   /* Create file dependent index part. */ | ||||
|   pointer = indexsize; | ||||
|   for(i = 0; i < nfiles; i++) { | ||||
|     WRITE(infiles[i], strlen(infiles[i])); | ||||
|     DEBUG("File: '%s' at %d", infiles[i], pointer); | ||||
|     WRITE(&b, 1); | ||||
|     WRITE(&pointer, 4); | ||||
|     pointer += 4 + getfilesize(infiles[i]) + 16; // Set pointer to be next file pos.
 | ||||
|     pointer += 4 + getfilesize(infiles[i]) + 16; /* Set pointer to be next file pos. */ | ||||
|   } | ||||
| 
 | ||||
|   // Data!
 | ||||
|   /* Data! */ | ||||
|   md5_state_t md5; | ||||
|   md5_byte_t* md5val = malloc(16); | ||||
|   for(i = 0; i < nfiles; i++) { | ||||
|     bytes = (uint32_t)getfilesize(infiles[i]); | ||||
|     WRITE(&bytes, 4); // filesize.
 | ||||
|     WRITE(&bytes, 4); /* filesize. */ | ||||
|     DEBUG("About to write '%s' of %d bytes", infiles[i], bytes); | ||||
|     md5_init(&md5); | ||||
| #ifdef _POSIX_SOURCE | ||||
| @ -201,7 +201,7 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles) | ||||
|     inf = fopen(infiles[i], "rb"); | ||||
|     while((bytes = fread(buf, 1, BLOCKSIZE, inf))) { | ||||
| #endif | ||||
|       WRITE(buf, bytes); // Data.
 | ||||
|       WRITE(buf, bytes); /* Data. */ | ||||
|       md5_append(&md5, buf, bytes); | ||||
|     } | ||||
|     md5_finish(&md5, md5val); | ||||
| @ -228,7 +228,7 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles) | ||||
| } | ||||
| #undef WRITE | ||||
| 
 | ||||
| // Opens the filename in packfile for reading.
 | ||||
| /* Opens the filename in packfile for reading. */ | ||||
| #ifdef _POSIX_SOURCE | ||||
| #define READ(b,n) if(read(file->fd, (b), (n))!=(n)) { \ | ||||
|   ERR("Too few bytes read. Expected more."); \ | ||||
| @ -256,7 +256,7 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) { | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   READ(buf, sizeof(magic)); // Make sure it's a packfile.
 | ||||
|   READ(buf, sizeof(magic)); /* Make sure it's a packfile. */ | ||||
|   if(memcmp(buf, &magic, sizeof(magic))) { | ||||
|     ERR("File %s is not a valid packfile", filename); | ||||
|     return -1; | ||||
| @ -264,20 +264,20 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) { | ||||
| 
 | ||||
|   READ(&nfiles, 4); | ||||
|   for(i = 0; i < nfiles; i++) { | ||||
|     // Start to search files.
 | ||||
|     /* Start to search files. */ | ||||
|     j = 0; | ||||
|     READ(&buf[j], 1); // Get the name.
 | ||||
|     READ(&buf[j], 1); /* Get the name. */ | ||||
|     while(buf[j++] != '\0') | ||||
|       READ(&buf[j], 1); | ||||
| 
 | ||||
|     if(strcmp(filename, buf) == 0) { | ||||
|       // We found the file.
 | ||||
|       /* We found the file. */ | ||||
|       READ(&file->start, 4); | ||||
|       DEBUG("'%s' found at %d", filename, file->start); | ||||
|       break; | ||||
|     } | ||||
| #ifdef _POSIX_SOURCE | ||||
|     lseek(file->fd, 4, SEEK_CUR); // Ignore the file location.
 | ||||
|     lseek(file->fd, 4, SEEK_CUR); /* Ignore the file location. */ | ||||
| #else | ||||
|     fseek(file->fp, 4, SEEK_CUR); | ||||
| #endif | ||||
| @ -285,7 +285,7 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) { | ||||
|   free(buf); | ||||
| 
 | ||||
|   if(file->start) { | ||||
|     // Go to the beginning of the file.
 | ||||
|     /* Go to the beginning of the file. */ | ||||
| #ifdef _POSIX_SOURCE | ||||
|     if((uint32_t)lseek(file->fd, file->start, SEEK_SET) != file->start) { | ||||
| #else | ||||
| @ -307,10 +307,10 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) { | ||||
| } | ||||
| #undef READ | ||||
| 
 | ||||
| // Read count bytes from file and put them into buf.
 | ||||
| /* Read count bytes from file and put them into buf. */ | ||||
| ssize_t pack_read(Packfile* file, void* buf, size_t count) { | ||||
|   if(file->pos + count > file->end) | ||||
|     count = file->end - file->pos; // Can't go past the end!
 | ||||
|     count = file->end - file->pos; /* Can't go past the end! */ | ||||
|   if(count == 0) return 0; | ||||
| 
 | ||||
|   int bytes; | ||||
| @ -328,7 +328,7 @@ ssize_t pack_read(Packfile* file, void* buf, size_t count) { | ||||
|   return bytes; | ||||
| } | ||||
| 
 | ||||
| // Seek in the packfile.
 | ||||
| /* Seek in the packfile. */ | ||||
| off_t pack_seek(Packfile* file, off_t offset, int whence) { | ||||
|   DEBUG("Attempting to seek offset: %d, whence: %d", offset, whence); | ||||
|   off_t ret; | ||||
| @ -373,12 +373,12 @@ off_t pack_seek(Packfile* file, off_t offset, int whence) { | ||||
|   return ret - file->start; | ||||
| } | ||||
| 
 | ||||
| // Return current pointer position.
 | ||||
| /* Return current pointer position. */ | ||||
| long pack_tell(Packfile* file) { | ||||
|   return file->pos - file->start; | ||||
| } | ||||
| 
 | ||||
| // Loads an entire file into memory and returns a pointer to it.
 | ||||
| /* Loads an entire file into memory and returns a pointer to it. */ | ||||
| void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesize) { | ||||
|   Packfile* file = (Packfile*)malloc(sizeof(Packfile)); | ||||
|   void* buf; | ||||
| @ -393,7 +393,7 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi | ||||
|   } | ||||
|   DEBUG("Opened file '%s' from '%s'", filename, packfile); | ||||
| 
 | ||||
|   // Read the entire file.
 | ||||
|   /* Read the entire file. */ | ||||
|   size = file->end - file->start; | ||||
|   buf = malloc(size+1); | ||||
|   if((bytes = pack_read(file, buf, size)) != size) { | ||||
| @ -404,9 +404,9 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi | ||||
|     return NULL; | ||||
|   } | ||||
|   DEBUG("Read %d bytes from '%s'", bytes, filename); | ||||
|   memset(buf+size, 0, 1); // Append size '\0' for it to validate as a string.
 | ||||
|   memset(buf+size, 0, 1); /* Append size '\0' for it to validate as a string. */ | ||||
| 
 | ||||
|   // Check the md5.
 | ||||
|   /* Check the md5. */ | ||||
|   md5_state_t md5; | ||||
|   md5_byte_t* md5val = malloc(16); | ||||
|   md5_byte_t* md5fd = malloc(16); | ||||
| @ -424,7 +424,7 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi | ||||
|   free(md5val); | ||||
|   free(md5fd); | ||||
| 
 | ||||
|   // Cleanup.
 | ||||
|   /* Cleanup. */ | ||||
|   if(pack_close(file) == -1) { | ||||
|     ERR("Closing packfile"); | ||||
|     free(file); | ||||
| @ -438,9 +438,9 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi | ||||
|   return buf; | ||||
| } | ||||
| 
 | ||||
| // Load the filenames int the packfile to filenames.
 | ||||
| // filenames should be freed after use
 | ||||
| // On error if filenames is (char**)-1.
 | ||||
| /* Load the filenames int the packfile to filenames. */ | ||||
| /* filenames should be freed after use */ | ||||
| /* On error if filenames is (char**)-1. */ | ||||
| #ifdef _POSIX_SOURCE | ||||
| #define READ(b,n) if(read(fd, (b), (n))!=(n)) { \ | ||||
|   ERR("Too few bytes read"); \ | ||||
| @ -473,7 +473,7 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) { | ||||
|     ERR("opening %s: %s", packfile, strerror(errno)); | ||||
|     return NULL; | ||||
|   } | ||||
|   READ(buf, sizeof(magic)); // Make sure it is a packfile.
 | ||||
|   READ(buf, sizeof(magic)); /* Make sure it is a packfile. */ | ||||
|   if(memcmp(buf, &magic, sizeof(magic))) { | ||||
|     ERR("File %s is not a valid packfile", packfile); | ||||
|     return NULL; | ||||
| @ -482,13 +482,13 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) { | ||||
|   READ(nfiles, 4); | ||||
|   filenames = malloc(((*nfiles)+1)*sizeof(char*)); | ||||
|   for(i = 0; i < *nfiles; i++) { | ||||
|     // Start searching files.
 | ||||
|     /* Start searching files. */ | ||||
|     j = 0; | ||||
|     filenames[i] = malloc(MAX_FILENAME * sizeof(char)); | ||||
|     READ(&filenames[i][j], 1); // Get the name.
 | ||||
|     READ(&filenames[i][j], 1); /* Get the name. */ | ||||
|     while(filenames[i][j++] != '\0') | ||||
|       READ(&filenames[i][j], 1); | ||||
|     READ(buf, 4); // skip the location.
 | ||||
|     READ(buf, 4); /* skip the location. */ | ||||
|   } | ||||
|   free(buf); | ||||
| 
 | ||||
| @ -502,7 +502,7 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) { | ||||
| } | ||||
| #undef READ | ||||
| 
 | ||||
| // Close the packfile.
 | ||||
| /* Close the packfile. */ | ||||
| int pack_close(Packfile* file) { | ||||
|   int i; | ||||
| #ifdef _POSIX_SOURCE | ||||
|  | ||||
							
								
								
									
										14
									
								
								src/pack.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/pack.h
									
									
									
									
									
								
							| @ -1,23 +1,23 @@ | ||||
| #pragma once | ||||
| #include <fcntl.h> | ||||
| #ifndef _POSIX_SOURCE // No posix.
 | ||||
| #ifndef _POSIX_SOURCE /* No posix. */ | ||||
| #include <stdio.h> | ||||
| #endif | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| typedef struct Packfile_ { | ||||
| #ifdef _POSIX_SOURCE | ||||
|   int fd; // File descriptor.
 | ||||
|   int fd; /* File descriptor. */ | ||||
| #else | ||||
|   FILE* fp; | ||||
| #endif | ||||
|   uint32_t pos; // position.
 | ||||
|   uint32_t start, end; // file limits.
 | ||||
|   uint32_t pos; /* position. */ | ||||
|   uint32_t start, end; /* file limits. */ | ||||
| } Packfile; | ||||
| 
 | ||||
| // Packfile manipulation. Automatically allocated and freed (with open and close).
 | ||||
| /* Packfile manipulation. Automatically allocated and freed (with open and close). */ | ||||
| 
 | ||||
| // Basic.
 | ||||
| /* Basic. */ | ||||
| int pack_check(const char* filename); | ||||
| int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles); | ||||
| int pack_open(Packfile* file, const char* packfile, const char* filename); | ||||
| @ -26,7 +26,7 @@ off_t pack_seek(Packfile* file, off_t offset, int whence); | ||||
| long pack_tell(Packfile* file); | ||||
| int pack_close(Packfile* file); | ||||
| 
 | ||||
| // Fancy stuff.
 | ||||
| /* Fancy stuff. */ | ||||
| void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesize); | ||||
| char** pack_listfiles(const char* packfile, uint32_t* nfiles); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										22
									
								
								src/pause.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/pause.c
									
									
									
									
									
								
							| @ -3,37 +3,37 @@ | ||||
| #include "spfx.h" | ||||
| #include "pause.h" | ||||
| 
 | ||||
| // Main thing with pausing is to allow things based on time to
 | ||||
| // work properly when the toolkit opens a window.
 | ||||
| /* Main thing with pausing is to allow things based on time to */ | ||||
| /* work properly when the toolkit opens a window. */ | ||||
| 
 | ||||
| int paused = 0; // Are we paused.
 | ||||
| int paused = 0; /* Are we paused. */ | ||||
| 
 | ||||
| // From pilot.c
 | ||||
| /* From pilot.c */ | ||||
| extern Pilot** pilot_stack; | ||||
| extern int pilots; | ||||
| // From space.c
 | ||||
| /* From space.c */ | ||||
| extern unsigned int spawn_timer; | ||||
| // From main.c
 | ||||
| /* From main.c */ | ||||
| extern unsigned int gtime; | ||||
| 
 | ||||
| static void pilots_pause(void); | ||||
| static void pilots_unpause(void); | ||||
| static void pilots_delay(unsigned int delay); | ||||
| 
 | ||||
| // Pause the game.
 | ||||
| /* Pause the game. */ | ||||
| void pause_game(void) { | ||||
|   if(paused) return; // Well well.. We are paused already.
 | ||||
|   if(paused) return; /* Well well.. We are paused already. */ | ||||
| 
 | ||||
|   pilots_pause(); | ||||
|   weapons_pause(); | ||||
|   spfx_pause(); | ||||
|   spawn_timer -= SDL_GetTicks(); | ||||
| 
 | ||||
|   paused = 1; // We should unpause it.
 | ||||
|   paused = 1; /* We should unpause it. */ | ||||
| } | ||||
| 
 | ||||
| void unpause_game(void) { | ||||
|   if(!paused) return; // We are unpaused already.
 | ||||
|   if(!paused) return; /* We are unpaused already. */ | ||||
| 
 | ||||
|   pilots_unpause(); | ||||
|   weapons_unpause(); | ||||
| @ -43,7 +43,7 @@ void unpause_game(void) { | ||||
|   paused = 0; | ||||
| } | ||||
| 
 | ||||
| // Set the timers back.
 | ||||
| /* Set the timers back. */ | ||||
| void pause_delay(unsigned int delay) { | ||||
|   pilots_delay(delay); | ||||
|   weapons_delay(delay); | ||||
|  | ||||
							
								
								
									
										114
									
								
								src/physics.c
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								src/physics.c
									
									
									
									
									
								
							| @ -6,9 +6,9 @@ | ||||
| #include "log.h" | ||||
| #include "physics.h" | ||||
| 
 | ||||
| // ================
 | ||||
| // MISC
 | ||||
| // ================
 | ||||
| /* ================ */ | ||||
| /* MISC */ | ||||
| /* ================ */ | ||||
| double angle_diff(const double ref, double a) { | ||||
|   double d; | ||||
|   if(a < M_PI) a += 2*M_PI; | ||||
| @ -19,15 +19,15 @@ double angle_diff(const double ref, double a) { | ||||
| void limit_speed(Vec2* vel, const double speed, const double dt) { | ||||
|   double vmod; | ||||
|   vmod = VMOD(*vel); | ||||
|   if(vmod > speed) // Should not go faster.
 | ||||
|   if(vmod > speed) /* Should not go faster. */ | ||||
|     vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel)); | ||||
| } | ||||
| 
 | ||||
| // ================
 | ||||
| // VEC2
 | ||||
| // ================
 | ||||
| /* ================ */ | ||||
| /* VEC2 */ | ||||
| /* ================ */ | ||||
| 
 | ||||
| // Set the vector value using cartesian coords.
 | ||||
| /* Set the vector value using cartesian coords. */ | ||||
| void vect_cset(Vec2* v, const double x, const double y) { | ||||
|   v->x = x; | ||||
|   v->y = y; | ||||
| @ -35,13 +35,13 @@ void vect_cset(Vec2* v, const double x, const double y) { | ||||
|   v->angle = ANGLE(x, y); | ||||
| } | ||||
| 
 | ||||
| // Create a minimal vector, only valid for blitting.
 | ||||
| /* Create a minimal vector, only valid for blitting. */ | ||||
| void vect_csetmin(Vec2* v, const double x, const double y) { | ||||
|   v->x = x; | ||||
|   v->y = y; | ||||
| } | ||||
| 
 | ||||
| // Set the vector value using polar coords.
 | ||||
| /* Set the vector value using polar coords. */ | ||||
| void vect_pset(Vec2* v, const double mod, const double angle) { | ||||
|   v->mod = mod; | ||||
|   v->angle = angle; | ||||
| @ -49,7 +49,7 @@ void vect_pset(Vec2* v, const double mod, const double angle) { | ||||
|   v->y = v->mod*sin(v->angle); | ||||
| } | ||||
| 
 | ||||
| // Copy vector source to destination.
 | ||||
| /* Copy vector source to destination. */ | ||||
| void vectcpy(Vec2* dest, const Vec2* src) { | ||||
|   dest->x = src->x; | ||||
|   dest->y = src->y; | ||||
| @ -57,12 +57,12 @@ void vectcpy(Vec2* dest, const Vec2* src) { | ||||
|   dest->angle = src->angle; | ||||
| } | ||||
| 
 | ||||
| // Null a vector.
 | ||||
| /* Null a vector. */ | ||||
| void vectnull(Vec2* v) { | ||||
|   v->x = v->y = v->mod = v->angle = 0.; | ||||
| } | ||||
| 
 | ||||
| // Get the direction pointed to by two vectors (from ref to v).
 | ||||
| /* Get the direction pointed to by two vectors (from ref to v). */ | ||||
| double vect_angle(const Vec2* ref, const Vec2* v) { | ||||
|   return ANGLE(v->x - ref->x, v->y - ref->y); | ||||
| } | ||||
| @ -75,23 +75,23 @@ void vect_cadd(Vec2* v, const double x, const double y) { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // ================
 | ||||
| // SOLID!
 | ||||
| // ================
 | ||||
| /* ================ */ | ||||
| /* SOLID! */ | ||||
| /* ================ */ | ||||
| 
 | ||||
| // ==Update method.========================================
 | ||||
| // d^2 x(t) / d t^2 = a, a = constant (acceleration)
 | ||||
| // x'(0) = v, x(0) = p
 | ||||
| //
 | ||||
| // d x(t) / d t = a*t + v, v = constant (initial velocity)
 | ||||
| // x(t) = a/2*t + v*t + p, p = constant (initial position)
 | ||||
| //
 | ||||
| // Since dt isn't actually differential this gives us an
 | ||||
| // error, so watch out with big values for dt.
 | ||||
| // ========================================================
 | ||||
| #if 0 // Simply commenting this out to avoid silly warnings.
 | ||||
| /* ==Update method.======================================== */ | ||||
| /* d^2 x(t) / d t^2 = a, a = constant (acceleration) */ | ||||
| /* x'(0) = v, x(0) = p */ | ||||
| /* */ | ||||
| /* d x(t) / d t = a*t + v, v = constant (initial velocity) */ | ||||
| /* x(t) = a/2*t + v*t + p, p = constant (initial position) */ | ||||
| /* */ | ||||
| /* Since dt isn't actually differential this gives us an */ | ||||
| /* error, so watch out with big values for dt. */ | ||||
| /* ======================================================== */ | ||||
| #if 0 /* Simply commenting this out to avoid silly warnings. */
 | ||||
| static void simple_update(Solid* obj, const double dt) { | ||||
|   // Make sure angle doesn't flip.
 | ||||
|   /* Make sure angle doesn't flip. */ | ||||
|   obj->dir += M_PI/360.*obj->dir_vel*dt; | ||||
|   if(obj->dir > 2*M_PI)   obj->dir -= 2*M_PI; | ||||
|   if(obj->dir < 0.)      obj->dir += 2*M_PI; | ||||
| @ -102,7 +102,7 @@ static void simple_update(Solid* obj, const double dt) { | ||||
|   vx = obj->vel->x; | ||||
|   vy = obj->vel->y; | ||||
| 
 | ||||
|   if(obj->force.mod) { // Force applied on an object.
 | ||||
|   if(obj->force.mod) { /* Force applied on an object. */ | ||||
|     double ax, ay; | ||||
|     ax = obj->force->x/obj->mass; | ||||
|     ay = obj->force->y/obj->mass; | ||||
| @ -124,46 +124,46 @@ static void simple_update(Solid* obj, const double dt) { | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| // ==Runge-Kutta 4th method.===============================
 | ||||
| // d^2 x(t) / d t^2 = a, a = constant(acceleration)
 | ||||
| // x'(0) = v, x(0) = p
 | ||||
| // x'' = f(t, x, x') = (x', a)
 | ||||
| //
 | ||||
| // x_ {n+1} = x_n + h/6 (k1 + 2*k2 + 3*k3 + k4)
 | ||||
| //  h = (b-a)/2
 | ||||
| //  k1 = f(t_n, X_n), X_n = (x_n, x'_n)
 | ||||
| //  k2 = f(t_n + h/2, X_n + h/2*k1)
 | ||||
| //  k3 = f(t_n + h/2, X_n + h/2*k2)
 | ||||
| //  k4 = f(t_n + h,   X_n + h*k3)
 | ||||
| //
 | ||||
| // x_{n+1} = x_n + h/6x'_n + 3*h*a, 4*a)
 | ||||
| // ========================================================
 | ||||
| /* ==Runge-Kutta 4th method.=============================== */ | ||||
| /* d^2 x(t) / d t^2 = a, a = constant(acceleration) */ | ||||
| /* x'(0) = v, x(0) = p */ | ||||
| /* x'' = f(t, x, x') = (x', a) */ | ||||
| /* */ | ||||
| /* x_ {n+1} = x_n + h/6 (k1 + 2*k2 + 3*k3 + k4) */ | ||||
| /*  h = (b-a)/2 */ | ||||
| /*  k1 = f(t_n, X_n), X_n = (x_n, x'_n) */ | ||||
| /*  k2 = f(t_n + h/2, X_n + h/2*k1) */ | ||||
| /*  k3 = f(t_n + h/2, X_n + h/2*k2) */ | ||||
| /*  k4 = f(t_n + h,   X_n + h*k3) */ | ||||
| /* */ | ||||
| /* x_{n+1} = x_n + h/6x'_n + 3*h*a, 4*a) */ | ||||
| /* ======================================================== */ | ||||
| 
 | ||||
| #define RK4_MIN_H 0.01 // Minimal pass we want.
 | ||||
| #define RK4_MIN_H 0.01 /* Minimal pass we want. */ | ||||
| static void rk4_update(Solid* obj, const double dt) { | ||||
|   int i, N;                       // For iteration and pass calculation.
 | ||||
|   double h, px, py, vx, vy;       // Pass and position/velocity values.
 | ||||
|   double ix, iy, tx, ty, ax, ay;  // Initial and temp cartesian vector values.
 | ||||
|   // Make sure angle doesn't flip.
 | ||||
|   int i, N;                       /* For iteration and pass calculation. */ | ||||
|   double h, px, py, vx, vy;       /* Pass and position/velocity values. */ | ||||
|   double ix, iy, tx, ty, ax, ay;  /* Initial and temp cartesian vector values. */ | ||||
|   /* Make sure angle doesn't flip. */ | ||||
|   obj->dir += M_PI/180.*obj->dir_vel*dt; | ||||
|   if(obj->dir >= 2.*M_PI) obj->dir -= 2*M_PI; | ||||
|   else if(obj->dir < 0.)  obj->dir += 2*M_PI; | ||||
| 
 | ||||
|   N = (dt > RK4_MIN_H) ? (int)(dt/RK4_MIN_H) : 1; | ||||
|   h = dt / (double)N; // Step.
 | ||||
|   h = dt / (double)N; /* Step. */ | ||||
| 
 | ||||
|   px = obj->pos.x; | ||||
|   py = obj->pos.y; | ||||
|   vx = obj->vel.x; | ||||
|   vy = obj->vel.y; | ||||
| 
 | ||||
|   if(obj->force.mod) {  // Force applied on object.
 | ||||
|     // Movement quantity theorem : m*a = \sum f.
 | ||||
|   if(obj->force.mod) {  /* Force applied on object. */ | ||||
|     /* Movement quantity theorem : m*a = \sum f. */ | ||||
|     ax = obj->force.x / obj->mass; | ||||
|     ay = obj->force.y / obj->mass; | ||||
|      | ||||
|     for(i = 0; i < N; i++) { | ||||
|       // X component.
 | ||||
|       /* X component. */ | ||||
|       tx = ix = vx; | ||||
|       tx += 2.*ix + h*tx; | ||||
|       tx += 2.*ix + h*tx; | ||||
| @ -173,7 +173,7 @@ static void rk4_update(Solid* obj, const double dt) { | ||||
|       px += tx; | ||||
|       vx += ax*h; | ||||
| 
 | ||||
|       // Y component.
 | ||||
|       /* Y component. */ | ||||
|       ty = iy = vy; | ||||
|       ty += 2.*(iy + h/2.*ty); | ||||
|       ty += 2.*(iy + h/2.*ty); | ||||
| @ -185,14 +185,14 @@ static void rk4_update(Solid* obj, const double dt) { | ||||
|     } | ||||
|     vect_cset(&obj->vel, vx, vy); | ||||
|   } else { | ||||
|     // Euler method -> p = v*t + 0.5*a*t^2 (no accel, so no error).
 | ||||
|     /* Euler method -> p = v*t + 0.5*a*t^2 (no accel, so no error). */ | ||||
|     px += dt*vx; | ||||
|     py += dt*vy; | ||||
|   } | ||||
|   vect_cset(&obj->pos, px, py); | ||||
| } | ||||
| 
 | ||||
| // Initialize a new solid.
 | ||||
| /* Initialize a new solid. */ | ||||
| void solid_init(Solid* dest, const double mass, const double dir, | ||||
|                 const Vec2* pos, const Vec2* vel) { | ||||
|   dest->mass = mass; | ||||
| @ -213,7 +213,7 @@ void solid_init(Solid* dest, const double mass, const double dir, | ||||
|   dest->update = rk4_update; | ||||
| } | ||||
| 
 | ||||
| // Create a new solid.
 | ||||
| /* Create a new solid. */ | ||||
| Solid* solid_create(const double mass, const double dir, | ||||
|                     const Vec2* pos, const Vec2* vel) { | ||||
|   Solid* dyn = MALLOC_L(Solid); | ||||
| @ -222,7 +222,7 @@ Solid* solid_create(const double mass, const double dir, | ||||
|   return dyn; | ||||
| } | ||||
| 
 | ||||
| // Free an existing solid.
 | ||||
| /* Free an existing solid. */ | ||||
| void solid_free(Solid* src) { | ||||
|   free(src); | ||||
|   src = NULL; | ||||
|  | ||||
| @ -14,19 +14,19 @@ | ||||
| #define vect_odist(v)   MOD((v)->x, (v)->y) | ||||
| 
 | ||||
| 
 | ||||
| // Base of 2D vectors.
 | ||||
| /* Base of 2D vectors. */ | ||||
| typedef struct Vec2_ { | ||||
|   double x, y; // Cartesian values.
 | ||||
|   double mod, angle; // Polar values.
 | ||||
|   double x, y; /* Cartesian values. */ | ||||
|   double mod, angle; /* Polar values. */ | ||||
| } Vec2; | ||||
| 
 | ||||
| // Misc
 | ||||
| /* Misc */ | ||||
| double angle_diff(const double ref, double a); | ||||
| void limit_speed(Vec2* vel, const double speed, const double dt); | ||||
| 
 | ||||
| // Vector manupulation.
 | ||||
| /* Vector manupulation. */ | ||||
| void vect_cset(Vec2* v, const double x, const double y); | ||||
| // Doesn't set mod nor angle.
 | ||||
| /* Doesn't set mod nor angle. */ | ||||
| void vect_csetmin(Vec2* v, const double x, const double y); | ||||
| void vect_pset(Vec2* v, const double mod, const double angle); | ||||
| void vectcpy(Vec2* dest, const Vec2* src); | ||||
| @ -34,14 +34,14 @@ void vectnull(Vec2* v); | ||||
| double vect_angle(const Vec2* ref, const Vec2* v); | ||||
| void vect_cadd(Vec2* v, const double x, const double y); | ||||
| 
 | ||||
| // Describe any solid in 2D space.
 | ||||
| /* Describe any solid in 2D space. */ | ||||
| typedef struct Solid_ { | ||||
|   double mass, dir, dir_vel; // Properties.
 | ||||
|   Vec2 vel, pos, force; // Position/velocity vectors.
 | ||||
|   void(*update)(struct Solid_*, const double); // Update method.
 | ||||
|   double mass, dir, dir_vel; /* Properties. */ | ||||
|   Vec2 vel, pos, force; /* Position/velocity vectors. */ | ||||
|   void(*update)(struct Solid_*, const double); /* Update method. */ | ||||
| } Solid; | ||||
| 
 | ||||
| // Solid manipulation.
 | ||||
| /* Solid manipulation. */ | ||||
| void solid_init(Solid* dest, const double mass, const double dir, | ||||
|                 const Vec2* pos, const Vec2* vel); | ||||
| Solid* solid_create(const double mass, const double dir, | ||||
|  | ||||
							
								
								
									
										438
									
								
								src/pilot.c
									
									
									
									
									
								
							
							
						
						
									
										438
									
								
								src/pilot.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										172
									
								
								src/pilot.h
									
									
									
									
									
								
							
							
						
						
									
										172
									
								
								src/pilot.h
									
									
									
									
									
								
							| @ -9,139 +9,139 @@ | ||||
| 
 | ||||
| #define PLAYER_ID 1 | ||||
| 
 | ||||
| #define HYPERSPACE_ENGINE_DELAY   3000  // Warm up the engines.
 | ||||
| #define HYPERSPACE_FLY_DELAY      5000  // Time taken to hyperspace.
 | ||||
| #define HYPERSPACE_STARS_BLUR     2000  // Time stars blur.
 | ||||
| #define HYPERSPACE_STARS_LENGTH   1000  // Length the stars blur to at max.
 | ||||
| #define HYPERSPACE_FADEOUT        1000  // Time fadeout.
 | ||||
| #define HYPERSPACE_FUEL           100   // Amount of fuel taken.
 | ||||
| #define HYPERSPACE_ENGINE_DELAY   3000  /* Warm up the engines. */ | ||||
| #define HYPERSPACE_FLY_DELAY      5000  /* Time taken to hyperspace. */ | ||||
| #define HYPERSPACE_STARS_BLUR     2000  /* Time stars blur. */ | ||||
| #define HYPERSPACE_STARS_LENGTH   1000  /* Length the stars blur to at max. */ | ||||
| #define HYPERSPACE_FADEOUT        1000  /* Time fadeout. */ | ||||
| #define HYPERSPACE_FUEL           100   /* Amount of fuel taken. */ | ||||
| 
 | ||||
| // Aproximation for pilot size.
 | ||||
| /* Aproximation for pilot size. */ | ||||
| #define PILOT_SIZE_APROX          0.8 | ||||
| #define PILOT_DISABLED_ARMOUR     0.3   // Based on armour percentage.
 | ||||
| #define PILOT_DISABLED_ARMOUR     0.3   /* Based on armour percentage. */ | ||||
| 
 | ||||
| // Hooks.
 | ||||
| #define PILOT_HOOK_NONE           0     // No hook.
 | ||||
| #define PILOT_HOOK_DEATH          1     // Pilot died.
 | ||||
| /* Hooks. */ | ||||
| #define PILOT_HOOK_NONE           0     /* No hook. */ | ||||
| #define PILOT_HOOK_DEATH          1     /* Pilot died. */ | ||||
| 
 | ||||
| // Flags.
 | ||||
| /* Flags. */ | ||||
| #define pilot_isFlag(p,f)   (p->flags & (f)) | ||||
| #define pilot_setFlag(p,f)  (p->flags |= (f)) | ||||
| #define pilot_rmFlag(p,f)   (p->flags ^= (f)) | ||||
| // Creation.
 | ||||
| #define PILOT_PLAYER        (1<<0)  // Pilot is a player.
 | ||||
| #define PILOT_HASTURRET     (1<<20) // Pilot has turrets.
 | ||||
| #define PILOT_NO_OUTFITS    (1<<21) // Do not create the pilot with outfits.
 | ||||
| #define PILOT_EMPTY         (1<<22) // Do not add pilot to stack.
 | ||||
| // Dynamic.
 | ||||
| #define PILOT_HOSTILE       (1<<1)  // Pilot is hostile to the player.
 | ||||
| #define PILOT_COMBAT        (1<<2)  // Pilot is engaged in combat.
 | ||||
| #define PILOT_AFTERBURNER   (1<<3)  // Pilot has her afterburner activated.
 | ||||
| #define PILOT_HYP_PREP      (1<<5)  // Pilot is getting ready for hyperspace.
 | ||||
| #define PILOT_HYP_BEGIN     (1<<6)  // Pilot is starting engines.
 | ||||
| #define PILOT_HYPERSPACE    (1<<7)  // Pilot is in hyperspace.
 | ||||
| #define PILOT_BOARDED       (1<<8)  // Pilot has been boarded already!
 | ||||
| #define PILOT_DISABLED      (1<<9)  // Pilot is disabled.
 | ||||
| #define PILOT_DEAD          (1<<10) // Pilot is on it's death bed.
 | ||||
| #define PILOT_EXPLODED      (1<<11) // Pilot did final death explosion.
 | ||||
| #define PILOT_DELETE        (1<<15) // Pilot will get delete asap.
 | ||||
| /* Creation. */ | ||||
| #define PILOT_PLAYER        (1<<0)  /* Pilot is a player. */ | ||||
| #define PILOT_HASTURRET     (1<<20) /* Pilot has turrets. */ | ||||
| #define PILOT_NO_OUTFITS    (1<<21) /* Do not create the pilot with outfits. */ | ||||
| #define PILOT_EMPTY         (1<<22) /* Do not add pilot to stack. */ | ||||
| /* Dynamic. */ | ||||
| #define PILOT_HOSTILE       (1<<1)  /* Pilot is hostile to the player. */ | ||||
| #define PILOT_COMBAT        (1<<2)  /* Pilot is engaged in combat. */ | ||||
| #define PILOT_AFTERBURNER   (1<<3)  /* Pilot has her afterburner activated. */ | ||||
| #define PILOT_HYP_PREP      (1<<5)  /* Pilot is getting ready for hyperspace. */ | ||||
| #define PILOT_HYP_BEGIN     (1<<6)  /* Pilot is starting engines. */ | ||||
| #define PILOT_HYPERSPACE    (1<<7)  /* Pilot is in hyperspace. */ | ||||
| #define PILOT_BOARDED       (1<<8)  /* Pilot has been boarded already! */ | ||||
| #define PILOT_DISABLED      (1<<9)  /* Pilot is disabled. */ | ||||
| #define PILOT_DEAD          (1<<10) /* Pilot is on it's death bed. */ | ||||
| #define PILOT_EXPLODED      (1<<11) /* Pilot did final death explosion. */ | ||||
| #define PILOT_DELETE        (1<<15) /* Pilot will get delete asap. */ | ||||
| 
 | ||||
| // Just makes life simpler.
 | ||||
| /* Just makes life simpler. */ | ||||
| #define pilot_isPlayer(p)   ((p)->flags & PILOT_PLAYER) | ||||
| #define pilot_isDisabled(p) ((p)->flags & PILOT_DISABLED) | ||||
| 
 | ||||
| typedef struct PilotOutfit_ { | ||||
|   Outfit* outfit;     // Associated outfit.
 | ||||
|   int quantity;       // Number of outfits of this type that the pilot has.
 | ||||
|   unsigned int timer; // Used to store last used weapon time.
 | ||||
|   Outfit* outfit;     /* Associated outfit. */ | ||||
|   int quantity;       /* Number of outfits of this type that the pilot has. */ | ||||
|   unsigned int timer; /* Used to store last used weapon time. */ | ||||
| } PilotOutfit; | ||||
| 
 | ||||
| // Pilot commodity.
 | ||||
| /* Pilot commodity. */ | ||||
| typedef struct PilotCommodity_ { | ||||
|   Commodity* commodity; | ||||
|   int quantity; | ||||
|   unsigned int id;  // Special mission id for cargo.
 | ||||
|   unsigned int id;  /* Special mission id for cargo. */ | ||||
| } PilotCommodity; | ||||
| 
 | ||||
| // Primary pilot structure.
 | ||||
| /* Primary pilot structure. */ | ||||
| typedef struct Pilot_ { | ||||
|   unsigned int id;  // Pilots id.
 | ||||
|   char* name;       // Pilot's name (if unique).
 | ||||
|   char* title;      // Title - Usuall indicating special properties - TODO.
 | ||||
|   unsigned int id;  /* Pilots id. */ | ||||
|   char* name;       /* Pilot's name (if unique). */ | ||||
|   char* title;      /* Title - Usuall indicating special properties - TODO. */ | ||||
| 
 | ||||
|   int faction; | ||||
| 
 | ||||
|   // Object characteristics.
 | ||||
|   Ship* ship;     // Pilots ship.
 | ||||
|   Solid* solid;   // Associated solid (physics).
 | ||||
|   int tsx, tsy;   // Current sprite, calculated on update.
 | ||||
|   /* Object characteristics. */ | ||||
|   Ship* ship;     /* Pilots ship. */ | ||||
|   Solid* solid;   /* Associated solid (physics). */ | ||||
|   int tsx, tsy;   /* Current sprite, calculated on update. */ | ||||
| 
 | ||||
|   double thrust, turn, speed; | ||||
| 
 | ||||
|   // Current health.
 | ||||
|   /* Current health. */ | ||||
|   double armour, shield, energy, fuel; | ||||
|   double armour_max, shield_max, energy_max, fuel_max; | ||||
|   double armour_regen, shield_regen, energy_regen; | ||||
| 
 | ||||
|   void (*think)(struct Pilot_*); // AI thinking for the pilot.
 | ||||
|   void (*update)(struct Pilot_*, const double); // Update the pilot.
 | ||||
|   void (*render)(struct Pilot_*); // Rendering the pilot.
 | ||||
|   void (*think)(struct Pilot_*); /* AI thinking for the pilot. */ | ||||
|   void (*update)(struct Pilot_*, const double); /* Update the pilot. */ | ||||
|   void (*render)(struct Pilot_*); /* Rendering the pilot. */ | ||||
| 
 | ||||
|   // Outfit management.
 | ||||
|   /* Outfit management. */ | ||||
|   PilotOutfit* outfits; | ||||
|   int noutfits; | ||||
|   PilotOutfit* secondary;   // Secondary weapon.
 | ||||
|   PilotOutfit* ammo;        // Secondary ammo (if needed).
 | ||||
|   PilotOutfit* afterburner; // Ze afterburner.
 | ||||
|   PilotOutfit* secondary;   /* Secondary weapon. */ | ||||
|   PilotOutfit* ammo;        /* Secondary ammo (if needed). */ | ||||
|   PilotOutfit* afterburner; /* Ze afterburner. */ | ||||
| 
 | ||||
|   // Cargo.
 | ||||
|   int credits; // Moniez the pilot has.
 | ||||
|   PilotCommodity* commodities; // Commodity and quantity.
 | ||||
|   /* Cargo. */ | ||||
|   int credits; /* Moniez the pilot has. */ | ||||
|   PilotCommodity* commodities; /* Commodity and quantity. */ | ||||
|   int ncommodities; | ||||
|   int cargo_free; | ||||
| 
 | ||||
|   // Misc.
 | ||||
|   uint32_t flags; // Used for AI etc.
 | ||||
|   unsigned int ptimer;  // Generic timer for internal pilot use.
 | ||||
|   /* Misc. */ | ||||
|   uint32_t flags; /* Used for AI etc. */ | ||||
|   unsigned int ptimer;  /* Generic timer for internal pilot use. */ | ||||
| 
 | ||||
|   // Hook attached to the pilot.
 | ||||
|   /* Hook attached to the pilot. */ | ||||
|   int hook_type; | ||||
|   int hook; | ||||
| 
 | ||||
|   // AI.
 | ||||
|   AI_Profile* ai; // Ai personality profile.
 | ||||
|   unsigned int tcontrol; // Timer for control tick.
 | ||||
|   unsigned int timer[MAX_AI_TIMERS]; // Timers for AI.
 | ||||
|   Task* task; // Current action.
 | ||||
|   /* AI. */ | ||||
|   AI_Profile* ai; /* Ai personality profile. */ | ||||
|   unsigned int tcontrol; /* Timer for control tick. */ | ||||
|   unsigned int timer[MAX_AI_TIMERS]; /* Timers for AI. */ | ||||
|   Task* task; /* Current action. */ | ||||
| } Pilot; | ||||
| 
 | ||||
| // Fleets.
 | ||||
| /* Fleets. */ | ||||
| typedef struct FleetPilot_ { | ||||
|   Ship* ship; // Ship that the pilot is flying.
 | ||||
|   char* name; // For special 'unique' names.
 | ||||
|   int chance; // Chance of this pilot appearing in the fleet.
 | ||||
|   Ship* ship; /* Ship that the pilot is flying. */ | ||||
|   char* name; /* For special 'unique' names. */ | ||||
|   int chance; /* Chance of this pilot appearing in the fleet. */ | ||||
| } FleetPilot; | ||||
| 
 | ||||
| typedef struct Fleet_ { | ||||
|   char* name;   // Fleet name, used as an identifier.
 | ||||
|   int faction;  // Faction of the fleet.
 | ||||
|   char* name;   /* Fleet name, used as an identifier. */ | ||||
|   int faction;  /* Faction of the fleet. */ | ||||
| 
 | ||||
|   AI_Profile* ai; // A useable profile.
 | ||||
|   AI_Profile* ai; /* A useable profile. */ | ||||
| 
 | ||||
|   FleetPilot* pilots; // The pilots in the fleet.
 | ||||
|   int npilots; // Total number of pilots.
 | ||||
|   FleetPilot* pilots; /* The pilots in the fleet. */ | ||||
|   int npilots; /* Total number of pilots. */ | ||||
| } Fleet; | ||||
| 
 | ||||
| // Grabing pilot crap.
 | ||||
| extern Pilot* player; // The player.
 | ||||
| /* Grabing pilot crap. */ | ||||
| extern Pilot* player; /* The player. */ | ||||
| Pilot* pilot_get(unsigned int id); | ||||
| unsigned int pilot_getNext(const unsigned int id); | ||||
| unsigned int pilot_getNearest(const Pilot* p); | ||||
| unsigned int pilot_getHostile(void); // Only for the player.
 | ||||
| unsigned int pilot_getHostile(void); /* Only for the player. */ | ||||
| Fleet* fleet_get(const char* name); | ||||
| int pilot_getJumps(const Pilot* p); | ||||
| 
 | ||||
| // MISC.
 | ||||
| /* MISC. */ | ||||
| void pilot_shoot(Pilot* p, const unsigned int target, const int secondary); | ||||
| void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter, | ||||
|     const DamageType dtype, const double damage); | ||||
| @ -149,23 +149,23 @@ void pilot_setSecondary(Pilot* p, const char* secondary); | ||||
| void pilot_setAmmo(Pilot* p); | ||||
| void pilot_setAfterburner(Pilot* p); | ||||
| double pilot_face(Pilot* p, const float dir); | ||||
| // Outfits.
 | ||||
| int pilot_freeSpace(Pilot* p); // Pilot space.
 | ||||
| /* Outfits. */ | ||||
| int pilot_freeSpace(Pilot* p); /* Pilot space. */ | ||||
| int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity); | ||||
| int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity); | ||||
| char* pilot_getOutfits(Pilot* pilot); | ||||
| void pilot_calcStats(Pilot* pilot); | ||||
| // Normal cargo.
 | ||||
| int pilot_cagoUsed(Pilot* pilot);   // Get amount of cargo onboard.
 | ||||
| int pilot_cargoFree(Pilot* p);      // Cargo space.
 | ||||
| /* Normal cargo. */ | ||||
| int pilot_cagoUsed(Pilot* pilot);   /* Get amount of cargo onboard. */ | ||||
| int pilot_cargoFree(Pilot* p);      /* Cargo space. */ | ||||
| int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity); | ||||
| int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity); | ||||
| // Mission cargo - Not to be confused with normal cargo.
 | ||||
| /* Mission cargo - Not to be confused with normal cargo. */ | ||||
| unsigned int pilot_addMissionCargo(Pilot* pilot, Commodity* cargo, int quantity); | ||||
| int pilot_rmMissionCargo(Pilot* pilot, unsigned int cargo_id); | ||||
| 
 | ||||
| 
 | ||||
| // Creation.
 | ||||
| /* Creation. */ | ||||
| void pilot_init(Pilot* dest, Ship* ship, char* name, int faction, | ||||
|                 AI_Profile* ai, const double dir, const Vec2* pos, | ||||
|                 const Vec2* vel, const int flags); | ||||
| @ -179,16 +179,16 @@ Pilot* pilot_createEmpty(Ship* ship, char* name, | ||||
| 
 | ||||
| Pilot* pilot_copy(Pilot* src); | ||||
| 
 | ||||
| // Init/Cleanup.
 | ||||
| /* Init/Cleanup. */ | ||||
| void pilot_destroy(Pilot* p); | ||||
| void pilots_free(void); | ||||
| void pilots_clean(void); | ||||
| void pilots_cleanAll(void); | ||||
| void pilot_free(Pilot* p); | ||||
| int fleet_load(void); // TODO
 | ||||
| int fleet_load(void); /* TODO */ | ||||
| void fleet_free(void); | ||||
| 
 | ||||
| // Update.
 | ||||
| /* Update. */ | ||||
| void pilots_update(double dt); | ||||
| void pilots_render(void); | ||||
| 
 | ||||
|  | ||||
| @ -11,7 +11,7 @@ static void pf_divFractal(double* map, const double x, const double y, | ||||
|                           double rw, const double rh, double c1, | ||||
|                           double c2, double c3, double c4, double rug); | ||||
| 
 | ||||
| // Acutally generate the fractal and loads it up in an opengl texture.
 | ||||
| /* Acutally generate the fractal and loads it up in an opengl texture. */ | ||||
| glTexture* pf_genFractal(const int w, const int h, double rug) { | ||||
|   int i; | ||||
|   double* map; | ||||
| @ -25,7 +25,7 @@ glTexture* pf_genFractal(const int w, const int h, double rug) { | ||||
|   sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RGBMASK); | ||||
|   pix = sur->pixels; | ||||
| 
 | ||||
|   // Convert from mapping to actual colours.
 | ||||
|   /* Convert from mapping to actual colours. */ | ||||
|   SDL_LockSurface(sur); | ||||
|   for(i = 0; i < h*w; i++) { | ||||
|     c = map[i]; | ||||
| @ -41,7 +41,7 @@ glTexture* pf_genFractal(const int w, const int h, double rug) { | ||||
| } | ||||
| 
 | ||||
| static double* pf_genFractalMap(const int w, const int h, double rug) { | ||||
|   double* map; // We'll use it to map out the fractal before saving.
 | ||||
|   double* map; /* We'll use it to map out the fractal before saving. */ | ||||
|   double cx, cy; | ||||
| 
 | ||||
|   map = malloc(w*h * sizeof(double)); | ||||
| @ -50,11 +50,11 @@ static double* pf_genFractalMap(const int w, const int h, double rug) { | ||||
|     return NULL; | ||||
|   } | ||||
| 
 | ||||
|   // Set up initial values.
 | ||||
|   /* Set up initial values. */ | ||||
|   cx = (double)w/2; | ||||
|   cy = (double)h/2; | ||||
| 
 | ||||
|   // Start by doing the four squares.
 | ||||
|   /* Start by doing the four squares. */ | ||||
|   pf_divFractal(map, 0,   0,  cx, cy, w, h, 0., 0., 1., 0., rug); | ||||
|   pf_divFractal(map, cx,  0,  cx, cy, w, h, 0., 0., 0., 1., rug); | ||||
|   pf_divFractal(map, cx,  cy, cx, cy, w, h, 1., 0., 0., 0., rug); | ||||
| @ -68,35 +68,35 @@ static void pf_divFractal(double* map, const double x, const double y, | ||||
|                           const double rh, double c1, double c2, double c3, | ||||
|                           double c4, double rug) { | ||||
| 
 | ||||
|   double nw, nh; // New dimensions.
 | ||||
|   double m, e1, e2, e3, e4; // Middle and edges.
 | ||||
|   double nw, nh; /* New dimensions. */ | ||||
|   double m, e1, e2, e3, e4; /* Middle and edges. */ | ||||
| 
 | ||||
|   // Still need to subdivide.
 | ||||
|   /* Still need to subdivide. */ | ||||
|   if((w>1.) || (h>1.)) { | ||||
|     // Calculate new dimensions.
 | ||||
|     /* Calculate new dimensions. */ | ||||
|     nw = w/2.; | ||||
|     nh = h/2.; | ||||
| 
 | ||||
|     // Edges.
 | ||||
|     /* Edges. */ | ||||
|     m   = (c1 + c2 + c3 + c4)/4.; | ||||
|     e1  = (c1 + c2)/2.; | ||||
|     e2  = (c2 + c3)/2.; | ||||
|     e3  = (c3 + c4)/2.; | ||||
|     e4  = (c4 + c1)/2.; | ||||
| 
 | ||||
|     // Now change the middle colour.
 | ||||
|     //DEBUG("%f + %f", m, rug*(RNGF()-0.5) * ((nw+nh)/(rw+rh)*1000));
 | ||||
|     /* Now change the middle colour. */ | ||||
|     /*DEBUG("%f + %f", m, rug*(RNGF()-0.5) * ((nw+nh)/(rw+rh)*1000)); */ | ||||
|     m += rug*(RNGF()-0.5)*((nw+nh)/(rw+rh)*3.); | ||||
|     if(m < 0.) m = 0.; | ||||
|     else if(m>1.) m = 1.; | ||||
| 
 | ||||
|     // Recursivation.
 | ||||
|     /* Recursivation. */ | ||||
|     pf_divFractal(map, x,    y,     nw, nh, rw, rh, c1, e1, m,  e4, rug); | ||||
|     pf_divFractal(map, x+nw, y,     nw, nh, rw, rh, e1, c2, e2, m,  rug); | ||||
|     pf_divFractal(map, x+nw, y+nh,  nw, nh, rw, rh, m,  e2, c3, e3, rug); | ||||
|     pf_divFractal(map, x,    y+nh,  nw, nh, rw, rh, e4, m,  e3, c4, rug); | ||||
|   } else | ||||
|     // Actually write the pixel.
 | ||||
|     /* Actually write the pixel. */ | ||||
|     map[(int)y*(int)rw + (int)x] = (c1 + c2 + c3 + c4)/4.; | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										532
									
								
								src/player.c
									
									
									
									
									
								
							
							
						
						
									
										532
									
								
								src/player.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										46
									
								
								src/player.h
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								src/player.h
									
									
									
									
									
								
							| @ -1,58 +1,58 @@ | ||||
| #pragma once | ||||
| #include "pilot.h" | ||||
| 
 | ||||
| // Flag definitions.
 | ||||
| #define PLAYER_TURN_LEFT    (1<<0)    // Player is turning left.
 | ||||
| #define PLAYER_TURN_RIGHT   (1<<1)    // Player is turning right.
 | ||||
| #define PLAYER_REVERSE      (1<<2)    // Player is facint opposite vel.
 | ||||
| #define PLAYER_AFTERBURNER  (1<<3)    // Player is burning it up.
 | ||||
| #define PLAYER_DESTROYED    (1<<9)    // Player goes BOOM!
 | ||||
| #define PLAYER_FACE         (1<<10)   // Player is facing target.
 | ||||
| #define PLAYER_PRIMARY      (1<<11)   // Player is shooting primary weapon.
 | ||||
| #define PLAYER_SECONDARY    (1<<12)   // Player is shooting secondary weapon.
 | ||||
| #define PLAYER_LANDACK      (1<<13)   // Player has permission to land.
 | ||||
| #define PLAYER_CREATING     (1<<14)   // Player is being created.
 | ||||
| /* Flag definitions. */ | ||||
| #define PLAYER_TURN_LEFT    (1<<0)    /* Player is turning left. */ | ||||
| #define PLAYER_TURN_RIGHT   (1<<1)    /* Player is turning right. */ | ||||
| #define PLAYER_REVERSE      (1<<2)    /* Player is facint opposite vel. */ | ||||
| #define PLAYER_AFTERBURNER  (1<<3)    /* Player is burning it up. */ | ||||
| #define PLAYER_DESTROYED    (1<<9)    /* Player goes BOOM! */ | ||||
| #define PLAYER_FACE         (1<<10)   /* Player is facing target. */ | ||||
| #define PLAYER_PRIMARY      (1<<11)   /* Player is shooting primary weapon. */ | ||||
| #define PLAYER_SECONDARY    (1<<12)   /* Player is shooting secondary weapon. */ | ||||
| #define PLAYER_LANDACK      (1<<13)   /* Player has permission to land. */ | ||||
| #define PLAYER_CREATING     (1<<14)   /* Player is being created. */ | ||||
| 
 | ||||
| // Flag functions.
 | ||||
| /* Flag functions. */ | ||||
| #define player_isFlag(f)  (player_flags  & f) | ||||
| #define player_setFlag(f) if(!player_isFlag(f)) (player_flags |= f) | ||||
| #define player_rmFlag(f)  if(player_isFlag(f)) (player_flags ^= f) | ||||
| 
 | ||||
| // The player.
 | ||||
| /* The player. */ | ||||
| extern Pilot* pilot; | ||||
| extern char* player_name; | ||||
| extern unsigned int player_flags; | ||||
| extern int combat_crating; | ||||
| 
 | ||||
| // Enums.
 | ||||
| /* Enums. */ | ||||
| 
 | ||||
| // For render functions.
 | ||||
| /* For render functions. */ | ||||
| typedef enum RadarShape_ { RADAR_RECT, RADAR_CIRCLE } RadarShape; | ||||
| 
 | ||||
| // Creation/Cleanup.
 | ||||
| /* Creation/Cleanup. */ | ||||
| void player_new(void); | ||||
| void player_newShip(Ship* ship, double px, double py, | ||||
|                     double vx, double vy, double dir); | ||||
| void player_cleanup(void); | ||||
| int gui_load(const char* name); | ||||
| 
 | ||||
| // Render.
 | ||||
| /* Render. */ | ||||
| int gui_init(void); | ||||
| void gui_free(void); | ||||
| void player_render(void); | ||||
| void player_renderBG(void); // Render BG layer.
 | ||||
| void player_renderBG(void); /* Render BG layer. */ | ||||
| 
 | ||||
| // Misc.
 | ||||
| /* Misc. */ | ||||
| void player_message(const char* fmt, ...); | ||||
| void player_clear(void); | ||||
| void player_warp(const double x, const double y); | ||||
| const char* player_rating(void); | ||||
| // Cargo.
 | ||||
| /* Cargo. */ | ||||
| int player_outfitOwned(const char* outfitname); | ||||
| int player_cargoOwned(const char* commodityname); | ||||
| void player_rmMissionCargo(unsigned int cargo_id); | ||||
| 
 | ||||
| // Pilot ships.
 | ||||
| /* Pilot ships. */ | ||||
| char** player_ships(int* nships); | ||||
| int    player_nships(void); | ||||
| Pilot* player_getShip(char* shipname); | ||||
| @ -60,11 +60,11 @@ char*  player_getLoc(char* shipname); | ||||
| void   player_setLoc(char* shipname, char* loc); | ||||
| void   player_swapShip(char* shipname); | ||||
| 
 | ||||
| // Player missions.
 | ||||
| /* Player missions. */ | ||||
| void player_missionFinished(int id); | ||||
| int player_missionAlreadyDone(int id); | ||||
| 
 | ||||
| // Keybind actions.
 | ||||
| /* Keybind actions. */ | ||||
| void player_setRadarRel(int mod); | ||||
| void player_secondaryNext(void); | ||||
| void player_targetPlanet(void); | ||||
|  | ||||
							
								
								
									
										28
									
								
								src/rng.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								src/rng.c
									
									
									
									
									
								
							| @ -11,13 +11,13 @@ | ||||
| #include "rng.h" | ||||
| #include "log.h" | ||||
| 
 | ||||
| // Mersenne twister state.
 | ||||
| /* Mersenne twister state. */ | ||||
| static uint32_t MT[624]; | ||||
| static uint32_t mt_y; | ||||
| static int mt_pos = 0;  // Current number.
 | ||||
| static int mt_pos = 0;  /* Current number. */ | ||||
| 
 | ||||
| static uint32_t rng_timeEntropy(void); | ||||
| // Mersenne twister.
 | ||||
| /* Mersenne twister. */ | ||||
| static void mt_initArray(uint32_t seed); | ||||
| static void mt_genArray(void); | ||||
| static uint32_t mt_getInt(void); | ||||
| @ -26,10 +26,10 @@ void rng_init(void) { | ||||
|   uint32_t i; | ||||
|   int need_init; | ||||
| 
 | ||||
|   need_init = 1; // Initialize by default.
 | ||||
|   need_init = 1; /* Initialize by default. */ | ||||
| #ifdef LINUX | ||||
|   int fd; | ||||
|   fd = open("/dev/urandom", O_RDONLY); // /dev/urandom is better then time seed.
 | ||||
|   fd = open("/dev/urandom", O_RDONLY); /* /dev/urandom is better then time seed. */ | ||||
|   if(fd != -1) { | ||||
|     i = sizeof(uint32_t)*624; | ||||
|     if(read(fd, &MT, i) == (ssize_t)i) | ||||
| @ -45,11 +45,11 @@ void rng_init(void) { | ||||
|   if(need_init) | ||||
|     mt_initArray(i); | ||||
|   for(i = 0; i < 10; i++) | ||||
|     // Generate numbers to get away from poor initial values.
 | ||||
|     /* Generate numbers to get away from poor initial values. */ | ||||
|     mt_genArray(); | ||||
| } | ||||
| 
 | ||||
| // Use the time as source of entropy.
 | ||||
| /* Use the time as source of entropy. */ | ||||
| static uint32_t rng_timeEntropy(void) { | ||||
|   int i; | ||||
|    | ||||
| @ -65,7 +65,7 @@ static uint32_t rng_timeEntropy(void) { | ||||
|   return i; | ||||
| } | ||||
| 
 | ||||
| // Generates the initial mersenne twister based on seed.
 | ||||
| /* Generates the initial mersenne twister based on seed. */ | ||||
| static void mt_initArray(uint32_t seed) { | ||||
|   int i; | ||||
|   MT[0] = seed; | ||||
| @ -74,22 +74,22 @@ static void mt_initArray(uint32_t seed) { | ||||
|   mt_pos = 0; | ||||
| } | ||||
| 
 | ||||
| // Generate an array of numbers.
 | ||||
| /* Generate an array of numbers. */ | ||||
| static void mt_genArray(void) { | ||||
|   int i; | ||||
|   for(i = 0; i < 624; i++) { | ||||
|     mt_y = (MT[i] & 0x80000000) + ((MT[i] % 624) & 0x7FFFFFFF); | ||||
|     if(mt_y % 2) | ||||
|       // Odd.
 | ||||
|       /* Odd. */ | ||||
|       MT[i] = (MT[(i+397) % 624] ^ (mt_y >> 1)) ^ 2567483615; | ||||
|     else | ||||
|       // Even.
 | ||||
|       /* Even. */ | ||||
|       MT[i] = MT[(i+397) % 624] ^ (mt_y >> 1); | ||||
|   } | ||||
|   mt_pos = 0; | ||||
| } | ||||
| 
 | ||||
| // Get the next int.
 | ||||
| /* Get the next int. */ | ||||
| static uint32_t mt_getInt(void) { | ||||
|   if(mt_pos >= 624) mt_genArray(); | ||||
| 
 | ||||
| @ -102,12 +102,12 @@ static uint32_t mt_getInt(void) { | ||||
|   return mt_y; | ||||
| } | ||||
| 
 | ||||
| // Return a random int.
 | ||||
| /* Return a random int. */ | ||||
| unsigned int randint(void) { | ||||
|   return mt_getInt(); | ||||
| } | ||||
| 
 | ||||
| // Return a random double.
 | ||||
| /* Return a random double. */ | ||||
| static double m_div = (double)(0xFFFFFFFF) + 1.; | ||||
| double randfp(void) { | ||||
|   double m = (double)mt_getInt(); | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #define RNG(L,H)  ((int)L + (int)((double)(H-L+1) * randfp())) // L <= RNG <= H
 | ||||
| #define RNG(L,H)  ((int)L + (int)((double)(H-L+1) * randfp())) /* L <= RNG <= H */ | ||||
| #define RNGF()  (randfp()) | ||||
| 
 | ||||
| void rng_init(void); | ||||
|  | ||||
							
								
								
									
										50
									
								
								src/save.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								src/save.c
									
									
									
									
									
								
							| @ -1,5 +1,5 @@ | ||||
| #ifdef _POSIX_SOURCE | ||||
| #include <unistd.h> // Unlink. | ||||
| #include <unistd.h> /* Unlink. */ | ||||
| #endif | ||||
| 
 | ||||
| #include "lephisto.h" | ||||
| @ -17,28 +17,28 @@ | ||||
| #define BUTTON_WIDTH  50 | ||||
| #define BUTTON_HEIGHT 30 | ||||
| 
 | ||||
| // Externs.
 | ||||
| extern int  player_save(xmlTextWriterPtr writer);         // A lot of stuff.
 | ||||
| /* Externs. */ | ||||
| extern int  player_save(xmlTextWriterPtr writer);         /* A lot of stuff. */ | ||||
| extern int  player_load(xmlNodePtr parent); | ||||
| extern int  missions_saveActive(xmlTextWriterPtr writer); // Active missions.
 | ||||
| extern int  missions_saveActive(xmlTextWriterPtr writer); /* Active missions. */ | ||||
| extern int  missions_loadActive(xmlNodePtr parent); | ||||
| extern int  var_save(xmlTextWriterPtr writer);            // misn var.
 | ||||
| extern int  var_save(xmlTextWriterPtr writer);            /* misn var. */ | ||||
| extern int  var_load(xmlNodePtr parent); | ||||
| extern int  pfaction_save(xmlTextWriterPtr writer);       // Faction data.
 | ||||
| extern int  pfaction_save(xmlTextWriterPtr writer);       /* Faction data. */ | ||||
| extern int  pfaction_load(xmlNodePtr parent); | ||||
| extern int  hook_save(xmlTextWriterPtr writer);           // Hooks.
 | ||||
| extern int  hook_save(xmlTextWriterPtr writer);           /* Hooks. */ | ||||
| extern int  hook_load(xmlNodePtr parent); | ||||
| extern void menu_main_close(void); | ||||
| // Static.
 | ||||
| /* Static. */ | ||||
| static int  save_data(xmlTextWriterPtr writer); | ||||
| static void load_menu_close(char* str); | ||||
| static void load_menu_load(char* str); | ||||
| static void load_menu_delete(char* str); | ||||
| static int  load_game(char* file); | ||||
| 
 | ||||
| // Save all the game data.
 | ||||
| /* Save all the game data. */ | ||||
| static int save_data(xmlTextWriterPtr writer) { | ||||
|   // The data itself.
 | ||||
|   /* The data itself. */ | ||||
|   if(player_save(writer) < 0)           return -1; | ||||
|   if(missions_saveActive(writer) < 0)   return -1; | ||||
|   if(var_save(writer) < 0)              return -1; | ||||
| @ -47,7 +47,7 @@ static int save_data(xmlTextWriterPtr writer) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Save the current game.
 | ||||
| /* Save the current game. */ | ||||
| int save_all(void) { | ||||
|   char file[PATH_MAX]; | ||||
|   xmlDocPtr doc; | ||||
| @ -62,11 +62,11 @@ int save_all(void) { | ||||
|   xmlw_start(writer); | ||||
|   xmlw_startElem(writer, "lephisto_save"); | ||||
| 
 | ||||
|   // Save the version or something..
 | ||||
|   /* Save the version or something.. */ | ||||
|   xmlw_startElem(writer, "version"); | ||||
|   xmlw_elem(writer, "lephisto", "%d.%d.%d", VMAJOR, VMINOR, VREV); | ||||
|   xmlw_elem(writer, "data", dataname); | ||||
|   xmlw_endElem(writer); // Version.
 | ||||
|   xmlw_endElem(writer); /* Version. */ | ||||
| 
 | ||||
|   if(save_data(writer) < 0) { | ||||
|     ERR("Trying to save game data"); | ||||
| @ -75,7 +75,7 @@ int save_all(void) { | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   xmlw_endElem(writer); // lephisto_save.
 | ||||
|   xmlw_endElem(writer); /* lephisto_save. */ | ||||
|   xmlw_done(writer); | ||||
| 
 | ||||
|   if(lfile_dirMakeExist("saves") < 0) { | ||||
| @ -93,32 +93,32 @@ int save_all(void) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Open the load game menu.
 | ||||
| /* Open the load game menu. */ | ||||
| void load_game_menu(void) { | ||||
|   unsigned int wid; | ||||
|   char** files; | ||||
|   int lfiles, i, len; | ||||
| 
 | ||||
|   // Window.
 | ||||
|   /* Window. */ | ||||
|   wid = window_create("Load Game", -1, -1, LOAD_WIDTH, LOAD_HEIGHT); | ||||
| 
 | ||||
|   // Load the saves.
 | ||||
|   /* Load the saves. */ | ||||
|   files = lfile_readDir(&lfiles, "saves"); | ||||
|   for(i = 0; i < lfiles; i++) { | ||||
|     len = strlen(files[i]); | ||||
| 
 | ||||
|     // No save extension.
 | ||||
|     /* No save extension. */ | ||||
|     if((len < 6) || strcmp(&files[i][len-3], ".ls")) { | ||||
|       free(files[i]); | ||||
|       memmove(&files[i], &files[i+1], sizeof(char*) * (lfiles-i-1)); | ||||
|       lfiles--; | ||||
|       i--; | ||||
|     } | ||||
|     else // Remove the extension.
 | ||||
|     else /* Remove the extension. */ | ||||
|       files[i][len-3] = '\0'; | ||||
|   } | ||||
| 
 | ||||
|   // Again.. What if there is no files?
 | ||||
|   /* Again.. What if there is no files? */ | ||||
|   if(files == NULL) { | ||||
|     files = malloc(sizeof(char*)); | ||||
|     files[0] = strdup("None"); | ||||
| @ -129,7 +129,7 @@ void load_game_menu(void) { | ||||
|       LOAD_WIDTH-BUTTON_WIDTH-50, LOAD_HEIGHT-90, | ||||
|       "lstSaves", files, lfiles, 0, NULL); | ||||
| 
 | ||||
|   // Buttons.
 | ||||
|   /* Buttons. */ | ||||
|   window_addButton(wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, | ||||
|       "btnBack", "Back", load_menu_close); | ||||
| 
 | ||||
| @ -139,7 +139,7 @@ void load_game_menu(void) { | ||||
|   window_addButton(wid, -20, 20+2*(10+BUTTON_HEIGHT), BUTTON_WIDTH, BUTTON_HEIGHT, | ||||
|       "btnDelete", "Del", load_menu_delete); | ||||
| 
 | ||||
|   // Default action.
 | ||||
|   /* Default action. */ | ||||
|   window_setFptr(wid, load_menu_load); | ||||
| } | ||||
| 
 | ||||
| @ -185,18 +185,18 @@ static void load_menu_delete(char* str) { | ||||
|   snprintf(path, PATH_MAX, "%ssaves/%s.ls", lfile_basePath(), save); | ||||
|   unlink(path); | ||||
| 
 | ||||
|   // Need to reload the menu.
 | ||||
|   /* Need to reload the menu. */ | ||||
|   load_menu_close(NULL); | ||||
|   load_game_menu(); | ||||
| } | ||||
| 
 | ||||
| // Load a new game.
 | ||||
| /* Load a new game. */ | ||||
| static int load_game(char* file) { | ||||
|   xmlNodePtr node; | ||||
|   xmlDocPtr doc; | ||||
| 
 | ||||
|   doc = xmlParseFile(file); | ||||
|   node = doc->xmlChildrenNode; // Base node.
 | ||||
|   node = doc->xmlChildrenNode; /* Base node. */ | ||||
|   if(node == NULL) { | ||||
|     WARN("Savegame '%s' invalid!", file); | ||||
|     return -1; | ||||
|  | ||||
							
								
								
									
										30
									
								
								src/ship.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								src/ship.c
									
									
									
									
									
								
							| @ -7,7 +7,7 @@ | ||||
| #include "toolkit.h" | ||||
| #include "ship.h" | ||||
| 
 | ||||
| #define XML_ID    "Ships" // XML section identifier.
 | ||||
| #define XML_ID    "Ships" /* XML section identifier. */ | ||||
| #define XML_SHIP  "ship" | ||||
| 
 | ||||
| #define SHIP_DATA   "../dat/ship.xml" | ||||
| @ -27,20 +27,20 @@ static int ships = 0; | ||||
| static Ship* ship_parse(xmlNodePtr parent); | ||||
| static void ship_view_close(char* btn); | ||||
| 
 | ||||
| // Get a ship based on it's name.
 | ||||
| /* Get a ship based on it's name. */ | ||||
| Ship* ship_get(const char* name) { | ||||
|   Ship* tmp = ship_stack; | ||||
|   int i; | ||||
|   for(i = 0; i < ships; i++) | ||||
|     if(strcmp((tmp+i)->name, name)==0) break; | ||||
| 
 | ||||
|   if(i == ships) // Ship doesn't exist, game will probably crash now.
 | ||||
|   if(i == ships) /* Ship doesn't exist, game will probably crash now. */ | ||||
|     WARN("Ship %s does not exist", name); | ||||
| 
 | ||||
|   return tmp+i; | ||||
| } | ||||
| 
 | ||||
| // Get the ship's classname.
 | ||||
| /* Get the ship's classname. */ | ||||
| static char* ship_classes[] = { | ||||
|   "NULL", | ||||
|   "Civialian Light", "Civilian Medium", "Civilian Heavy" | ||||
| @ -50,7 +50,7 @@ static char* ship_classes[] = { | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| // Return all the ships in text form.
 | ||||
| /* Return all the ships in text form. */ | ||||
| char** ship_getTech(int* n, const int* tech, const int techmax) { | ||||
|   int i, j; | ||||
|   char** shipnames; | ||||
| @ -91,13 +91,13 @@ static Ship* ship_parse(xmlNodePtr parent) { | ||||
|   node = parent->xmlChildrenNode; | ||||
| 
 | ||||
|   do { | ||||
|     // Load all the data.
 | ||||
|     /* Load all the data. */ | ||||
|     if(xml_isNode(node,"GFX")) { | ||||
|       snprintf(str, strlen(xml_get(node)) + | ||||
|                sizeof(SHIP_GFX) + sizeof(SHIP_EXT), | ||||
|                SHIP_GFX"%s"SHIP_EXT, xml_get(node)); | ||||
|       tmp->gfx_space = gl_newSprite(str, 6, 6); | ||||
|       // Target.
 | ||||
|       /* Target. */ | ||||
|       snprintf(str, strlen(xml_get(node)) + | ||||
|                sizeof(SHIP_GFX)+sizeof(SHIP_TARGET)+sizeof(SHIP_EXT), | ||||
|                SHIP_GFX"%s"SHIP_TARGET SHIP_EXT, xml_get(node)); | ||||
| @ -168,7 +168,7 @@ static Ship* ship_parse(xmlNodePtr parent) { | ||||
|     } | ||||
|   } while(xml_nextNode(node)); | ||||
| 
 | ||||
|   tmp->thrust *= tmp->mass; // Helps keep number sane.
 | ||||
|   tmp->thrust *= tmp->mass; /* Helps keep number sane. */ | ||||
| 
 | ||||
| #define MELEMENT(o,s) if(o) WARN("Ship '%s' missing '"s"' element", tmp->name) | ||||
|   MELEMENT(tmp->name == NULL, "name"); | ||||
| @ -207,13 +207,13 @@ int ships_load(void) { | ||||
| 
 | ||||
|   Ship* tmp = NULL; | ||||
| 
 | ||||
|   node = doc->xmlChildrenNode; // Ships node.
 | ||||
|   node = doc->xmlChildrenNode; /* Ships node. */ | ||||
|   if(strcmp((char*)node->name, XML_ID)) { | ||||
|     ERR("Malformed "SHIP_DATA" file: missing root element '"XML_ID"'"); | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   node = node->xmlChildrenNode; // First ship node.
 | ||||
|   node = node->xmlChildrenNode; /* First ship node. */ | ||||
|   if(node == NULL) { | ||||
|     ERR("Malformed "SHIP_DATA" file: Does not contain elements"); | ||||
|     return -1; | ||||
| @ -241,14 +241,14 @@ void ships_free(void) { | ||||
|   ShipOutfit* so, *sot; | ||||
|   int i; | ||||
|   for(i = 0; i < ships; i++) { | ||||
|     // Free stored strings.
 | ||||
|     /* Free stored strings. */ | ||||
|     if((ship_stack+i)->name) free(ship_stack[i].name); | ||||
|     if((ship_stack+i)->description) free(ship_stack[i].description); | ||||
|     if((ship_stack+i)->gui) free(ship_stack[i].gui); | ||||
|     if((ship_stack+i)->fabricator) free(ship_stack[i].fabricator); | ||||
| 
 | ||||
|     so = (ship_stack+i)->outfit; | ||||
|     while(so) { // free the ship outfit.
 | ||||
|     while(so) { /* free the ship outfit. */ | ||||
|       sot = so; | ||||
|       so = so->next; | ||||
|       free(sot); | ||||
| @ -260,7 +260,7 @@ void ships_free(void) { | ||||
|   ship_stack = NULL; | ||||
| } | ||||
| 
 | ||||
| // Used to visualize the ships status.
 | ||||
| /* Used to visualize the ships status. */ | ||||
| void ship_view(char* shipname) { | ||||
|   Ship* s; | ||||
|   char buf[1024]; | ||||
| @ -317,7 +317,7 @@ void ship_view(char* shipname) { | ||||
|   window_addText(wid, 120, -40, VIEW_WIDTH-140, h, | ||||
|                  0, "txtProperties", &gl_smallFont, &cBlack, buf); | ||||
| 
 | ||||
|   // Close the button.
 | ||||
|   /* Close the button. */ | ||||
|   snprintf(buf, 37, "close%s", shipname); | ||||
|   window_addButton(wid, -20, 20, | ||||
|                    BUTTON_WIDTH, BUTTON_HEIGHT, | ||||
| @ -325,6 +325,6 @@ void ship_view(char* shipname) { | ||||
| } | ||||
| 
 | ||||
| static void ship_view_close(char* btn) { | ||||
|   window_destroy(window_get(btn+5)); // "closefoo -> Foo"
 | ||||
|   window_destroy(window_get(btn+5)); /* "closefoo -> Foo" */ | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										46
									
								
								src/ship.h
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								src/ship.h
									
									
									
									
									
								
							| @ -3,7 +3,7 @@ | ||||
| #include "outfit.h" | ||||
| #include "sound.h" | ||||
| 
 | ||||
| // Target gfx dimensions.
 | ||||
| /* Target gfx dimensions. */ | ||||
| #define SHIP_TARGET_W 128 | ||||
| #define SHIP_TARGET_H 96 | ||||
| 
 | ||||
| @ -23,63 +23,63 @@ typedef enum ShipClass_ { | ||||
|   SHIP_CLASS_HYB_HEAVY  = 12 | ||||
| } ShipClass; | ||||
| 
 | ||||
| // Small wrapper for the outfits.
 | ||||
| /* Small wrapper for the outfits. */ | ||||
| typedef struct ShipOutfit_ { | ||||
|   struct ShipOutfit_* next; // Linked list.
 | ||||
|   Outfit* data; // Data itself.
 | ||||
|   struct ShipOutfit_* next; /* Linked list. */ | ||||
|   Outfit* data; /* Data itself. */ | ||||
|   int quantity; | ||||
| } ShipOutfit; | ||||
| 
 | ||||
| 
 | ||||
| // Ship structure.
 | ||||
| /* Ship structure. */ | ||||
| typedef struct Ship_ { | ||||
|   char* name; // Ship name.
 | ||||
|   ShipClass class; // Ship class.
 | ||||
|   char* name; /* Ship name. */ | ||||
|   ShipClass class; /* Ship class. */ | ||||
| 
 | ||||
|   // Store stuff.
 | ||||
|   int price;      // Price!
 | ||||
|   /* Store stuff. */ | ||||
|   int price;      /* Price! */ | ||||
|   int tech; | ||||
|   char* fabricator;  // Manufacturer.
 | ||||
|   char* description; // Sales pitch.
 | ||||
|   char* fabricator;  /* Manufacturer. */ | ||||
|   char* description; /* Sales pitch. */ | ||||
| 
 | ||||
|   // Movement.
 | ||||
|   /* Movement. */ | ||||
|   double thrust, turn, speed; | ||||
| 
 | ||||
|   // Graphics.
 | ||||
|   /* Graphics. */ | ||||
|   glTexture* gfx_space, *gfx_target; | ||||
| 
 | ||||
|   // GUI interface.
 | ||||
|   /* GUI interface. */ | ||||
|   char* gui; | ||||
| 
 | ||||
|   // Sound.
 | ||||
|   /* Sound. */ | ||||
|   ALuint sound; | ||||
| 
 | ||||
|   // Characteristics.
 | ||||
|   /* Characteristics. */ | ||||
|   int crew; | ||||
|   int mass; | ||||
|   int fuel; // How many jumps by default.
 | ||||
|   int fuel; /* How many jumps by default. */ | ||||
| 
 | ||||
|   // Health.
 | ||||
|   /* Health. */ | ||||
|   double armour, armour_regen; | ||||
|   double shield, shield_regen; | ||||
|   double energy, energy_regen; | ||||
| 
 | ||||
|   // Capacity.
 | ||||
|   /* Capacity. */ | ||||
|   int cap_cargo, cap_weapon; | ||||
| 
 | ||||
|   // Outfits
 | ||||
|   /* Outfits */ | ||||
|   ShipOutfit* outfit; | ||||
| } Ship; | ||||
| 
 | ||||
| // Get.
 | ||||
| /* Get. */ | ||||
| Ship* ship_get(const char* name); | ||||
| char** ship_getTech(int* n, const int* tech, const int techmax); | ||||
| char* ship_class(Ship* p); | ||||
| 
 | ||||
| // Load/quit.
 | ||||
| /* Load/quit. */ | ||||
| int ships_load(void); | ||||
| void ships_free(void); | ||||
| 
 | ||||
| // Toolkit.
 | ||||
| /* Toolkit. */ | ||||
| void ship_view(char* shipname); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										308
									
								
								src/sound.c
									
									
									
									
									
								
							
							
						
						
									
										308
									
								
								src/sound.c
									
									
									
									
									
								
							| @ -10,41 +10,41 @@ | ||||
| #include "music.h" | ||||
| #include "sound.h" | ||||
| 
 | ||||
| // ==============================================
 | ||||
| // sound.c controls the routines for using a
 | ||||
| // virtual voice wrapper system around the openal
 | ||||
| // library to get 3D sound.
 | ||||
| //
 | ||||
| // We only use position sound and no doppler effect
 | ||||
| // right now.
 | ||||
| // ==============================================
 | ||||
| /* ============================================== */ | ||||
| /* sound.c controls the routines for using a */ | ||||
| /* virtual voice wrapper system around the openal */ | ||||
| /* library to get 3D sound. */ | ||||
| /* */ | ||||
| /* We only use position sound and no doppler effect */ | ||||
| /* right now. */ | ||||
| /* ============================================== */ | ||||
| 
 | ||||
| // ==============================================
 | ||||
| // Sound Overview:
 | ||||
| // ---------------
 | ||||
| //
 | ||||
| // We use a priority virtual voice system with
 | ||||
| // pre-allocated buffers.
 | ||||
| //
 | ||||
| // Nameing:
 | ||||
| //    -- buffer - Sound sample.
 | ||||
| //    -- source - openal object that plays sound.
 | ||||
| //    -- voice  - Virtual object that wants to play sound.
 | ||||
| //
 | ||||
| // First we allocate all the buffers based on what
 | ||||
| // we find inside the datafile.
 | ||||
| // Then we allocate all the possible sources (giving
 | ||||
| // the music system what it needs).
 | ||||
| // Now we allow the user to dynamically create
 | ||||
| // voices, these voices will always try to grab
 | ||||
| // a source from the source pool. If they can't,
 | ||||
| // they will pretend to play the buffer.
 | ||||
| // Every so often we'll check to see if the important
 | ||||
| // voices are being played and take away the sources
 | ||||
| // from the lesser ones.
 | ||||
| // ==============================================
 | ||||
| /* ============================================== */ | ||||
| /* Sound Overview: */ | ||||
| /* --------------- */ | ||||
| /* */ | ||||
| /* We use a priority virtual voice system with */ | ||||
| /* pre-allocated buffers. */ | ||||
| /* */ | ||||
| /* Nameing: */ | ||||
| /*    -- buffer - Sound sample. */ | ||||
| /*    -- source - openal object that plays sound. */ | ||||
| /*    -- voice  - Virtual object that wants to play sound. */ | ||||
| /* */ | ||||
| /* First we allocate all the buffers based on what */ | ||||
| /* we find inside the datafile. */ | ||||
| /* Then we allocate all the possible sources (giving */ | ||||
| /* the music system what it needs). */ | ||||
| /* Now we allow the user to dynamically create */ | ||||
| /* voices, these voices will always try to grab */ | ||||
| /* a source from the source pool. If they can't, */ | ||||
| /* they will pretend to play the buffer. */ | ||||
| /* Every so often we'll check to see if the important */ | ||||
| /* voices are being played and take away the sources */ | ||||
| /* from the lesser ones. */ | ||||
| /* ============================================== */ | ||||
| 
 | ||||
| // Sound parameters - TODO: make it variable per source.
 | ||||
| /* Sound parameters - TODO: make it variable per source. */ | ||||
| #define SOUND_ROLLOFF_FACTOR  1. | ||||
| #define SOUND_REFERENCE_DIST  500. | ||||
| #define SOUND_MAX_DIST        1000. | ||||
| @ -56,57 +56,57 @@ | ||||
| #define soundLock()   SDL_mutexP(sound_lock) | ||||
| #define soundUnlock() SDL_mutexV(sound_lock) | ||||
| 
 | ||||
| // Give the buffers a name.
 | ||||
| /* Give the buffers a name. */ | ||||
| typedef struct alSound_ { | ||||
|   char* name;   // Buffers name.
 | ||||
|   ALuint buffer; // Associated OpenAL buffer.
 | ||||
|   char* name;   /* Buffers name. */ | ||||
|   ALuint buffer; /* Associated OpenAL buffer. */ | ||||
| } alSound; | ||||
| 
 | ||||
| // Voice private flags (public in sound.h).
 | ||||
| #define VOICE_PLAYING   (1<<0)  // Voice is playing.
 | ||||
| #define VOICE_DONE      (1<<1)  // Voice is done - must remove.
 | ||||
| /* Voice private flags (public in sound.h). */ | ||||
| #define VOICE_PLAYING   (1<<0)  /* Voice is playing. */ | ||||
| #define VOICE_DONE      (1<<1)  /* Voice is done - must remove. */ | ||||
| #define voice_set(v,f) ((v)->flags |= f) | ||||
| #define voice_is(v,f)  ((v)->flags & f) | ||||
| 
 | ||||
| // Global sound lock.
 | ||||
| /* Global sound lock. */ | ||||
| SDL_mutex* sound_lock = NULL; | ||||
| 
 | ||||
| // Gobal device and context.
 | ||||
| /* Gobal device and context. */ | ||||
| static ALCcontext* al_context = NULL; | ||||
| static ALCdevice* al_device = NULL; | ||||
| 
 | ||||
| // Threads.
 | ||||
| /* Threads. */ | ||||
| static SDL_Thread* music_player = NULL; | ||||
| 
 | ||||
| // List of sounds available (All preloaded into a buffer).
 | ||||
| /* List of sounds available (All preloaded into a buffer). */ | ||||
| static alSound* sound_list = NULL; | ||||
| static int nsound_list = 0; | ||||
| 
 | ||||
| // Struct to hold all the sources and currently attached voice.
 | ||||
| static ALuint* source_stack = NULL; // And it's stack.
 | ||||
| /* Struct to hold all the sources and currently attached voice. */ | ||||
| static ALuint* source_stack = NULL; /* And it's stack. */ | ||||
| static int source_nstack = 0; | ||||
| 
 | ||||
| // Virtual voice.
 | ||||
| /* Virtual voice. */ | ||||
| struct alVoice { | ||||
|   alVoice* next;      // Yes it's a linked list.
 | ||||
|   alVoice* next;      /* Yes it's a linked list. */ | ||||
| 
 | ||||
|   //ALuint id;        // Unique id for the voice.
 | ||||
|   /*ALuint id;        // Unique id for the voice. */ | ||||
| 
 | ||||
|   ALuint source;      // Source itself, 0 if not set.
 | ||||
|   ALuint buffer;      // Buffer.
 | ||||
|   ALuint source;      /* Source itself, 0 if not set. */ | ||||
|   ALuint buffer;      /* Buffer. */ | ||||
| 
 | ||||
|   int priority;       // Base priority.
 | ||||
|   int priority;       /* Base priority. */ | ||||
| 
 | ||||
|   double px, py;      // Position.
 | ||||
|   //double vx, vy;    // Velocity.
 | ||||
|   double px, py;      /* Position. */ | ||||
|   /*double vx, vy;    // Velocity. */ | ||||
| 
 | ||||
|   unsigned int start; // time started in ms.
 | ||||
|   unsigned int flags; // Flags to set properties.
 | ||||
|   unsigned int start; /* time started in ms. */ | ||||
|   unsigned int flags; /* Flags to set properties. */ | ||||
| }; | ||||
| static alVoice* voice_start = NULL; | ||||
| static alVoice* voice_end   = NULL; | ||||
| 
 | ||||
| // Volume.
 | ||||
| /* Volume. */ | ||||
| static ALfloat svolume = 0.3; | ||||
| 
 | ||||
| static int  sound_makeList(void); | ||||
| @ -124,15 +124,15 @@ int sound_init(void) { | ||||
| 
 | ||||
|   ret = 0; | ||||
|    | ||||
|   // We'll need a mutex.
 | ||||
|   /* We'll need a mutex. */ | ||||
|   sound_lock = SDL_CreateMutex(); | ||||
|   soundLock(); | ||||
| 
 | ||||
|   // Initialize alut - I think it's worth it.
 | ||||
|   /* Initialize alut - I think it's worth it. */ | ||||
|   alutInitWithoutContext(NULL, NULL); | ||||
| 
 | ||||
|   const ALchar* device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); | ||||
|   // Open the default device.
 | ||||
|   /* Open the default device. */ | ||||
|   al_device = alcOpenDevice(NULL); | ||||
|   if(al_device == NULL) { | ||||
|     WARN("Unable to open default sound device"); | ||||
| @ -140,7 +140,7 @@ int sound_init(void) { | ||||
|     goto snderr_dev; | ||||
|   } | ||||
| 
 | ||||
|   // Create the OpenAL context.
 | ||||
|   /* Create the OpenAL context. */ | ||||
|   al_context = alcCreateContext(al_device, NULL); | ||||
|   if(sound_lock == NULL) { | ||||
|     WARN("Unable to create OpenAL context"); | ||||
| @ -148,34 +148,34 @@ int sound_init(void) { | ||||
|     goto snderr_ctx; | ||||
|   } | ||||
| 
 | ||||
|   // Clear the errors.
 | ||||
|   /* Clear the errors. */ | ||||
|   alGetError(); | ||||
| 
 | ||||
|   // Set active context.
 | ||||
|   /* Set active context. */ | ||||
|   if(alcMakeContextCurrent(al_context)==AL_FALSE) { | ||||
|     WARN("Failure to set default context"); | ||||
|     ret = -4; | ||||
|     goto snderr_act; | ||||
|   } | ||||
| 
 | ||||
|   // Set the master gain.
 | ||||
|   /* Set the master gain. */ | ||||
|   alListenerf(AL_GAIN, .1); | ||||
| 
 | ||||
|   // Set the distance model.
 | ||||
|   /* Set the distance model. */ | ||||
|   alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); | ||||
| 
 | ||||
|   // We can unlock now.
 | ||||
|   /* We can unlock now. */ | ||||
|   soundUnlock(); | ||||
| 
 | ||||
|   // Start the music server.
 | ||||
|   /* Start the music server. */ | ||||
|   music_init(); | ||||
| 
 | ||||
|   // Start allocating the sources - music has already taken this.
 | ||||
|   alGetError(); // Another error clear.
 | ||||
|   /* Start allocating the sources - music has already taken this. */ | ||||
|   alGetError(); /* Another error clear. */ | ||||
|   mem = 0; | ||||
|   while(((err = alGetError()) == AL_NO_ERROR) && (source_nstack < 128)) { | ||||
|     if(mem < source_nstack+1) { | ||||
|       // Allocate more memory.
 | ||||
|       /* Allocate more memory. */ | ||||
|       mem += 32; | ||||
|       source_stack = realloc(source_stack, sizeof(ALuint) * mem); | ||||
|     } | ||||
| @ -183,20 +183,20 @@ int sound_init(void) { | ||||
|     source_nstack++; | ||||
|   } | ||||
|    | ||||
|   // Use minimal ram.
 | ||||
|   /* Use minimal ram. */ | ||||
|   source_stack = realloc(source_stack, sizeof(ALuint) * source_nstack); | ||||
| 
 | ||||
|   // Debug magic.
 | ||||
|   /* Debug magic. */ | ||||
|   DEBUG("OpenAL:    %s", device); | ||||
|   DEBUG("Sources:   %d", source_nstack); | ||||
|   DEBUG("Renderer:  %s", alGetString(AL_RENDERER)); | ||||
|   DEBUG("Version:   %s", alGetString(AL_VERSION)); | ||||
| 
 | ||||
|   // Load up all the sounds.
 | ||||
|   /* Load up all the sounds. */ | ||||
|   sound_makeList(); | ||||
|   music_makeList(); // And music.
 | ||||
|   music_makeList(); /* And music. */ | ||||
| 
 | ||||
|   // Now start the music thread.
 | ||||
|   /* Now start the music thread. */ | ||||
|   music_player = SDL_CreateThread(music_thread, NULL); | ||||
| 
 | ||||
|   return 0; | ||||
| @ -216,18 +216,18 @@ snderr_dev: | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Clean up after the sound system.
 | ||||
| /* Clean up after the sound system. */ | ||||
| void sound_exit(void) { | ||||
|   int i; | ||||
|   // Free the sounds.
 | ||||
|   /* Free the sounds. */ | ||||
|   for(i = 0; i < nsound_list; i++) | ||||
|     sound_free(&sound_list[i]); | ||||
|   free(sound_list); | ||||
|   sound_list = NULL; | ||||
|   nsound_list = 0; | ||||
| 
 | ||||
|   // Must stop the music before killing it,
 | ||||
|   // then thread should commit suicide.
 | ||||
|   /* Must stop the music before killing it, */ | ||||
|   /* then thread should commit suicide. */ | ||||
|   if(music_player) { | ||||
|     music_stop(); | ||||
|     music_kill(); | ||||
| @ -235,11 +235,11 @@ void sound_exit(void) { | ||||
|     music_exit(); | ||||
|   } | ||||
| 
 | ||||
|   // Clean up the voices.
 | ||||
|   /* Clean up the voices. */ | ||||
|   while(voice_start != NULL) | ||||
|     voice_rm(NULL, voice_start); | ||||
| 
 | ||||
|   // Clean up the sources.
 | ||||
|   /* Clean up the sources. */ | ||||
|   if(source_stack) | ||||
|     alDeleteSources(source_nstack, source_stack); | ||||
| 
 | ||||
| @ -255,11 +255,11 @@ void sound_exit(void) { | ||||
|     soundUnlock(); | ||||
|     SDL_DestroyMutex(sound_lock); | ||||
|   } | ||||
|   // Cya alut!
 | ||||
|   /* Cya alut! */ | ||||
|   alutExit(); | ||||
| } | ||||
| 
 | ||||
| // Get the buffer to sound of [name].
 | ||||
| /* Get the buffer to sound of [name]. */ | ||||
| ALuint sound_get(char* name) { | ||||
|   if(sound_lock == NULL) return 0; | ||||
| 
 | ||||
| @ -271,7 +271,7 @@ ALuint sound_get(char* name) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Make list of available sounds.
 | ||||
| /* Make list of available sounds. */ | ||||
| static int sound_makeList(void) { | ||||
|   if(sound_lock == NULL) return 0; | ||||
| 
 | ||||
| @ -281,38 +281,38 @@ static int sound_makeList(void) { | ||||
|   int len; | ||||
|   int mem; | ||||
| 
 | ||||
|   // Get the file list.
 | ||||
|   /* Get the file list. */ | ||||
|   files = pack_listfiles(data, &nfiles); | ||||
| 
 | ||||
|   // Load the profiles.
 | ||||
|   /* Load the profiles. */ | ||||
|   mem = 0; | ||||
|   for(i = 0; i < nfiles; i++) | ||||
|     if((strncmp(files[i], SOUND_PREFIX, strlen(SOUND_PREFIX))==0) && | ||||
|        (strncmp(files[i] + strlen(files[i]) - strlen(SOUND_SUFFIX), | ||||
|                 SOUND_SUFFIX, strlen(SOUND_SUFFIX))==0)) { | ||||
| 
 | ||||
|       // Expand the selection size.
 | ||||
|       /* Expand the selection size. */ | ||||
|       nsound_list++; | ||||
|       if(nsound_list > mem) { | ||||
|         // We must grow.
 | ||||
|         mem += 32;  // We'll overallocate most likely.
 | ||||
|         /* We must grow. */ | ||||
|         mem += 32;  /* We'll overallocate most likely. */ | ||||
|         sound_list = realloc(sound_list, mem*sizeof(alSound)); | ||||
|       } | ||||
| 
 | ||||
|       // Remove the prefix and suffix.
 | ||||
|       /* Remove the prefix and suffix. */ | ||||
|       len = strlen(files[i]) - strlen(SOUND_SUFFIX SOUND_PREFIX); | ||||
|       strncpy(tmp, files[i] + strlen(SOUND_PREFIX), len); | ||||
|       tmp[len] = '\0'; | ||||
| 
 | ||||
|       // give it the new name.
 | ||||
|       /* give it the new name. */ | ||||
|       sound_list[nsound_list-1].name = strdup(tmp); | ||||
|       sound_load(&sound_list[nsound_list-1].buffer, files[i]); | ||||
|     } | ||||
| 
 | ||||
|   // Shrink to minimum ram usage.
 | ||||
|   /* Shrink to minimum ram usage. */ | ||||
|   sound_list = realloc(sound_list, nsound_list*sizeof(alSound)); | ||||
| 
 | ||||
|   // Free the char* allocated by pack.
 | ||||
|   /* Free the char* allocated by pack. */ | ||||
|   for(i = 0; i < nfiles; i++) | ||||
|     free(files[i]); | ||||
|   free(files); | ||||
| @ -322,7 +322,7 @@ static int sound_makeList(void) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Loads a sound into the sound_list.
 | ||||
| /* Loads a sound into the sound_list. */ | ||||
| static int sound_load(ALuint* buffer, char* filename) { | ||||
|   if(sound_lock == NULL) return 0; | ||||
| 
 | ||||
| @ -330,18 +330,18 @@ static int sound_load(ALuint* buffer, char* filename) { | ||||
|   unsigned int size; | ||||
|   ALenum err; | ||||
| 
 | ||||
|   // Get the file data buffer from the packfile.
 | ||||
|   /* Get the file data buffer from the packfile. */ | ||||
|   wavdata = pack_readfile(DATA, filename, &size); | ||||
| 
 | ||||
|   soundLock(); | ||||
| 
 | ||||
|   // Bind to OpenAL buffer.
 | ||||
|   /* Bind to OpenAL buffer. */ | ||||
|   (*buffer) = alutCreateBufferFromFileImage(wavdata, size); | ||||
|   if((*buffer) == AL_NONE) WARN("FAILURE: %s", alutGetErrorString(alutGetError())); | ||||
|   //alGenBuffers(1, buffer);
 | ||||
|   //alBufferData(*buffer, AL_FORMAT_MONO16, wavdata, size, 22050);
 | ||||
|   /*alGenBuffers(1, buffer); */ | ||||
|   /*alBufferData(*buffer, AL_FORMAT_MONO16, wavdata, size, 22050); */ | ||||
| 
 | ||||
|   // Errors?
 | ||||
|   /* Errors? */ | ||||
|   if((err = alGetError()) != AL_NO_ERROR) { | ||||
|     WARN("OpenAL erro '%d' loading sound '%s'.", err, filename); | ||||
|     return 0; | ||||
| @ -349,7 +349,7 @@ static int sound_load(ALuint* buffer, char* filename) { | ||||
| 
 | ||||
|   soundUnlock(); | ||||
| 
 | ||||
|   // Finish up.
 | ||||
|   /* Finish up. */ | ||||
|   free(wavdata); | ||||
|   return 0; | ||||
| } | ||||
| @ -359,39 +359,39 @@ static void sound_free(alSound* snd) { | ||||
| 
 | ||||
|   soundLock(); | ||||
| 
 | ||||
|   // Free the stuff.
 | ||||
|   /* Free the stuff. */ | ||||
|   if(snd->name) free(snd->name); | ||||
|   alDeleteBuffers(1, &snd->buffer); | ||||
| 
 | ||||
|   soundUnlock(); | ||||
| } | ||||
| 
 | ||||
| // Update the sounds and prioritize them.
 | ||||
| /* Update the sounds and prioritize them. */ | ||||
| void sound_update(void) { | ||||
|   ALint stat; | ||||
|   alVoice* voice, *prev, *next; | ||||
| 
 | ||||
|   if(sound_lock == NULL)  return; // Sound system is off.
 | ||||
|   if(voice_start == NULL) return; // No voices.
 | ||||
|   if(sound_lock == NULL)  return; /* Sound system is off. */ | ||||
|   if(voice_start == NULL) return; /* No voices. */ | ||||
| 
 | ||||
|   soundLock(); | ||||
| 
 | ||||
|   // Update sound.
 | ||||
|   /* Update sound. */ | ||||
|   prev = NULL; | ||||
|   voice = voice_start; | ||||
|   do { | ||||
|     next = voice->next; | ||||
| 
 | ||||
|     // Get status.
 | ||||
|     /* Get status. */ | ||||
|     stat = -1; | ||||
|     if(voice->source != 0) | ||||
|       alGetSourcei(voice->source, AL_SOURCE_STATE, &stat); | ||||
| 
 | ||||
|     if(!voice_is(voice, VOICE_DONE)) { // Still working.
 | ||||
|       // Voice has a source.
 | ||||
|     if(!voice_is(voice, VOICE_DONE)) { /* Still working. */ | ||||
|       /* Voice has a source. */ | ||||
|       if(voice->source != 0) { | ||||
| 
 | ||||
|         // Update position.
 | ||||
|         /* Update position. */ | ||||
|         alSource3f(voice->source, AL_POSITION, | ||||
|             voice->px, voice->py, 0.); | ||||
|         /*alSource3f(voice->source, AL_VELOCITY,
 | ||||
| @ -400,9 +400,9 @@ void sound_update(void) { | ||||
| 
 | ||||
|       prev = voice; | ||||
|     }else { | ||||
|       // Delete them.
 | ||||
|       /* Delete them. */ | ||||
|       if(stat != AL_PLAYING) | ||||
|         voice_rm(prev, voice); // Do not set prev to voice.
 | ||||
|         voice_rm(prev, voice); /* Do not set prev to voice. */ | ||||
|       else | ||||
|         prev = voice; | ||||
|     } | ||||
| @ -412,53 +412,53 @@ void sound_update(void) { | ||||
|   soundUnlock(); | ||||
| } | ||||
| 
 | ||||
| // Remove a voice.
 | ||||
| /* Remove a voice. */ | ||||
| static void voice_rm(alVoice* prev, alVoice* voice) { | ||||
|   ALint stat; | ||||
| 
 | ||||
|   if(voice->source != 0) { // Source must exist.
 | ||||
|     // Stop it if playing.
 | ||||
|   if(voice->source != 0) { /* Source must exist. */ | ||||
|     /* Stop it if playing. */ | ||||
|     alGetSourcei(voice->source, AL_SOURCE_STATE, &stat); | ||||
|     if(stat == AL_PLAYING) alSourceStop(voice->source); | ||||
| 
 | ||||
|     // Clear it and get rid of it.
 | ||||
|     source_stack[source_nstack++] = voice->source; // Throw it back.
 | ||||
|     /* Clear it and get rid of it. */ | ||||
|     source_stack[source_nstack++] = voice->source; /* Throw it back. */ | ||||
|   } | ||||
| 
 | ||||
|   // Delete from linked list.
 | ||||
|   if(prev == NULL) // Was the first member.
 | ||||
|   /* Delete from linked list. */ | ||||
|   if(prev == NULL) /* Was the first member. */ | ||||
|     voice_start = voice->next; | ||||
|   else // Not first memmber.
 | ||||
|   else /* Not first memmber. */ | ||||
|     prev->next = voice->next; | ||||
|   if(voice_end == voice) // Last voice in linked list.
 | ||||
|   if(voice_end == voice) /* Last voice in linked list. */ | ||||
|     voice_end = prev; | ||||
|   free(voice); | ||||
| } | ||||
| 
 | ||||
| // Set all the sounds volume to vol.
 | ||||
| /* Set all the sounds volume to vol. */ | ||||
| void sound_volume(const double vol) { | ||||
|   if(sound_lock == NULL) return; | ||||
| 
 | ||||
|   svolume = (ALfloat) vol; | ||||
| } | ||||
| 
 | ||||
| // Attempt to alloc a source for a voice.
 | ||||
| /* Attempt to alloc a source for a voice. */ | ||||
| static int voice_getSource(alVoice* voc) { | ||||
|   int ret; | ||||
| 
 | ||||
|   // Sound system isn't on.
 | ||||
|   /* Sound system isn't on. */ | ||||
|   if(sound_lock == NULL) return -1; | ||||
| 
 | ||||
|   ret = 0; // Default return.
 | ||||
|   ret = 0; /* Default return. */ | ||||
| 
 | ||||
|   soundLock(); | ||||
| 
 | ||||
|   // Try and grab a source.
 | ||||
|   if(source_nstack > 0) { // We have the source.
 | ||||
|     // We must pull it from the free source vector.
 | ||||
|   /* Try and grab a source. */ | ||||
|   if(source_nstack > 0) { /* We have the source. */ | ||||
|     /* We must pull it from the free source vector. */ | ||||
|     voc->source = source_stack[--source_nstack]; | ||||
| 
 | ||||
|     // Initialize and play.
 | ||||
|     /* Initialize and play. */ | ||||
|     voice_init(voc); | ||||
|     ret = voice_play(voc); | ||||
|   } else | ||||
| @ -469,23 +469,23 @@ static int voice_getSource(alVoice* voc) { | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| // Must lock becore calling.
 | ||||
| /* Must lock becore calling. */ | ||||
| static void voice_init(alVoice* voice) { | ||||
|   // Distance model.
 | ||||
|   /* Distance model. */ | ||||
|   alSourcef(voice->source, AL_ROLLOFF_FACTOR, SOUND_ROLLOFF_FACTOR); | ||||
|   alSourcef(voice->source, AL_MAX_DISTANCE, SOUND_MAX_DIST); | ||||
|   alSourcef(voice->source, AL_REFERENCE_DISTANCE, SOUND_REFERENCE_DIST); | ||||
| 
 | ||||
|   alSourcef(voice->source, AL_GAIN, svolume); | ||||
|   alSource3f(voice->source, AL_POSITION, voice->px, voice->py, 0.); | ||||
|   //alSource3f(voice->source, AL_VELOCITY, voice->vx, voice->vy, 0.);
 | ||||
|   /*alSource3f(voice->source, AL_VELOCITY, voice->vx, voice->vy, 0.); */ | ||||
|   if(voice_is(voice, VOICE_LOOPING)) | ||||
|     alSourcei(voice->source, AL_LOOPING, AL_TRUE); | ||||
|   else | ||||
|     alSourcei(voice->source, AL_LOOPING, AL_FALSE); | ||||
| } | ||||
| 
 | ||||
| // Create a dynamic moving piece.
 | ||||
| /* Create a dynamic moving piece. */ | ||||
| alVoice* sound_addVoice(int priority, double px, double py, | ||||
|     double vx, double vy, const ALuint buffer, const unsigned int flags) { | ||||
| 
 | ||||
| @ -495,25 +495,25 @@ alVoice* sound_addVoice(int priority, double px, double py, | ||||
| 
 | ||||
|   if(sound_lock == NULL) return NULL; | ||||
| 
 | ||||
|   // Allocate the voice.
 | ||||
|   /* Allocate the voice. */ | ||||
|   voc = malloc(sizeof(alVoice)); | ||||
| 
 | ||||
|   // Set the data.
 | ||||
|   /* Set the data. */ | ||||
|   voc->next = NULL; | ||||
|   voc->priority = priority; | ||||
|   voc->start = SDL_GetTicks(); | ||||
|   voc->buffer = buffer; | ||||
| 
 | ||||
|   // Handle positions.
 | ||||
|   /* Handle positions. */ | ||||
|   voc->px = px; | ||||
|   voc->py = py; | ||||
|   //voc->vx = vx;
 | ||||
|   //voc->vy = vy;
 | ||||
|   /*voc->vx = vx; */ | ||||
|   /*voc->vy = vy; */ | ||||
|    | ||||
|   // Handle the flags.
 | ||||
|   /* Handle the flags. */ | ||||
|   voice_parseFlags(voc, flags); | ||||
| 
 | ||||
|   // Get the source.
 | ||||
|   /* Get the source. */ | ||||
|   voice_getSource(voc); | ||||
| 
 | ||||
|   if(voice_start == NULL) { | ||||
| @ -528,14 +528,14 @@ alVoice* sound_addVoice(int priority, double px, double py, | ||||
|   return voc; | ||||
| } | ||||
| 
 | ||||
| // Delete the voice.
 | ||||
| /* Delete the voice. */ | ||||
| void sound_delVoice(alVoice* voice) { | ||||
|   if(sound_lock == NULL) return; | ||||
| 
 | ||||
|   voice_set(voice, VOICE_DONE); | ||||
| } | ||||
| 
 | ||||
| // Update voice position, should be run once per frame.
 | ||||
| /* Update voice position, should be run once per frame. */ | ||||
| void voice_update(alVoice* voice, double px, double py, double vx, double vy) { | ||||
|   (void) vx; | ||||
|   (void) vy; | ||||
| @ -544,24 +544,24 @@ void voice_update(alVoice* voice, double px, double py, double vx, double vy) { | ||||
| 
 | ||||
|   voice->px = px; | ||||
|   voice->py = py; | ||||
|   //voice->vx = vx;
 | ||||
|   //voice->vy = vy;
 | ||||
|   /*voice->vx = vx; */ | ||||
|   /*voice->vy = vy; */ | ||||
| } | ||||
| 
 | ||||
| // Changes the voice's buffer.
 | ||||
| /* Changes the voice's buffer. */ | ||||
| void voice_buffer(alVoice* voice, const ALuint buffer, const unsigned int flags) { | ||||
|   if(voice == NULL) return; | ||||
| 
 | ||||
|   voice->buffer = buffer; | ||||
|   voice_parseFlags(voice, flags); | ||||
| 
 | ||||
|   // Start playing.
 | ||||
|   /* Start playing. */ | ||||
|   soundLock(); | ||||
|   voice_play(voice); | ||||
|   soundUnlock(); | ||||
| } | ||||
| 
 | ||||
| // Stop playing sound.
 | ||||
| /* Stop playing sound. */ | ||||
| void voice_stop(alVoice* voice) { | ||||
|   if(voice == NULL) return; | ||||
| 
 | ||||
| @ -571,11 +571,11 @@ void voice_stop(alVoice* voice) { | ||||
|   soundUnlock(); | ||||
| } | ||||
| 
 | ||||
| // Handle flags.
 | ||||
| /* Handle flags. */ | ||||
| static void voice_parseFlags(alVoice* voice, const unsigned int flags) { | ||||
|   voice->flags = 0; // Defaults.
 | ||||
|   voice->flags = 0; /* Defaults. */ | ||||
| 
 | ||||
|   // Looping.
 | ||||
|   /* Looping. */ | ||||
|   if(flags & VOICE_LOOPING) | ||||
|     voice_set(voice, VOICE_LOOPING); | ||||
| 
 | ||||
| @ -585,20 +585,20 @@ static void voice_parseFlags(alVoice* voice, const unsigned int flags) { | ||||
|     alSourcei(voice->source, AL_SOURCE_RELATIVE, AL_FALSE); | ||||
| } | ||||
| 
 | ||||
| // Make a voice play. Must lock before calling.
 | ||||
| /* Make a voice play. Must lock before calling. */ | ||||
| static int voice_play(alVoice* voice) { | ||||
|   ALenum err; | ||||
|   ALint stat; | ||||
| 
 | ||||
|   // Must have buffer.
 | ||||
|   /* Must have buffer. */ | ||||
|   if(voice->buffer != 0) { | ||||
|     alGetSourcei(voice->source, AL_SOURCE_STATE, &stat); | ||||
|     if(stat == AL_PLAYING) | ||||
|       alSourceStop(voice->source); | ||||
|     // Set buffer.
 | ||||
|     /* Set buffer. */ | ||||
|     alSourcei(voice->source, AL_BUFFER, voice->buffer); | ||||
| 
 | ||||
|     // Try to play the source.
 | ||||
|     /* Try to play the source. */ | ||||
|     alSourcePlay(voice->source); | ||||
|     err = alGetError(); | ||||
|     if(err == AL_NO_ERROR) voice_set(voice, VOICE_PLAYING); | ||||
| @ -616,13 +616,13 @@ void sound_listener(double dir, double px, double py, double vx, double vy) { | ||||
| 
 | ||||
|   soundLock(); | ||||
| 
 | ||||
|   // Set orientation.
 | ||||
|   /* Set orientation. */ | ||||
|   ALfloat ori[] = { 0., 0., 0., 0., 0., 1. }; | ||||
|   ori[0] = cos(dir); | ||||
|   ori[1] = sin(dir); | ||||
|   alListenerfv(AL_ORIENTATION, ori); | ||||
|   alListener3f(AL_POSITION, px, py, 1.); | ||||
|   //alListener3f(AL_VELOCITY, vx, vy, 0.);
 | ||||
|   /*alListener3f(AL_VELOCITY, vx, vy, 0.); */ | ||||
| 
 | ||||
|   soundUnlock(); | ||||
| } | ||||
|  | ||||
							
								
								
									
										14
									
								
								src/sound.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/sound.h
									
									
									
									
									
								
							| @ -2,31 +2,31 @@ | ||||
| #include <AL/al.h> | ||||
| #include "physics.h" | ||||
| 
 | ||||
| #define VOICE_LOOPING   (1<<10) // Voice loops.
 | ||||
| #define VOICE_STATIC    (1<<11) // Voice isn't relative.
 | ||||
| #define VOICE_LOOPING   (1<<10) /* Voice loops. */ | ||||
| #define VOICE_STATIC    (1<<11) /* Voice isn't relative. */ | ||||
| 
 | ||||
| struct alVoice; | ||||
| typedef struct alVoice alVoice; | ||||
| 
 | ||||
| // Sound subsystem.
 | ||||
| /* Sound subsystem. */ | ||||
| int sound_init(void); | ||||
| void sound_exit(void); | ||||
| void sound_update(void); | ||||
| 
 | ||||
| // Sound manupulation functions.
 | ||||
| /* Sound manupulation functions. */ | ||||
| ALuint sound_get(char* name); | ||||
| void sound_volume(const double vol); | ||||
| 
 | ||||
| // Voice manipulation function.
 | ||||
| /* Voice manipulation function. */ | ||||
| alVoice* sound_addVoice(int priority, double px, double py, | ||||
|     double vx, double vy, const ALuint buffer, const unsigned int flags); | ||||
| 
 | ||||
| void sound_delVoice(alVoice* voice); // Delete voice.
 | ||||
| void sound_delVoice(alVoice* voice); /* Delete voice. */ | ||||
| 
 | ||||
| void voice_update(alVoice* voice, double px, double py, double vx, double vy); | ||||
| void voice_buffer(alVoice* voice, const ALuint buffer, const unsigned int flags); | ||||
| void voice_stop(alVoice* voice); | ||||
| 
 | ||||
| // Listener manipulation.
 | ||||
| /* Listener manipulation. */ | ||||
| void sound_listener(double dir, double px, double py, double vx, double vy); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										260
									
								
								src/space.c
									
									
									
									
									
								
							
							
						
						
									
										260
									
								
								src/space.c
									
									
									
									
									
								
							| @ -34,7 +34,7 @@ | ||||
| #define PLANET_GFX_EXTERIOR_W 400 | ||||
| #define PLANET_GFX_EXTERIOR_H 400 | ||||
| 
 | ||||
| // Overcome warning due to zero value.
 | ||||
| /* Overcome warning due to zero value. */ | ||||
| 
 | ||||
| #define FLAG_XSET           (1<<0) | ||||
| #define FLAG_YSET           (1<<1) | ||||
| @ -44,45 +44,45 @@ | ||||
| #define FLAG_TECHSET        (1<<5) | ||||
| #define FLAG_FACTIONSET     (1<<6) | ||||
| 
 | ||||
| // Planet <-> system name stack.
 | ||||
| /* Planet <-> system name stack. */ | ||||
| static char** planetname_stack  = NULL; | ||||
| static char** systemname_stack  = NULL; | ||||
| static int    spacename_nstack  = 0; | ||||
| 
 | ||||
| // Star system stack and co.
 | ||||
| StarSystem* systems_stack = NULL; // Star system stack.
 | ||||
| int systems_nstack     = 0;       // Number of star systems.
 | ||||
| static int  nplanets    = 0;      // Total number of loaded planets - A little silly.
 | ||||
| StarSystem* cur_system   = NULL;  // Current star system.
 | ||||
| /* Star system stack and co. */ | ||||
| StarSystem* systems_stack = NULL; /* Star system stack. */ | ||||
| int systems_nstack     = 0;       /* Number of star systems. */ | ||||
| static int  nplanets    = 0;      /* Total number of loaded planets - A little silly. */ | ||||
| StarSystem* cur_system   = NULL;  /* Current star system. */ | ||||
| 
 | ||||
| // Fleet spawn rate.
 | ||||
| unsigned int spawn_timer = 0; // Controls spawn rate.
 | ||||
| /* Fleet spawn rate. */ | ||||
| unsigned int spawn_timer = 0; /* Controls spawn rate. */ | ||||
| 
 | ||||
| // Star stack and co.
 | ||||
| #define STAR_BUF 100 // Area to leave around screen, more = less repitition.
 | ||||
| /* Star stack and co. */ | ||||
| #define STAR_BUF 100 /* Area to leave around screen, more = less repitition. */ | ||||
| typedef struct Star_ { | ||||
|   double x, y; // Position. It is simpler ligher to use two doubles than the physics.
 | ||||
|   double x, y; /* Position. It is simpler ligher to use two doubles than the physics. */ | ||||
|   double brightness; | ||||
| } Star; | ||||
| 
 | ||||
| static Star* stars = NULL;  // Star array.
 | ||||
| static int nstars = 0;      // Total stars.
 | ||||
| static int mstars = 0;      // Memory stars are taking.
 | ||||
| static Star* stars = NULL;  /* Star array. */ | ||||
| static int nstars = 0;      /* Total stars. */ | ||||
| static int mstars = 0;      /* Memory stars are taking. */ | ||||
| 
 | ||||
| // Intern.
 | ||||
| /* Intern. */ | ||||
| static StarSystem* system_get(const char* sysname); | ||||
| static Planet* planet_pull(const char* name); | ||||
| static void space_addFleet(Fleet* fleet); | ||||
| static StarSystem* system_parse(const xmlNodePtr parent); | ||||
| static void system_parseJumps(const xmlNodePtr parent); | ||||
| static PlanetClass planetclass_get(const char a); | ||||
| // Extern.
 | ||||
| /* Extern. */ | ||||
| extern void player_message(const char* fmt, ...); | ||||
| void planets_minimap(const double res, const double w, | ||||
|     const double h, const RadarShape shape); | ||||
| 
 | ||||
| // Draw the planet. Used in planet.c
 | ||||
| // Matrix mode is already displaced to center of the minimap.
 | ||||
| /* Draw the planet. Used in planet.c */ | ||||
| /* Matrix mode is already displaced to center of the minimap. */ | ||||
| #define PIXEL(x,y)  if((shape == RADAR_RECT && ABS(x)<w/2. && ABS(y)<h/2.) || \ | ||||
|   (shape == RADAR_CIRCLE && (((x)*(x)+(y)*(y)) < rc))) glVertex2i((x),(y)) | ||||
| void planets_minimap(const double res, const double w, | ||||
| @ -146,20 +146,20 @@ void planets_minimap(const double res, const double w, | ||||
| } | ||||
| #undef PIXEL | ||||
| 
 | ||||
| // A* Algorithm fo shortest path finding.
 | ||||
| /* A* Algorithm fo shortest path finding. */ | ||||
| 
 | ||||
| // The node struct.
 | ||||
| /* The node struct. */ | ||||
| typedef struct SysNode_ { | ||||
|   struct SysNode_* next, *gnext; | ||||
| 
 | ||||
|   struct SysNode_* parent; | ||||
|   StarSystem* sys; | ||||
|   double r; // Ranking.
 | ||||
|   int g;    // Step.
 | ||||
|   double r; /* Ranking. */ | ||||
|   int g;    /* Step. */ | ||||
| } SysNode; | ||||
| 
 | ||||
| static SysNode* A_gc; | ||||
| // Prototypes.
 | ||||
| /* Prototypes. */ | ||||
| static SysNode* A_newNode(StarSystem* sys, SysNode* parent); | ||||
| static double A_h(StarSystem* n, StarSystem* g); | ||||
| static double A_g(SysNode* n); | ||||
| @ -169,7 +169,7 @@ static SysNode* A_in(SysNode* first, StarSystem* cur); | ||||
| static SysNode* A_lowest(SysNode* first); | ||||
| static void A_freeList(SysNode* first); | ||||
| 
 | ||||
| // Creates a new node link to star system.
 | ||||
| /* Creates a new node link to star system. */ | ||||
| static SysNode* A_newNode(StarSystem* sys, SysNode* parent) { | ||||
|   SysNode* n; | ||||
| 
 | ||||
| @ -190,17 +190,17 @@ static SysNode* A_newNode(StarSystem* sys, SysNode* parent) { | ||||
| static double A_h(StarSystem* n, StarSystem* g) { | ||||
|   (void)n; | ||||
|   (void)g; | ||||
|   // Euclidean distance.
 | ||||
|   //return sqrt(pow2(n->pos.x - g->pos.x) + pow2(n->pos.y - g->pos.y))/100.;
 | ||||
|   /* Euclidean distance. */ | ||||
|   /*return sqrt(pow2(n->pos.x - g->pos.x) + pow2(n->pos.y - g->pos.y))/100.; */ | ||||
|   return 0.; | ||||
| } | ||||
| 
 | ||||
| // Get the g from a node.
 | ||||
| /* Get the g from a node. */ | ||||
| static double A_g(SysNode* n) { | ||||
|   return n->g; | ||||
| } | ||||
| 
 | ||||
| // Add a node to the linkes list.
 | ||||
| /* Add a node to the linkes list. */ | ||||
| static SysNode* A_add(SysNode* first, SysNode* cur) { | ||||
|   SysNode* n; | ||||
| 
 | ||||
| @ -215,7 +215,7 @@ static SysNode* A_add(SysNode* first, SysNode* cur) { | ||||
|   return first; | ||||
| } | ||||
| 
 | ||||
| // Remove a node from a linked list.
 | ||||
| /* Remove a node from a linked list. */ | ||||
| static SysNode* A_rm(SysNode* first, StarSystem* cur) { | ||||
|   SysNode* n, *p; | ||||
| 
 | ||||
| @ -238,7 +238,7 @@ static SysNode* A_rm(SysNode* first, StarSystem* cur) { | ||||
|   return first; | ||||
| } | ||||
| 
 | ||||
| // Check if node is in linked list.
 | ||||
| /* Check if node is in linked list. */ | ||||
| static SysNode* A_in(SysNode* first, StarSystem* cur) { | ||||
|   SysNode* n; | ||||
|    | ||||
| @ -253,7 +253,7 @@ static SysNode* A_in(SysNode* first, StarSystem* cur) { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| // Return the lowest ranking node from a linked list of nodes.
 | ||||
| /* Return the lowest ranking node from a linked list of nodes. */ | ||||
| static SysNode* A_lowest(SysNode* first) { | ||||
|   SysNode* lowest, *n; | ||||
| 
 | ||||
| @ -270,7 +270,7 @@ static SysNode* A_lowest(SysNode* first) { | ||||
|   return lowest; | ||||
| } | ||||
| 
 | ||||
| // Free a linked list.
 | ||||
| /* Free a linked list. */ | ||||
| static void A_freeList(SysNode* first) { | ||||
|   SysNode* p, *n; | ||||
| 
 | ||||
| @ -299,17 +299,17 @@ StarSystem** system_getJumpPath(int* njumps, char* sysstart, char* sysend) { | ||||
| 
 | ||||
|   A_gc = NULL; | ||||
| 
 | ||||
|   // Initial and target systems.
 | ||||
|   ssys = system_get(sysstart);  // Start.
 | ||||
|   esys = system_get(sysend);    // End.
 | ||||
|   /* Initial and target systems. */ | ||||
|   ssys = system_get(sysstart);  /* Start. */ | ||||
|   esys = system_get(sysend);    /* End. */ | ||||
| 
 | ||||
|   // Start the linked lists.
 | ||||
|   /* Start the linked lists. */ | ||||
|   open = closed = NULL; | ||||
|   cur = A_newNode(ssys, NULL); | ||||
|   open = A_add(open, cur); // Initial open node is the start system.
 | ||||
|   open = A_add(open, cur); /* Initial open node is the start system. */ | ||||
| 
 | ||||
|   while((cur = A_lowest(open))->sys != esys) { | ||||
|     // Get best from open and toss to closed.
 | ||||
|     /* Get best from open and toss to closed. */ | ||||
|     open = A_rm(open, cur->sys); | ||||
|     closed = A_add(closed, cur); | ||||
|     cost = A_g(cur) + 1; | ||||
| @ -320,12 +320,12 @@ StarSystem** system_getJumpPath(int* njumps, char* sysstart, char* sysend) { | ||||
| 
 | ||||
|       ocost = A_in(open, sys); | ||||
|       if((ocost != NULL) && (cost < ocost->g)) { | ||||
|         open = A_rm(open, sys); // New path is better.
 | ||||
|         open = A_rm(open, sys); /* New path is better. */ | ||||
|       } | ||||
| 
 | ||||
|       ccost = A_in(closed, sys); | ||||
|       if(ccost != NULL) { | ||||
|         closed = A_rm(closed, sys); // Shouldn't happen.
 | ||||
|         closed = A_rm(closed, sys); /* Shouldn't happen. */ | ||||
|       } | ||||
| 
 | ||||
|       if((ocost == NULL) && (ccost == NULL)) { | ||||
| @ -336,7 +336,7 @@ StarSystem** system_getJumpPath(int* njumps, char* sysstart, char* sysend) { | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   // Build the path backwards.
 | ||||
|   /* Build the path backwards. */ | ||||
|   (*njumps) = A_g(cur); | ||||
|   res = malloc(sizeof(StarSystem*) * (*njumps)); | ||||
|   for(i = 0; i < (*njumps); i++) { | ||||
| @ -344,14 +344,14 @@ StarSystem** system_getJumpPath(int* njumps, char* sysstart, char* sysend) { | ||||
|     cur = cur->parent; | ||||
|   } | ||||
| 
 | ||||
|   // Free the linked list.
 | ||||
|   /* Free the linked list. */ | ||||
|   A_freeList(A_gc); | ||||
|   return res; | ||||
| } | ||||
| 
 | ||||
| static PlanetClass planetclass_get(const char a) { | ||||
|   switch(a) { | ||||
|   // Planets use letters.
 | ||||
|   /* Planets use letters. */ | ||||
|   case 'A': return PLANET_CLASS_A; | ||||
|   case 'B': return PLANET_CLASS_B; | ||||
|   case 'C': return PLANET_CLASS_C; | ||||
| @ -376,7 +376,7 @@ static PlanetClass planetclass_get(const char a) { | ||||
|   case 'Y': return PLANET_CLASS_Y; | ||||
|   case 'Z': return PLANET_CLASS_Z; | ||||
| 
 | ||||
|   // Stations use numbers as there isn't as many.
 | ||||
|   /* Stations use numbers as there isn't as many. */ | ||||
|   case '0' : return STATION_CLASS_A; | ||||
|   case '1' : return STATION_CLASS_B; | ||||
|   case '2' : return STATION_CLASS_C; | ||||
| @ -386,7 +386,7 @@ static PlanetClass planetclass_get(const char a) { | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| // Check distance to ensure we can go into hyperspace.
 | ||||
| /* Check distance to ensure we can go into hyperspace. */ | ||||
| int space_canHyperspace(Pilot* p) { | ||||
|   int i; | ||||
|   double d; | ||||
| @ -400,18 +400,18 @@ int space_canHyperspace(Pilot* p) { | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| // Hyperspace, returns 0 if entering hyperspace, or the distance if not.
 | ||||
| /* Hyperspace, returns 0 if entering hyperspace, or the distance if not. */ | ||||
| int space_hyperspace(Pilot* p) { | ||||
|   if(p->fuel < HYPERSPACE_FUEL) return -3; | ||||
|   if(!space_canHyperspace(p)) return -1; | ||||
| 
 | ||||
|   // Pilot is now going to get automatically ready for hyperspace.
 | ||||
|   /* Pilot is now going to get automatically ready for hyperspace. */ | ||||
|   pilot_setFlag(p, PILOT_HYP_PREP); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Return the name of all the planets that belong to factions.
 | ||||
| /* Return the name of all the planets that belong to factions. */ | ||||
| char** space_getFactionPlanet(int* nplanets, int* factions, int nfactions) { | ||||
|   int i, j, k; | ||||
|   Planet* planet; | ||||
| @ -437,14 +437,14 @@ char** space_getFactionPlanet(int* nplanets, int* factions, int nfactions) { | ||||
|             tmp = realloc(tmp, sizeof(char*) * mtmp); | ||||
|           } | ||||
|           tmp[ntmp-1] = planet->name; | ||||
|           break; // No need to check all factions.
 | ||||
|           break; /* No need to check all factions. */ | ||||
|         } | ||||
|     } | ||||
|   (*nplanets) = ntmp; | ||||
|   return tmp; | ||||
| } | ||||
| 
 | ||||
| // Return the name of a random planet.
 | ||||
| /* Return the name of a random planet. */ | ||||
| char* space_getRndPlanet(void) { | ||||
|   int i, j; | ||||
|   char** tmp; | ||||
| @ -472,7 +472,7 @@ char* space_getRndPlanet(void) { | ||||
|   return res; | ||||
| } | ||||
| 
 | ||||
| // Get the system from it's name.
 | ||||
| /* Get the system from it's name. */ | ||||
| static StarSystem* system_get(const char* sysname) { | ||||
|   int i; | ||||
| 
 | ||||
| @ -484,7 +484,7 @@ static StarSystem* system_get(const char* sysname) { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| // Get the name of a system from a planetname.
 | ||||
| /* Get the name of a system from a planetname. */ | ||||
| char* planet_getSystem(char* planetname) { | ||||
|   int i; | ||||
|   for(i = 0; i < spacename_nstack; i++) | ||||
| @ -495,7 +495,7 @@ char* planet_getSystem(char* planetname) { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| // Get a planet based on it's name.
 | ||||
| /* Get a planet based on it's name. */ | ||||
| Planet* planet_get(char* planetname) { | ||||
|   int i; | ||||
|   char* sys; | ||||
| @ -511,31 +511,31 @@ Planet* planet_get(char* planetname) { | ||||
|   return NULL; | ||||
| } | ||||
| 
 | ||||
| // Basically used for spawning fleets.
 | ||||
| /* Basically used for spawning fleets. */ | ||||
| void space_update(const double dt) { | ||||
|   unsigned int t; | ||||
|   int i, j, f; | ||||
| 
 | ||||
|   (void)dt; // Don't need it right now.
 | ||||
|   (void)dt; /* Don't need it right now. */ | ||||
| 
 | ||||
|   if(cur_system == NULL) return; // Can't update a null system.
 | ||||
|   if(cur_system == NULL) return; /* Can't update a null system. */ | ||||
| 
 | ||||
|   t = SDL_GetTicks(); | ||||
| 
 | ||||
|   if(cur_system->nfleets == 0) | ||||
|     // Please stop checking that there are no fleets.
 | ||||
|     /* Please stop checking that there are no fleets. */ | ||||
|     spawn_timer = t + 300000; | ||||
| 
 | ||||
|   if(spawn_timer < t) { | ||||
|     // Time to possibly spawn.
 | ||||
|     /* Time to possibly spawn. */ | ||||
| 
 | ||||
|     // Spawn chance is based on overall percentage.
 | ||||
|     /* Spawn chance is based on overall percentage. */ | ||||
|     f = RNG(0, 100*cur_system->nfleets); | ||||
|     j = 0; | ||||
|     for(i = 0; i < cur_system->nfleets; i++) { | ||||
|       j += cur_system->fleets[i].chance; | ||||
|       if(f < j) { | ||||
|         // Add one fleet.
 | ||||
|         /* Add one fleet. */ | ||||
|         space_addFleet(cur_system->fleets[i].fleet); | ||||
|         break; | ||||
|       } | ||||
| @ -544,13 +544,13 @@ void space_update(const double dt) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Crate a fleet.
 | ||||
| /* Crate a fleet. */ | ||||
| static void space_addFleet(Fleet* fleet) { | ||||
|   int i; | ||||
|   double a; | ||||
|   Vec2 vv, vp, vn; | ||||
| 
 | ||||
|   // Simulate them coming from hyperspace.
 | ||||
|   /* Simulate them coming from hyperspace. */ | ||||
|   vect_pset(&vp, RNG(MIN_HYPERSPACE_DIST, MIN_HYPERSPACE_DIST*1.5), | ||||
|             RNG(0, 360)*M_PI/180.); | ||||
|   vectnull(&vn); | ||||
| @ -574,16 +574,16 @@ static void space_addFleet(Fleet* fleet) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Init the system.
 | ||||
| /* Init the system. */ | ||||
| void space_init(const char* sysname) { | ||||
|   char* lt; | ||||
|   int i; | ||||
| 
 | ||||
|   // Cleanup some stuff.
 | ||||
|   player_clear(); // Clears targets.
 | ||||
|   pilots_clean(); // Destroy all the current pilots, exept player.
 | ||||
|   weapon_clear(); // Get rid of all the weapons.
 | ||||
|   spfx_clear();  // Remove of explosions.
 | ||||
|   /* Cleanup some stuff. */ | ||||
|   player_clear(); /* Clears targets. */ | ||||
|   pilots_clean(); /* Destroy all the current pilots, exept player. */ | ||||
|   weapon_clear(); /* Get rid of all the weapons. */ | ||||
|   spfx_clear();  /* Remove of explosions. */ | ||||
| 
 | ||||
|   if((sysname == NULL) && (cur_system == NULL)) | ||||
|     ERR("Cannot reinit system if there is no system previously loaded"); | ||||
| @ -598,26 +598,26 @@ void space_init(const char* sysname) { | ||||
|     player_message("Entering System %s on %s", sysname, lt); | ||||
|     free(lt); | ||||
| 
 | ||||
|     // Set up stars.
 | ||||
|     /* Set up stars. */ | ||||
|     nstars = (cur_system->stars*SCREEN_W*SCREEN_H+STAR_BUF*STAR_BUF)/(800*640); | ||||
|     if(mstars < nstars) | ||||
|       stars = realloc(stars, sizeof(Star)*nstars); // should realloc not malloc.
 | ||||
|       stars = realloc(stars, sizeof(Star)*nstars); /* should realloc not malloc. */ | ||||
|     for(i = 0; i < nstars; i++) { | ||||
|       stars[i].brightness = (double)RNG(50, 200)/256.; | ||||
|       stars[i].x = (double)RNG(-STAR_BUF, SCREEN_W + STAR_BUF); | ||||
|       stars[i].y = (double)RNG(-STAR_BUF, SCREEN_H + STAR_BUF); | ||||
|     } | ||||
|   } | ||||
|   // Set up fleets -> pilots.
 | ||||
|   /* Set up fleets -> pilots. */ | ||||
|   for(i = 0; i < cur_system->nfleets; i++) | ||||
|     if(RNG(0,100) <= (cur_system->fleets[i].chance/2)) // Fleet check (50% chance).
 | ||||
|     if(RNG(0,100) <= (cur_system->fleets[i].chance/2)) /* Fleet check (50% chance). */ | ||||
|       space_addFleet(cur_system->fleets[i].fleet); | ||||
| 
 | ||||
|   // Start the spawn timer.
 | ||||
|   /* Start the spawn timer. */ | ||||
|   spawn_timer = SDL_GetTicks() + 120000./(float)(cur_system->nfleets+1); | ||||
| } | ||||
| 
 | ||||
| // Load the planets of name 'name'.
 | ||||
| /* Load the planets of name 'name'. */ | ||||
| static Planet* planet_pull(const char* name) { | ||||
|   int i; | ||||
| 
 | ||||
| @ -640,7 +640,7 @@ static Planet* planet_pull(const char* name) { | ||||
|     return NULL; | ||||
|   } | ||||
| 
 | ||||
|   node = node->xmlChildrenNode; // First system node.
 | ||||
|   node = node->xmlChildrenNode; /* First system node. */ | ||||
|   if(node == NULL) { | ||||
|     ERR("Malformed "PLANET_DATA" file: does not contain elements"); | ||||
|     return NULL; | ||||
| @ -649,7 +649,7 @@ static Planet* planet_pull(const char* name) { | ||||
|   do { | ||||
|     if(xml_isNode(node, XML_PLANET_TAG)) { | ||||
|       tstr = xml_nodeProp(node, "name"); | ||||
|       if(strcmp(tstr, name)==0) { // Found.
 | ||||
|       if(strcmp(tstr, name)==0) { /* Found. */ | ||||
|         tmp = CALLOC_L(Planet); | ||||
|         tmp->name = tstr; | ||||
| 
 | ||||
| @ -660,13 +660,13 @@ static Planet* planet_pull(const char* name) { | ||||
|             cur = node->children; | ||||
|             do { | ||||
|               if(xml_isNode(cur, "space")) { | ||||
|                 // Load space gfx.
 | ||||
|                 /* Load space gfx. */ | ||||
|                 snprintf(str, strlen(xml_get(cur))+sizeof(PLANET_GFX_SPACE), | ||||
|                          PLANET_GFX_SPACE"%s", xml_get(cur)); | ||||
|                 tmp->gfx_space = gl_newImage(str); | ||||
|               } | ||||
|               else if(xml_isNode(cur, "exterior")) { | ||||
|                 // Load land gfx.
 | ||||
|                 /* Load land gfx. */ | ||||
|                 snprintf(str, strlen(xml_get(cur))+sizeof(PLANET_GFX_EXTERIOR), | ||||
|                          PLANET_GFX_EXTERIOR"%s", xml_get(cur)); | ||||
|                 tmp->gfx_exterior = gl_newImage(str); | ||||
| @ -738,7 +738,7 @@ static Planet* planet_pull(const char* name) { | ||||
|         } while(xml_nextNode(node)); | ||||
|         break; | ||||
|       } else | ||||
|         free(tstr); // xmlGetProp mallocs the string.
 | ||||
|         free(tstr); /* xmlGetProp mallocs the string. */ | ||||
|     } | ||||
|   } while(xml_nextNode(node)); | ||||
| 
 | ||||
| @ -746,7 +746,7 @@ static Planet* planet_pull(const char* name) { | ||||
|   free(buf); | ||||
|   xmlCleanupParser(); | ||||
| 
 | ||||
|   // Check elements.
 | ||||
|   /* Check elements. */ | ||||
|   if(tmp) { | ||||
| #define MELEMENT(o,s) if(o) WARN("Planet '%s' missing '"s"' element", tmp->name) | ||||
|     MELEMENT(tmp->gfx_space==NULL,         "GFX_space"); | ||||
| @ -775,8 +775,8 @@ static Planet* planet_pull(const char* name) { | ||||
|   return tmp; | ||||
| } | ||||
| 
 | ||||
| // Parse node 'parent' which should be the node of a system.
 | ||||
| // Return the StarSystem fully loaded.
 | ||||
| /* Parse node 'parent' which should be the node of a system. */ | ||||
| /* Return the StarSystem fully loaded. */ | ||||
| static StarSystem* system_parse(const xmlNodePtr parent) { | ||||
|   Planet* planet = NULL; | ||||
|   SystemFleet* fleet = NULL; | ||||
| @ -786,12 +786,12 @@ static StarSystem* system_parse(const xmlNodePtr parent) { | ||||
| 
 | ||||
|   uint32_t flags; | ||||
| 
 | ||||
|   tmp->name = xml_nodeProp(parent, "name"); // Already mallocs.
 | ||||
|   tmp->name = xml_nodeProp(parent, "name"); /* Already mallocs. */ | ||||
| 
 | ||||
|   node = parent->xmlChildrenNode; | ||||
| 
 | ||||
|   do { | ||||
|     // Load all the things!
 | ||||
|     /* Load all the things! */ | ||||
|     if(xml_isNode(node, "pos")) { | ||||
|       cur = node->children; | ||||
|       do { | ||||
| @ -808,7 +808,7 @@ static StarSystem* system_parse(const xmlNodePtr parent) { | ||||
|     else if(xml_isNode(node, "general")) { | ||||
|       cur = node->children; | ||||
|       do { | ||||
|         if(xml_isNode(cur, "stars")) // Non-zero.
 | ||||
|         if(xml_isNode(cur, "stars")) /* Non-zero. */ | ||||
|           tmp->stars = xml_getInt(cur); | ||||
|         else if(xml_isNode(cur, "asteroids")) { | ||||
|           flags |= FLAG_ASTEROIDSSET; | ||||
| @ -820,18 +820,18 @@ static StarSystem* system_parse(const xmlNodePtr parent) { | ||||
|         } | ||||
|       }while(xml_nextNode(cur)); | ||||
|     } | ||||
|     // Load all the planets.
 | ||||
|     /* Load all the planets. */ | ||||
|     else if(xml_isNode(node, "planets")) { | ||||
|       cur = node->children; | ||||
|       do { | ||||
|         if(cur && xml_isNode(cur, "planet")) { | ||||
|           // Add planet to system.
 | ||||
|           nplanets++; // Increase planet counter.
 | ||||
|           /* Add planet to system. */ | ||||
|           nplanets++; /* Increase planet counter. */ | ||||
|           planet = planet_pull(xml_get(cur)); | ||||
|           tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets)); | ||||
|           memcpy(tmp->planets+(tmp->nplanets-1), planet, sizeof(Planet)); | ||||
| 
 | ||||
|           // Add planet <-> star system to name stack.
 | ||||
|           /* Add planet <-> star system to name stack. */ | ||||
|           spacename_nstack++; | ||||
|           planetname_stack = realloc(planetname_stack, | ||||
|               sizeof(char*)*spacename_nstack); | ||||
| @ -843,7 +843,7 @@ static StarSystem* system_parse(const xmlNodePtr parent) { | ||||
|         } | ||||
|       } while(xml_nextNode(cur)); | ||||
|     } | ||||
|     // Load all the fleets.
 | ||||
|     /* Load all the fleets. */ | ||||
|     else if(xml_isNode(node, "fleets")) { | ||||
|       cur = node->children; | ||||
|       do { | ||||
| @ -853,12 +853,12 @@ static StarSystem* system_parse(const xmlNodePtr parent) { | ||||
|           if(fleet->fleet == NULL) | ||||
|             WARN("Fleet %s for Star System %s not found", xml_get(cur), tmp->name); | ||||
| 
 | ||||
|           ptrc = xml_nodeProp(cur, "chance"); // Malloc ptrc.
 | ||||
|           ptrc = xml_nodeProp(cur, "chance"); /* Malloc ptrc. */ | ||||
|           fleet->chance = atoi(ptrc); | ||||
|           if(fleet->chance == 0) | ||||
|             WARN("Fleet %s for Star System %s has 0%% chance to appear", | ||||
|                  fleet->fleet->name, tmp->name); | ||||
|           if(ptrc) free(ptrc); // Free the ptrc.
 | ||||
|           if(ptrc) free(ptrc); /* Free the ptrc. */ | ||||
| 
 | ||||
|           tmp->fleets = realloc(tmp->fleets, sizeof(SystemFleet)*(++tmp->nfleets)); | ||||
|           memcpy(tmp->fleets+(tmp->nfleets-1), fleet, sizeof(SystemFleet)); | ||||
| @ -868,30 +868,30 @@ static StarSystem* system_parse(const xmlNodePtr parent) { | ||||
|     } | ||||
|   } while(xml_nextNode(node)); | ||||
| 
 | ||||
|   // Check elements.
 | ||||
|   /* Check elements. */ | ||||
| #define MELEMENT(o,s) if((o) == 0) WARN("Star System '%s' missing '"s"' element", tmp->name) | ||||
|   MELEMENT(flags&FLAG_XSET, "x"); | ||||
|   MELEMENT(flags&FLAG_YSET, "y"); | ||||
|   MELEMENT(tmp->stars, "stars"); | ||||
|   MELEMENT(flags&FLAG_ASTEROIDSSET, "asteroids"); // Can be 0.
 | ||||
|   MELEMENT(flags&FLAG_ASTEROIDSSET, "asteroids"); /* Can be 0. */ | ||||
|   MELEMENT(flags&FLAG_INTEFERENCESET, "inteference"); | ||||
| #undef MELEMENT | ||||
| 
 | ||||
|   // Post processing.
 | ||||
|   /* Post processing. */ | ||||
|   if(tmp->nplanets > 0) | ||||
|     // TODO: Make dependant on overall planet faction.
 | ||||
|     /* TODO: Make dependant on overall planet faction. */ | ||||
|     tmp->faction = tmp->planets[0].faction; | ||||
|   return tmp; | ||||
| } | ||||
| 
 | ||||
| // Load the jumps into a system.
 | ||||
| /* Load the jumps into a system. */ | ||||
| static void system_parseJumps(const xmlNodePtr parent) { | ||||
|   int i; | ||||
|   StarSystem* system; | ||||
|   char* name; | ||||
|   xmlNodePtr cur, node; | ||||
| 
 | ||||
|   name = xml_nodeProp(parent, "name"); // Already mallocs.
 | ||||
|   name = xml_nodeProp(parent, "name"); /* Already mallocs. */ | ||||
|   for(i = 0; i < systems_nstack; i++) | ||||
|     if(strcmp(systems_stack[i].name, name)==0) { | ||||
|       system = &systems_stack[i]; | ||||
| @ -899,12 +899,12 @@ static void system_parseJumps(const xmlNodePtr parent) { | ||||
|     } | ||||
|   if(i == systems_nstack) | ||||
|     WARN("System '%s' was not found in the stack for some reason", name); | ||||
|   free(name); // No need for it now.
 | ||||
|   free(name); /* No need for it now. */ | ||||
| 
 | ||||
|   node = parent->xmlChildrenNode; | ||||
| 
 | ||||
|   do { | ||||
|     // Load the data.
 | ||||
|     /* Load the data. */ | ||||
|     if(xml_isNode(node, "jumps")) { | ||||
|       cur = node->children; | ||||
|       do { | ||||
| @ -924,8 +924,8 @@ static void system_parseJumps(const xmlNodePtr parent) { | ||||
|   } while(xml_nextNode(node)); | ||||
| } | ||||
| 
 | ||||
| // Load the ENTIRE universe into RAM. -- WOAH!
 | ||||
| // -- Used a two system pass to first load the star systems_stack and then set jump routes.
 | ||||
| /* Load the ENTIRE universe into RAM. -- WOAH! */ | ||||
| /* -- Used a two system pass to first load the star systems_stack and then set jump routes. */ | ||||
| int space_load(void) { | ||||
|   uint32_t bufsize; | ||||
|   char* buf = pack_readfile(DATA, SYSTEM_DATA, &bufsize); | ||||
| @ -940,12 +940,12 @@ int space_load(void) { | ||||
|     ERR("Malformed "SYSTEM_DATA" file: missing root element '"XML_SYSTEM_ID"'"); | ||||
|     return -1; | ||||
|   } | ||||
|   node = node->xmlChildrenNode; // First system node.
 | ||||
|   node = node->xmlChildrenNode; /* First system node. */ | ||||
|   if(node == NULL) { | ||||
|     ERR("Malformed "SYSTEM_DATA" file: does not contain elements"); | ||||
|     return -1; | ||||
|   } | ||||
|   // Fist pass - Load all the star systems_stack.
 | ||||
|   /* Fist pass - Load all the star systems_stack. */ | ||||
|   do { | ||||
|     if(xml_isNode(node, XML_SYSTEM_TAG)) { | ||||
|       tmp = system_parse(node); | ||||
| @ -955,14 +955,14 @@ int space_load(void) { | ||||
|     } | ||||
|   } while(xml_nextNode(node)); | ||||
| 
 | ||||
|   // Second pass - Load all the jump routes.
 | ||||
|   /* Second pass - Load all the jump routes. */ | ||||
|   node = doc->xmlChildrenNode->xmlChildrenNode; | ||||
|   do { | ||||
|     if(xml_isNode(node, XML_SYSTEM_TAG)) | ||||
|       system_parseJumps(node); // Automatically load the jumps into the system.
 | ||||
|       system_parseJumps(node); /* Automatically load the jumps into the system. */ | ||||
|   } while(xml_nextNode(node)); | ||||
| 
 | ||||
|   // Cleanup.
 | ||||
|   /* Cleanup. */ | ||||
|   xmlFreeDoc(doc); | ||||
|   free(buf); | ||||
|   xmlCleanupParser(); | ||||
| @ -974,29 +974,29 @@ int space_load(void) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Render the system. -- Just playing god now.
 | ||||
| /* Render the system. -- Just playing god now. */ | ||||
| void space_render(double dt) { | ||||
|   int i; | ||||
|   unsigned int t, timer; | ||||
|   double x, y, m, b; | ||||
| 
 | ||||
|   glMatrixMode(GL_MODELVIEW); | ||||
|   glPushMatrix(); // Translation matrix.
 | ||||
|   glPushMatrix(); /* Translation matrix. */ | ||||
|   glTranslated(-(double)SCREEN_W/2., -(double)SCREEN_H/2., 0); | ||||
| 
 | ||||
|   t = SDL_GetTicks(); | ||||
|   if(!player_isFlag(PLAYER_DESTROYED) && !player_isFlag(PLAYER_CREATING) && | ||||
|      pilot_isFlag(player, PILOT_HYPERSPACE) && // Hyperspace fancy effect.
 | ||||
|      pilot_isFlag(player, PILOT_HYPERSPACE) && /* Hyperspace fancy effect. */ | ||||
|      !paused && (player->ptimer-HYPERSPACE_STARS_BLUR < t)) { | ||||
| 
 | ||||
|     timer = player->ptimer - HYPERSPACE_STARS_BLUR; | ||||
| 
 | ||||
|     // Fancy hyperspace effects.
 | ||||
|     /* Fancy hyperspace effects. */ | ||||
|     glShadeModel(GL_SMOOTH); | ||||
| 
 | ||||
|     glBegin(GL_LINES); | ||||
| 
 | ||||
|     // Lines will be based on velocity.
 | ||||
|     /* Lines will be based on velocity. */ | ||||
|     m = HYPERSPACE_STARS_LENGTH * (double)(t-timer) / (HYPERSPACE_STARS_BLUR); | ||||
|     x = m*cos(VANGLE(player->solid->vel)+M_PI); | ||||
|     y = m*sin(VANGLE(player->solid->vel)+M_PI); | ||||
| @ -1012,28 +1012,28 @@ void space_render(double dt) { | ||||
|     glShadeModel(GL_FLAT); | ||||
| 
 | ||||
|   } else { | ||||
|     glBegin(GL_POINTS); // Normal rendering.
 | ||||
|     glBegin(GL_POINTS); /* Normal rendering. */ | ||||
|     if(!paused && !player_isFlag(PLAYER_DESTROYED) && | ||||
|         !player_isFlag(PLAYER_CREATING)) { // Update position.
 | ||||
|         !player_isFlag(PLAYER_CREATING)) { /* Update position. */ | ||||
|       for(i = 0; i < nstars; i++) { | ||||
|         b = 13.-10.*stars[i].brightness; | ||||
|         stars[i].x -= player->solid->vel.x/b*dt; | ||||
|         stars[i].y -= player->solid->vel.y/b*dt; | ||||
|          | ||||
|         // Check for boundaries.
 | ||||
|         /* Check for boundaries. */ | ||||
|         if(stars[i].x > SCREEN_W + STAR_BUF) stars[i].x = -STAR_BUF; | ||||
|         else if(stars[i].x < -STAR_BUF) stars[i].x = SCREEN_W + STAR_BUF; | ||||
|         if(stars[i].y > SCREEN_H + STAR_BUF) stars[i].y = -STAR_BUF; | ||||
|         else if(stars[i].y < -STAR_BUF) stars[i].y = SCREEN_H + STAR_BUF; | ||||
| 
 | ||||
|         // Render.
 | ||||
|         /* Render. */ | ||||
|         if((stars[i].x < SCREEN_W) && (stars[i].x > 0) && | ||||
|             (stars[i].y < SCREEN_H) && (stars[i].y > 0)) { | ||||
|           glColor4d(1., 1., 1., stars[i].brightness); | ||||
|           glVertex2d(stars[i].x, stars[i].y); | ||||
|         } | ||||
|       } | ||||
|     } else { // Just render.
 | ||||
|     } else { /* Just render. */ | ||||
|       for(i = 0; i < nstars; i++) { | ||||
|         if((stars[i].x < SCREEN_W) && (stars[i].x > 0) && | ||||
|             (stars[i].y < SCREEN_H) && (stars[i].y > 0)) { | ||||
| @ -1042,12 +1042,12 @@ void space_render(double dt) { | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     glEnd(); // GL_POINTS
 | ||||
|     glEnd(); /* GL_POINTS */ | ||||
|   } | ||||
|   glPopMatrix(); // Translation matrix.
 | ||||
|   glPopMatrix(); /* Translation matrix. */ | ||||
| } | ||||
| 
 | ||||
| // Render the planets.
 | ||||
| /* Render the planets. */ | ||||
| void planets_render(void) { | ||||
|   if(cur_system == NULL) return; | ||||
| 
 | ||||
| @ -1057,13 +1057,13 @@ void planets_render(void) { | ||||
|                   cur_system->planets[i].pos.x, cur_system->planets[i].pos.y, 0, 0, NULL); | ||||
| } | ||||
| 
 | ||||
| // Clean up the system.
 | ||||
| /* Clean up the system. */ | ||||
| void space_exit(void) { | ||||
|   int i,j; | ||||
|    | ||||
|   // Free the names.
 | ||||
|   //if(planetname_stack) free(planetname_stack);
 | ||||
|   //if(systemname_stack) free(systemname_stack);
 | ||||
|   /* Free the names. */ | ||||
|   /*if(planetname_stack) free(planetname_stack); */ | ||||
|   /*if(systemname_stack) free(systemname_stack); */ | ||||
|   if(planetname_stack) { | ||||
|   	 free(planetname_stack); | ||||
|   	 planetname_stack = NULL; | ||||
| @ -1074,7 +1074,7 @@ void space_exit(void) { | ||||
|   } | ||||
|   spacename_nstack = 0; | ||||
| 
 | ||||
|   // Free the systems.
 | ||||
|   /* Free the systems. */ | ||||
|   for(i = 0; i < systems_nstack; i++) { | ||||
|     free(systems_stack[i].name); | ||||
|     if(systems_stack[i].fleets) | ||||
| @ -1082,7 +1082,7 @@ void space_exit(void) { | ||||
|     if(systems_stack[i].jumps) | ||||
|       free(systems_stack[i].jumps); | ||||
| 
 | ||||
|     // Free some planets.
 | ||||
|     /* Free some planets. */ | ||||
|     for(j = 0; j < systems_stack[i].nplanets; j++) { | ||||
|       free(systems_stack[i].planets[j].name); | ||||
|       if(systems_stack[i].planets[j].description) | ||||
| @ -1090,13 +1090,13 @@ void space_exit(void) { | ||||
|       if(systems_stack[i].planets[j].bar_description) | ||||
|         free(systems_stack[i].planets[j].bar_description); | ||||
| 
 | ||||
|       // Graphics.
 | ||||
|       /* Graphics. */ | ||||
|       if(systems_stack[i].planets[j].gfx_space) | ||||
|         gl_freeTexture(systems_stack[i].planets[j].gfx_space); | ||||
|       if(systems_stack[i].planets[j].gfx_exterior) | ||||
|         gl_freeTexture(systems_stack[i].planets[j].gfx_exterior); | ||||
| 
 | ||||
|       // Commodities.
 | ||||
|       /* Commodities. */ | ||||
|       free(systems_stack[i].planets[j].commodities); | ||||
|     } | ||||
|     free(systems_stack[i].planets); | ||||
| @ -1105,7 +1105,7 @@ void space_exit(void) { | ||||
|   systems_stack   = NULL; | ||||
|   systems_nstack  = 0; | ||||
| 
 | ||||
|   // Stars must be set free too.
 | ||||
|   /* Stars must be set free too. */ | ||||
|   if(stars) free(stars); | ||||
|   stars   = NULL; | ||||
|   nstars  = 0; | ||||
|  | ||||
							
								
								
									
										128
									
								
								src/space.h
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								src/space.h
									
									
									
									
									
								
							| @ -9,110 +9,110 @@ | ||||
| 
 | ||||
| #define PLANET_TECH_MAX   8 | ||||
| 
 | ||||
| // Planet types. I didn't take them from Star Trek, I promise.
 | ||||
| /* Planet types. I didn't take them from Star Trek, I promise. */ | ||||
| typedef enum PlanetClass_ { | ||||
|   PLANET_CLASS_NULL = 0, | ||||
|   PLANET_CLASS_A,   // Geothermal.
 | ||||
|   PLANET_CLASS_B,   // Geomorteus.
 | ||||
|   PLANET_CLASS_C,   // Geoinactive.
 | ||||
|   PLANET_CLASS_D,   // Asteroid/Moon.
 | ||||
|   PLANET_CLASS_E,   // Geoplastic.
 | ||||
|   PLANET_CLASS_F,   // Geometallic.
 | ||||
|   PLANET_CLASS_G,   // GroCrystaline.
 | ||||
|   PLANET_CLASS_H,   // Desert.
 | ||||
|   PLANET_CLASS_I,   // Gas Supergiant.
 | ||||
|   PLANET_CLASS_J,   // Gas Giant.
 | ||||
|   PLANET_CLASS_K,   // Adaptable.
 | ||||
|   PLANET_CLASS_L,   // Marginal.
 | ||||
|   PLANET_CLASS_M,   // Terrestrial.
 | ||||
|   PLANET_CLASS_N,   // Reducing.
 | ||||
|   PLANET_CLASS_O,   // Pelagic.
 | ||||
|   PLANET_CLASS_P,   // Glaciated.
 | ||||
|   PLANET_CLASS_Q,   // Variable.
 | ||||
|   PLANET_CLASS_R,   // Rogue.
 | ||||
|   PLANET_CLASS_S,   // Ultragiant.
 | ||||
|   PLANET_CLASS_T,   // Ultragiant.
 | ||||
|   PLANET_CLASS_X,   // Demon.
 | ||||
|   PLANET_CLASS_Y,   // Demon.
 | ||||
|   PLANET_CLASS_Z,   // Demon.
 | ||||
|   STATION_CLASS_A,  // Civilian station.
 | ||||
|   STATION_CLASS_B,  // Military station.
 | ||||
|   STATION_CLASS_C,  // Interfactional station.
 | ||||
|   STATION_CLASS_D,  // Robotoc station.
 | ||||
|   PLANET_CLASS_A,   /* Geothermal. */ | ||||
|   PLANET_CLASS_B,   /* Geomorteus. */ | ||||
|   PLANET_CLASS_C,   /* Geoinactive. */ | ||||
|   PLANET_CLASS_D,   /* Asteroid/Moon. */ | ||||
|   PLANET_CLASS_E,   /* Geoplastic. */ | ||||
|   PLANET_CLASS_F,   /* Geometallic. */ | ||||
|   PLANET_CLASS_G,   /* GroCrystaline. */ | ||||
|   PLANET_CLASS_H,   /* Desert. */ | ||||
|   PLANET_CLASS_I,   /* Gas Supergiant. */ | ||||
|   PLANET_CLASS_J,   /* Gas Giant. */ | ||||
|   PLANET_CLASS_K,   /* Adaptable. */ | ||||
|   PLANET_CLASS_L,   /* Marginal. */ | ||||
|   PLANET_CLASS_M,   /* Terrestrial. */ | ||||
|   PLANET_CLASS_N,   /* Reducing. */ | ||||
|   PLANET_CLASS_O,   /* Pelagic. */ | ||||
|   PLANET_CLASS_P,   /* Glaciated. */ | ||||
|   PLANET_CLASS_Q,   /* Variable. */ | ||||
|   PLANET_CLASS_R,   /* Rogue. */ | ||||
|   PLANET_CLASS_S,   /* Ultragiant. */ | ||||
|   PLANET_CLASS_T,   /* Ultragiant. */ | ||||
|   PLANET_CLASS_X,   /* Demon. */ | ||||
|   PLANET_CLASS_Y,   /* Demon. */ | ||||
|   PLANET_CLASS_Z,   /* Demon. */ | ||||
|   STATION_CLASS_A,  /* Civilian station. */ | ||||
|   STATION_CLASS_B,  /* Military station. */ | ||||
|   STATION_CLASS_C,  /* Interfactional station. */ | ||||
|   STATION_CLASS_D,  /* Robotoc station. */ | ||||
| } PlanetClass; | ||||
| 
 | ||||
| // Planet services.
 | ||||
| #define PLANET_SERVICE_LAND       (1<<0) // Can we land?
 | ||||
| #define PLANET_SERVICE_BASIC      (1<<1) // Refueling, spaceport bar, new.
 | ||||
| /* Planet services. */ | ||||
| #define PLANET_SERVICE_LAND       (1<<0) /* Can we land? */ | ||||
| #define PLANET_SERVICE_BASIC      (1<<1) /* Refueling, spaceport bar, new. */ | ||||
| #define PLANET_SERVICE_COMMODITY  (1<<2) | ||||
| #define PLANET_SERVICE_OUTFITS    (1<<3) | ||||
| #define PLANET_SERVICE_SHIPYARD   (1<<4) | ||||
| #define planet_hasService(p,s)    ((p)->services & s) | ||||
| 
 | ||||
| typedef struct Planet_ { | ||||
|   char* name;               // Planet name
 | ||||
|   Vec2 pos;                 // Position in star system.
 | ||||
|   char* name;               /* Planet name */ | ||||
|   Vec2 pos;                 /* Position in star system. */ | ||||
| 
 | ||||
|   PlanetClass class;        // Planet type.
 | ||||
|   int faction;              // Planet faction.
 | ||||
|   PlanetClass class;        /* Planet type. */ | ||||
|   int faction;              /* Planet faction. */ | ||||
| 
 | ||||
|   char* description;        // Planet description.
 | ||||
|   char* bar_description;    // Spaceport bar description.
 | ||||
|   unsigned int services;    // Offered services.
 | ||||
|   Commodity** commodities;  // Commodities sold.
 | ||||
|   int ncommodities;         // Amount in stock.
 | ||||
|   char* description;        /* Planet description. */ | ||||
|   char* bar_description;    /* Spaceport bar description. */ | ||||
|   unsigned int services;    /* Offered services. */ | ||||
|   Commodity** commodities;  /* Commodities sold. */ | ||||
|   int ncommodities;         /* Amount in stock. */ | ||||
| 
 | ||||
|   // tech[0] stores global tech level (everything that and below) while
 | ||||
|   // tech[1-PLANET_TECH_MAX] stores the unique tech levels.
 | ||||
|   /* tech[0] stores global tech level (everything that and below) while */ | ||||
|   /* tech[1-PLANET_TECH_MAX] stores the unique tech levels. */ | ||||
|   int tech[PLANET_TECH_MAX]; | ||||
| 
 | ||||
|   glTexture* gfx_space;     // Graphics in space.
 | ||||
|   glTexture* gfx_exterior;  // Graphics in the exterior.
 | ||||
|   glTexture* gfx_space;     /* Graphics in space. */ | ||||
|   glTexture* gfx_exterior;  /* Graphics in the exterior. */ | ||||
| } Planet; | ||||
| 
 | ||||
| // Star systems.
 | ||||
| /* Star systems. */ | ||||
| typedef struct SystemFleet_ { | ||||
|   Fleet* fleet;         // Fleet to appear.
 | ||||
|   int chance;           // Chance of fleet appearing in the system.
 | ||||
|   Fleet* fleet;         /* Fleet to appear. */ | ||||
|   int chance;           /* Chance of fleet appearing in the system. */ | ||||
| } SystemFleet; | ||||
| 
 | ||||
| typedef struct StarSystem_ { | ||||
|   char* name;           // Star system identifier.
 | ||||
|   Vec2 pos;             // Position.
 | ||||
|   int stars, asteroids; // Un numero!
 | ||||
|   double interference;  // Un uh.. Percentage.
 | ||||
|   char* name;           /* Star system identifier. */ | ||||
|   Vec2 pos;             /* Position. */ | ||||
|   int stars, asteroids; /* Un numero! */ | ||||
|   double interference;  /* Un uh.. Percentage. */ | ||||
| 
 | ||||
|   int faction;          // Overall faction.
 | ||||
|   int faction;          /* Overall faction. */ | ||||
| 
 | ||||
|   Planet* planets;      // Planets.
 | ||||
|   int nplanets;         // Total number of planets.
 | ||||
|   Planet* planets;      /* Planets. */ | ||||
|   int nplanets;         /* Total number of planets. */ | ||||
| 
 | ||||
|   SystemFleet* fleets;  // Fleets that can appear in the current system.
 | ||||
|   int nfleets;          // Total number of fleets.
 | ||||
|   SystemFleet* fleets;  /* Fleets that can appear in the current system. */ | ||||
|   int nfleets;          /* Total number of fleets. */ | ||||
| 
 | ||||
|   int* jumps;           // Adjacent star system index number.
 | ||||
|   int njumps;           // Number of adjacent jumps.
 | ||||
|   int* jumps;           /* Adjacent star system index number. */ | ||||
|   int njumps;           /* Number of adjacent jumps. */ | ||||
| } StarSystem; | ||||
| 
 | ||||
| extern StarSystem* cur_system; // Current star system.
 | ||||
| extern StarSystem* cur_system; /* Current star system. */ | ||||
| 
 | ||||
| // Load/Exit.
 | ||||
| /* Load/Exit. */ | ||||
| void space_init(const char* sysname); | ||||
| int space_load(void); | ||||
| void space_exit(void); | ||||
| 
 | ||||
| // Planet stuff.
 | ||||
| /* Planet stuff. */ | ||||
| char* planet_getSystem(char* planetname); | ||||
| Planet* planet_get(char* planetname); | ||||
| 
 | ||||
| // Render.
 | ||||
| /* Render. */ | ||||
| void space_render(double dt); | ||||
| void planets_render(void); | ||||
| 
 | ||||
| // Update.
 | ||||
| /* Update. */ | ||||
| void space_update(const double dt); | ||||
| 
 | ||||
| // Misc.
 | ||||
| /* Misc. */ | ||||
| StarSystem** system_getJumpPath(int* njumps, char* sysstart, char* sysend); | ||||
| int space_canHyperspace(Pilot* p); | ||||
| int space_hyperspace(Pilot* p); | ||||
|  | ||||
							
								
								
									
										62
									
								
								src/spfx.c
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								src/spfx.c
									
									
									
									
									
								
							| @ -9,38 +9,38 @@ | ||||
| #include "rng.h" | ||||
| #include "spfx.h" | ||||
| 
 | ||||
| #define SPFX_GFX "../gfx/spfx/" // Graphics location.
 | ||||
| #define SPFX_CHUNK 32           // Chunk to allocate when needed.
 | ||||
| #define SPFX_GFX "../gfx/spfx/" /* Graphics location. */ | ||||
| #define SPFX_CHUNK 32           /* Chunk to allocate when needed. */ | ||||
| 
 | ||||
| // Special hardcoded effects..
 | ||||
| /* Special hardcoded effects.. */ | ||||
| 
 | ||||
| // Shake, AKA RUMBLE!
 | ||||
| /* Shake, AKA RUMBLE! */ | ||||
| static double shake_rad = 0.; | ||||
| static Vec2 shake_pos = { .x = 0., .y = 0. }; | ||||
| static Vec2 shake_vel = { .x = 0., .y = 0. }; | ||||
| static int shake_off = 1; | ||||
| 
 | ||||
| // Generic SPFX template.
 | ||||
| /* Generic SPFX template. */ | ||||
| typedef struct SPFX_Base_ { | ||||
|   char* name; | ||||
| 
 | ||||
|   int anim; // Total duration in ms.
 | ||||
|   glTexture* gfx; // Will use each sprite as a frame.
 | ||||
|   int anim; /* Total duration in ms. */ | ||||
|   glTexture* gfx; /* Will use each sprite as a frame. */ | ||||
| } SPFX_Base; | ||||
| 
 | ||||
| static SPFX_Base* spfx_effects = NULL; | ||||
| static int spfx_neffects = 0; | ||||
| 
 | ||||
| typedef struct SPFX_ { | ||||
|   Vec2 pos, vel;  // They don't accelerate.
 | ||||
|   Vec2 pos, vel;  /* They don't accelerate. */ | ||||
| 
 | ||||
|   int lastframe;  // Need when pausing.
 | ||||
|   int effect;   // Actual effect.
 | ||||
|   unsigned int t; // Start.
 | ||||
|   int lastframe;  /* Need when pausing. */ | ||||
|   int effect;   /* Actual effect. */ | ||||
|   unsigned int t; /* Start. */ | ||||
| } SPFX; | ||||
| 
 | ||||
| // Front stack is for effects on player.
 | ||||
| // Back is for everything else.
 | ||||
| /* Front stack is for effects on player. */ | ||||
| /* Back is for everything else. */ | ||||
| static SPFX*  spfx_stack_front   = NULL; | ||||
| static int   spfx_nstack_front  = 0; | ||||
| static int   spfx_mstack_front  = 0; | ||||
| @ -56,7 +56,7 @@ static void spfx_pause_layer(SPFX* layer, int nlayer); | ||||
| static void spfx_unpause_layer(SPFX* layer, int nlayer); | ||||
| static void spfx_delay_layer(SPFX* layer, int nlayer, unsigned int delay); | ||||
| 
 | ||||
| // Load the SPFX_Base.
 | ||||
| /* Load the SPFX_Base. */ | ||||
| static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy) { | ||||
|   SPFX_Base* cur; | ||||
|   char buf[PATH_MAX]; | ||||
| @ -86,7 +86,7 @@ int spfx_get(char* name) { | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| // Load/Unload.
 | ||||
| /* Load/Unload. */ | ||||
| int spfx_load(void) { | ||||
|   spfx_base_load("ExpS", 400, "exps.png", 6, 5); | ||||
|   spfx_base_load("ExpM", 450, "expm.png", 6, 5); | ||||
| @ -97,7 +97,7 @@ int spfx_load(void) { | ||||
| void spfx_free(void) { | ||||
|   int i; | ||||
| 
 | ||||
|   // Get rid of all the particles and free the stacks.
 | ||||
|   /* Get rid of all the particles and free the stacks. */ | ||||
|   spfx_clear(); | ||||
|   if(spfx_stack_front) free(spfx_stack_front); | ||||
|   spfx_stack_front = NULL; | ||||
| @ -120,9 +120,9 @@ void spfx_add(int effect, | ||||
|   SPFX* cur_spfx; | ||||
| 
 | ||||
|   if(layer == SPFX_LAYER_FRONT) { | ||||
|     // Front layer.
 | ||||
|     /* Front layer. */ | ||||
|     if(spfx_mstack_front < spfx_nstack_front+1) { | ||||
|       // We need more memory.
 | ||||
|       /* We need more memory. */ | ||||
|       spfx_mstack_front += SPFX_CHUNK; | ||||
|       spfx_stack_front = realloc(spfx_stack_front, spfx_mstack_front*sizeof(SPFX)); | ||||
|     } | ||||
| @ -130,9 +130,9 @@ void spfx_add(int effect, | ||||
|     spfx_nstack_front++; | ||||
|   } | ||||
|   else if(layer == SPFX_LAYER_BACK) { | ||||
|     // Back layer.
 | ||||
|     /* Back layer. */ | ||||
|     if(spfx_mstack_back < spfx_nstack_back+1) { | ||||
|       // Need more memory.
 | ||||
|       /* Need more memory. */ | ||||
|       spfx_mstack_back += SPFX_CHUNK; | ||||
|       spfx_stack_back = realloc(spfx_stack_back, spfx_mstack_back*sizeof(SPFX)); | ||||
|     } | ||||
| @ -170,35 +170,35 @@ static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt) { | ||||
|   unsigned int t = SDL_GetTicks(); | ||||
| 
 | ||||
|   for(i = 0; i < *nlayer; i++) { | ||||
|     // Time to die!!!
 | ||||
|     /* Time to die!!! */ | ||||
|     if(t > (layer[i].t + spfx_effects[layer[i].effect].anim)) { | ||||
|       spfx_destroy(layer, nlayer, i); | ||||
|       i--; | ||||
|       continue; | ||||
|     } | ||||
|     // Mkay. Update it now.
 | ||||
|     /* Mkay. Update it now. */ | ||||
|     vect_cadd(&layer[i].pos, dt*VX(layer[i].vel), dt*VY(layer[i].vel)); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Prepare the rendering for special affects.
 | ||||
| /* Prepare the rendering for special affects. */ | ||||
| void spfx_start(double dt) { | ||||
|   GLdouble bx, by, x, y; | ||||
|   double inc; | ||||
| 
 | ||||
|   if(shake_off == 1) return; // Save the cycles.
 | ||||
|   if(shake_off == 1) return; /* Save the cycles. */ | ||||
|   bx = SCREEN_W / 2; | ||||
|   by = SCREEN_H / 2; | ||||
| 
 | ||||
|   if(!paused) { | ||||
|     inc = dt*100000.; | ||||
| 
 | ||||
|     // Calculate new position.
 | ||||
|     /* Calculate new position. */ | ||||
|     if(shake_rad > 0.01) { | ||||
|       vect_cadd(&shake_pos, shake_vel.x * inc, shake_vel.y * inc); | ||||
|        | ||||
|       if(VMOD(shake_pos) > shake_rad) { | ||||
|         // Change direction.
 | ||||
|         /* Change direction. */ | ||||
|         vect_pset(&shake_pos, shake_rad, VANGLE(shake_pos)); | ||||
|         vect_pset(&shake_vel, shake_rad, | ||||
|             -VANGLE(shake_pos) + (RNGF()-0.5) * M_PI); | ||||
| @ -220,7 +220,7 @@ void spfx_start(double dt) { | ||||
|   glOrtho(-bx+x, bx+x,  -by+y, by+y, -1., 1.); | ||||
| } | ||||
| 
 | ||||
| // Add ruuumble!!
 | ||||
| /* Add ruuumble!! */ | ||||
| void spfx_shake(double mod) { | ||||
|   shake_rad += mod; | ||||
|   if(shake_rad > SHAKE_MAX) shake_rad = SHAKE_MAX; | ||||
| @ -231,7 +231,7 @@ void spfx_shake(double mod) { | ||||
| 
 | ||||
| void spfx_cinematic(void) { | ||||
|   glMatrixMode(GL_MODELVIEW); | ||||
|   glPushMatrix(); // Translation matrix.
 | ||||
|   glPushMatrix(); /* Translation matrix. */ | ||||
|   glTranslated(-(double)SCREEN_W/2., -(double)SCREEN_H/2., 0); | ||||
|    | ||||
|   COLOUR(cBlack); | ||||
| @ -246,7 +246,7 @@ void spfx_cinematic(void) { | ||||
|     glVertex2d(0.,         SCREEN_H*0.8); | ||||
|   glEnd(); | ||||
| 
 | ||||
|   glPopMatrix(); // Translation matrix.
 | ||||
|   glPopMatrix(); /* Translation matrix. */ | ||||
| } | ||||
| 
 | ||||
| void spfx_render(const int layer) { | ||||
| @ -256,7 +256,7 @@ void spfx_render(const int layer) { | ||||
|   int sx, sy; | ||||
|   unsigned int t = SDL_GetTicks(); | ||||
| 
 | ||||
|   // Get the appropriate layer.
 | ||||
|   /* Get the appropriate layer. */ | ||||
|   switch(layer) { | ||||
|   case SPFX_LAYER_FRONT: | ||||
|     spfx_stack = spfx_stack_front; | ||||
| @ -273,7 +273,7 @@ void spfx_render(const int layer) { | ||||
|     sx = (int)effect->gfx->sx; | ||||
|     sy = (int)effect->gfx->sy; | ||||
| 
 | ||||
|     if(!paused) // Don't calculate frame if paused.
 | ||||
|     if(!paused) /* Don't calculate frame if paused. */ | ||||
|       spfx_stack[i].lastframe = sx * sy | ||||
|           * MIN(((double)(t - spfx_stack[i].t)/(double)effect->anim), 1.); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										16
									
								
								src/spfx.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/spfx.h
									
									
									
									
									
								
							| @ -5,33 +5,33 @@ | ||||
| #define SPFX_LAYER_FRONT  0 | ||||
| #define SPFX_LAYER_BACK  1 | ||||
| 
 | ||||
| #define SHAKE_DECAY 50. // Decay parameter.
 | ||||
| #define SHAKE_MAX   50.*SCREEN_W*SCREEN_H/1024./768. // Max parameter.
 | ||||
| #define SHAKE_DECAY 50. /* Decay parameter. */ | ||||
| #define SHAKE_MAX   50.*SCREEN_W*SCREEN_H/1024./768. /* Max parameter. */ | ||||
| 
 | ||||
| // Stack manipulation.
 | ||||
| /* Stack manipulation. */ | ||||
| int spfx_get(char* name); | ||||
| void spfx_add(const int effect, | ||||
|               const double px, const double py, | ||||
|               const double vx, const double vy, | ||||
|               const int layer); | ||||
| 
 | ||||
| // Stack mass manipulation functions.
 | ||||
| /* Stack mass manipulation functions. */ | ||||
| void spfx_update(const double dt); | ||||
| void spfx_render(const int layer); | ||||
| void spfx_clear(void); | ||||
| 
 | ||||
| // Get ready to rumble!
 | ||||
| /* Get ready to rumble! */ | ||||
| void spfx_start(double dt); | ||||
| void spfx_shake(double mod); | ||||
| 
 | ||||
| // Other effects.
 | ||||
| /* Other effects. */ | ||||
| void spfx_cinematic(void); | ||||
| 
 | ||||
| // Load/free.
 | ||||
| /* Load/free. */ | ||||
| int spfx_load(void); | ||||
| void spfx_free(void); | ||||
| 
 | ||||
| // Pause/Unpause routines.
 | ||||
| /* Pause/Unpause routines. */ | ||||
| void spfx_pause(void); | ||||
| void spfx_unpause(void); | ||||
| void spfx_delay(unsigned int delay); | ||||
|  | ||||
							
								
								
									
										450
									
								
								src/toolkit.c
									
									
									
									
									
								
							
							
						
						
									
										450
									
								
								src/toolkit.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -5,7 +5,7 @@ | ||||
| 
 | ||||
| extern int toolkit; | ||||
| 
 | ||||
| // Creation.
 | ||||
| /* Creation. */ | ||||
| unsigned int window_create(char* name, const int x, const int y, | ||||
|                            const int w, const int h); | ||||
| 
 | ||||
| @ -21,19 +21,19 @@ void window_addImage(const unsigned int wid, const int x, const int y, | ||||
|                      char* name, glTexture* image, int border); | ||||
| 
 | ||||
| void window_addList(const unsigned int wid, | ||||
|                     const int x, const int y, // Position.
 | ||||
|                     const int w, const int h, // Size.
 | ||||
|                     const int x, const int y, /* Position. */ | ||||
|                     const int w, const int h, /* Size. */ | ||||
|                     char* name, char** items, int nitems, int defitem, | ||||
|                     void(*call)(char*)); | ||||
| 
 | ||||
| void window_addRect(const unsigned int wid, | ||||
|                     const int x, const int y, // Position.
 | ||||
|                     const int w, const int h, // size.
 | ||||
|                     char* name, glColour* colour, int border); // Properties.
 | ||||
|                     const int x, const int y, /* Position. */ | ||||
|                     const int w, const int h, /* size. */ | ||||
|                     char* name, glColour* colour, int border); /* Properties. */ | ||||
| 
 | ||||
| void window_addCust(const unsigned int wid, | ||||
|                     const int x, const int y, // Position.
 | ||||
|                     const int w, const int h, // Size.
 | ||||
|                     const int x, const int y, /* Position. */ | ||||
|                     const int w, const int h, /* Size. */ | ||||
|                     char* name, const int border, | ||||
|                     void(*render) (double x, double y, double w, double h), | ||||
|                     void(*mouse) (SDL_Event* event, double x, double y)); | ||||
| @ -43,27 +43,27 @@ void window_addInput(const unsigned int wid, | ||||
|                      const int w, const int h, | ||||
|                      char* name, const int max, const int oneline); | ||||
| 
 | ||||
| // Popups and alerts.
 | ||||
| /* Popups and alerts. */ | ||||
| 
 | ||||
| // Does not pause execution.
 | ||||
| /* Does not pause execution. */ | ||||
| void  dialogue_alert(const char* fmt, ...); | ||||
| void  dialogue_msg(char* caption, const char* fmt, ...); | ||||
| // Yes = 1, No = 0.
 | ||||
| /* Yes = 1, No = 0. */ | ||||
| int   dialogue_YesNo(char* caption, const char* fmt, ...); | ||||
| char* dialogue_input(char* title, int min, int max, const char* fmt, ...); | ||||
| 
 | ||||
| // Modification.
 | ||||
| /* Modification. */ | ||||
| void window_setFptr(const unsigned int wid, void(*fptr)(char*)); | ||||
| // Text.
 | ||||
| /* Text. */ | ||||
| void window_modifyText(const unsigned int wid, char* name, char* newstring); | ||||
| // Button.
 | ||||
| /* Button. */ | ||||
| void window_disableButton(const unsigned int wid, char* name); | ||||
| void window_enableButton(const unsigned int wid, char* name); | ||||
| // Image.
 | ||||
| /* Image. */ | ||||
| void window_modifyImage(const unsigned int wid, char* name, glTexture* image); | ||||
| void window_imgColour(const unsigned int wid, char* name, glColour* colour); | ||||
| 
 | ||||
| // Get the window by name.
 | ||||
| /* Get the window by name. */ | ||||
| int window_exists(const char* wdwname); | ||||
| unsigned int window_get(const char* wdwname); | ||||
| char* toolkit_getList(const unsigned int wid, char* name); | ||||
| @ -71,18 +71,18 @@ int toolkit_getListPos(const unsigned int wid, char* name); | ||||
| glTexture* window_getImage(const unsigned int wid, char* name); | ||||
| char* window_getInput(const unsigned int wid, char* name); | ||||
| 
 | ||||
| // Destroy window.
 | ||||
| /* Destroy window. */ | ||||
| void window_destroy(const unsigned int wid); | ||||
| void window_destroyWidget(unsigned wid, const char* wgtname); | ||||
| 
 | ||||
| // Render.
 | ||||
| /* Render. */ | ||||
| void toolkit_render(void); | ||||
| 
 | ||||
| // Input.
 | ||||
| /* Input. */ | ||||
| int toolkit_input(SDL_Event* event); | ||||
| void toolkit_update(void); | ||||
| 
 | ||||
| // Init/Exit.
 | ||||
| /* Init/Exit. */ | ||||
| int toolkit_init(void); | ||||
| void toolkit_exit(void); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										142
									
								
								src/weapon.c
									
									
									
									
									
								
							
							
						
						
									
										142
									
								
								src/weapon.c
									
									
									
									
									
								
							| @ -15,50 +15,50 @@ | ||||
| 
 | ||||
| #define weapon_isSmart(w) (w->think) | ||||
| 
 | ||||
| #define VOICE_PRIORITY_BOLT   10  // Default.
 | ||||
| #define VOICE_PRIORITY_AMMO   8   // Higher.
 | ||||
| #define VOICE_PRIORITY_BEAM   6   // Even higher.
 | ||||
| #define VOICE_PRIORITY_BOLT   10  /* Default. */ | ||||
| #define VOICE_PRIORITY_AMMO   8   /* Higher. */ | ||||
| #define VOICE_PRIORITY_BEAM   6   /* Even higher. */ | ||||
| 
 | ||||
| #define WEAPON_CHUNK 32 | ||||
| 
 | ||||
| // Some stuff from pilot.
 | ||||
| /* Some stuff from pilot. */ | ||||
| extern Pilot** pilot_stack; | ||||
| extern int pilots; | ||||
| 
 | ||||
| // Player stuff.
 | ||||
| /* Player stuff. */ | ||||
| extern unsigned int player_target; | ||||
| 
 | ||||
| // Ai stuff.
 | ||||
| /* Ai stuff. */ | ||||
| extern void ai_attacked(Pilot* attacked, const unsigned int attacker); | ||||
| 
 | ||||
| typedef struct Weapon_ { | ||||
|   Solid* solid; // Actually has its own solid. :D
 | ||||
|   Solid* solid; /* Actually has its own solid. :D */ | ||||
| 
 | ||||
|   unsigned int parent; // The pilot that just shot at you!
 | ||||
|   unsigned int target; // Target to hit. Only used by seeking stuff.
 | ||||
|   const Outfit* outfit; // Related outfit that fired.
 | ||||
|   unsigned int timer; // Mainly used to see when the weapon was fired.
 | ||||
|   unsigned int parent; /* The pilot that just shot at you! */ | ||||
|   unsigned int target; /* Target to hit. Only used by seeking stuff. */ | ||||
|   const Outfit* outfit; /* Related outfit that fired. */ | ||||
|   unsigned int timer; /* Mainly used to see when the weapon was fired. */ | ||||
| 
 | ||||
|   alVoice* voice; // Virtual voise.
 | ||||
|   alVoice* voice; /* Virtual voise. */ | ||||
| 
 | ||||
|   // Update position and render.
 | ||||
|   void(*update)(struct Weapon_*, const double, WeaponLayer); // Position update and render.
 | ||||
|   void(*think)(struct Weapon_*, const double); // Some missiles need to be inteligent.a
 | ||||
|   /* Update position and render. */ | ||||
|   void(*update)(struct Weapon_*, const double, WeaponLayer); /* Position update and render. */ | ||||
|   void(*think)(struct Weapon_*, const double); /* Some missiles need to be inteligent.a */ | ||||
| 
 | ||||
|   double pid_last; | ||||
|   double pid_int; | ||||
| } Weapon; | ||||
| 
 | ||||
| // Behind Pilot layer.
 | ||||
| static Weapon** wbackLayer = NULL; // Behind pilots.
 | ||||
| static int nwbackLayer     = 0;    // Number of elements.
 | ||||
| static int mwbackLayer     = 0;    // Allocated memory size.
 | ||||
| // Behind player layer.
 | ||||
| static Weapon** wfrontLayer = NULL;  // Behind pilots.
 | ||||
| static int nwfrontLayer    = 0;    // Number of elements.
 | ||||
| static int mwfrontLayer    = 0;    // Allocated memory size.
 | ||||
| /* Behind Pilot layer. */ | ||||
| static Weapon** wbackLayer = NULL; /* Behind pilots. */ | ||||
| static int nwbackLayer     = 0;    /* Number of elements. */ | ||||
| static int mwbackLayer     = 0;    /* Allocated memory size. */ | ||||
| /* Behind player layer. */ | ||||
| static Weapon** wfrontLayer = NULL;  /* Behind pilots. */ | ||||
| static int nwfrontLayer    = 0;    /* Number of elements. */ | ||||
| static int mwfrontLayer    = 0;    /* Allocated memory size. */ | ||||
| 
 | ||||
| // Static.
 | ||||
| /* Static. */ | ||||
| static Weapon* weapon_create(const Outfit* outfit, const double dir, | ||||
|                              const Vec2* pos, const Vec2* vel, | ||||
|                              const unsigned int parent, | ||||
| @ -70,14 +70,14 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer); | ||||
| static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer); | ||||
| static void weapon_destroy(Weapon* w, WeaponLayer layer); | ||||
| static void weapon_free(Weapon* w); | ||||
| // Think.
 | ||||
| /* Think. */ | ||||
| static void think_seeker(Weapon* w, const double dt); | ||||
| static void think_smart(Weapon* w, const double dt); | ||||
| // Extern.
 | ||||
| /* Extern. */ | ||||
| void weapon_minimap(const double res, const double w, | ||||
|     const double h, const RadarShape shape); | ||||
| 
 | ||||
| // Draw the minimap weapons (player.c).
 | ||||
| /* Draw the minimap weapons (player.c). */ | ||||
| #define PIXEL(x,y) if((shape == RADAR_RECT && ABS(x) < w/2. && ABS(y)<h/2.) || \ | ||||
|   (shape == RADAR_CIRCLE && (((x)*(x)+(y)*(y))<rc))) glVertex2i((x),(y)) | ||||
| void weapon_minimap(const double res, const double w, | ||||
| @ -101,7 +101,7 @@ void weapon_minimap(const double res, const double w, | ||||
| } | ||||
| #undef PIXEL | ||||
| 
 | ||||
| // Pause/Unpause the weapon system.
 | ||||
| /* Pause/Unpause the weapon system. */ | ||||
| void weapons_pause(void) { | ||||
|   int i; | ||||
|   unsigned int t = SDL_GetTicks(); | ||||
| @ -129,10 +129,10 @@ void weapons_delay(unsigned int delay) { | ||||
|     wfrontLayer[i]->timer += delay; | ||||
| } | ||||
| 
 | ||||
| // Seeker brain, You get what you pay for. :)
 | ||||
| /* Seeker brain, You get what you pay for. :) */ | ||||
| static void think_seeker(Weapon* w, const double dt) { | ||||
|   double diff; | ||||
|   if(w->target == w->parent) return; // HEY! Self harm is not allowed.
 | ||||
|   if(w->target == w->parent) return; /* HEY! Self harm is not allowed. */ | ||||
| 
 | ||||
|   Pilot* p = pilot_get(w->target); | ||||
|   if(p == NULL) { | ||||
| @ -140,11 +140,11 @@ static void think_seeker(Weapon* w, const double dt) { | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   // Ammo isn't locked on yet..
 | ||||
|   /* Ammo isn't locked on yet.. */ | ||||
|   if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) { | ||||
|     diff = angle_diff(w->solid->dir, vect_angle(&w->solid->pos, &p->solid->pos)); | ||||
|     w->solid->dir_vel = 10 * diff * w->outfit->u.amm.turn; | ||||
|     // Face the target.
 | ||||
|     /* Face the target. */ | ||||
|     if(w->solid->dir_vel > w->outfit->u.amm.turn) | ||||
|       w->solid->dir_vel = w->outfit->u.amm.turn; | ||||
|     else if(w->solid->dir_vel < -w->outfit->u.amm.turn) | ||||
| @ -156,16 +156,16 @@ static void think_seeker(Weapon* w, const double dt) { | ||||
|   limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt); | ||||
| } | ||||
| 
 | ||||
| // ========================================================
 | ||||
| // Smart seeker brain. Much better at homing.
 | ||||
| // ========================================================
 | ||||
| /* ======================================================== */ | ||||
| /* Smart seeker brain. Much better at homing. */ | ||||
| /* ======================================================== */ | ||||
| static void think_smart(Weapon* w, const double dt) { | ||||
|   Vec2 sv, tv; | ||||
|   double t; | ||||
| 
 | ||||
|   if(w->target == w->parent) return; // No self shooting here.
 | ||||
|   if(w->target == w->parent) return; /* No self shooting here. */ | ||||
| 
 | ||||
|   Pilot* p = pilot_get(w->target); // No null pilots..
 | ||||
|   Pilot* p = pilot_get(w->target); /* No null pilots.. */ | ||||
| 
 | ||||
|   if(p == NULL) { | ||||
|     limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt); | ||||
| @ -181,7 +181,7 @@ static void think_smart(Weapon* w, const double dt) { | ||||
| 
 | ||||
|     t = -angle_diff(w->solid->dir, vect_angle(&tv, &sv)); | ||||
| 
 | ||||
|     w->solid->dir_vel = t * w->outfit->u.amm.turn; // Face the target.
 | ||||
|     w->solid->dir_vel = t * w->outfit->u.amm.turn; /* Face the target. */ | ||||
| 
 | ||||
|     if(w->solid->dir_vel > w->outfit->u.amm.turn) | ||||
|       w->solid->dir_vel = w->outfit->u.amm.turn; | ||||
| @ -195,13 +195,13 @@ static void think_smart(Weapon* w, const double dt) { | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| // Update all the weapon layers.
 | ||||
| /* Update all the weapon layers. */ | ||||
| void weapons_update(const double dt) { | ||||
|   weapons_updateLayer(dt, WEAPON_LAYER_BG); | ||||
|   weapons_updateLayer(dt, WEAPON_LAYER_FG); | ||||
| } | ||||
| 
 | ||||
| // Update all weapons in the layer.
 | ||||
| /* Update all weapons in the layer. */ | ||||
| static void weapons_updateLayer(const double dt, const WeaponLayer layer) { | ||||
|   Weapon** wlayer; | ||||
|   int* nlayer; | ||||
| @ -221,7 +221,7 @@ static void weapons_updateLayer(const double dt, const WeaponLayer layer) { | ||||
|   for(i = 0; i < (*nlayer); i++) { | ||||
|     w = wlayer[i]; | ||||
|     switch(wlayer[i]->outfit->type) { | ||||
|     // Most missiles behave the same.
 | ||||
|     /* Most missiles behave the same. */ | ||||
|     case OUTFIT_TYPE_MISSILE_SEEK_AMMO: | ||||
|     case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO: | ||||
|     case OUTFIT_TYPE_MISSILE_SWARM_AMMO: | ||||
| @ -233,7 +233,7 @@ static void weapons_updateLayer(const double dt, const WeaponLayer layer) { | ||||
|       } | ||||
|       break; | ||||
|     case OUTFIT_TYPE_BOLT: | ||||
|       // Check see if it exceeds distance.
 | ||||
|       /* Check see if it exceeds distance. */ | ||||
|     case OUTFIT_TYPE_TURRET_BOLT: | ||||
|       if(SDL_GetTicks() > wlayer[i]->timer) { | ||||
|         weapon_destroy(wlayer[i],layer); | ||||
| @ -244,12 +244,12 @@ static void weapons_updateLayer(const double dt, const WeaponLayer layer) { | ||||
|       break; | ||||
|     } | ||||
|     weapon_update(wlayer[i], dt, layer); | ||||
|     // If the weapon has been deleted we are going to have to hold back one.
 | ||||
|     /* If the weapon has been deleted we are going to have to hold back one. */ | ||||
|     if(w != wlayer[i]) i--; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Render all the weapons.
 | ||||
| /* Render all the weapons. */ | ||||
| void weapons_render(const WeaponLayer layer) { | ||||
|   Weapon** wlayer; | ||||
|   int* nlayer; | ||||
| @ -269,20 +269,20 @@ void weapons_render(const WeaponLayer layer) { | ||||
|     weapon_render(wlayer[i]); | ||||
| } | ||||
| 
 | ||||
| // Render the weapons.
 | ||||
| /* Render the weapons. */ | ||||
| static void weapon_render(const Weapon* w) { | ||||
|   int sx, sy; | ||||
|   glTexture* gfx; | ||||
| 
 | ||||
|   gfx = outfit_gfx(w->outfit); | ||||
| 
 | ||||
|   // Get the sprite corresponding to the direction facing.
 | ||||
|   /* Get the sprite corresponding to the direction facing. */ | ||||
|   gl_getSpriteFromDir(&sx, &sy, gfx, w->solid->dir); | ||||
| 
 | ||||
|   gl_blitSprite(gfx, w->solid->pos.x, w->solid->pos.y, sx, sy, NULL); | ||||
| } | ||||
| 
 | ||||
| // Update the weapon.
 | ||||
| /* Update the weapon. */ | ||||
| static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) { | ||||
|   int i, wsx, wsy, psx, psy; | ||||
|   glTexture* gfx; | ||||
| @ -295,7 +295,7 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) { | ||||
|     psx = pilot_stack[i]->tsx; | ||||
|     psy = pilot_stack[i]->tsy; | ||||
| 
 | ||||
|     if(w->parent == pilot_stack[i]->id) continue; // Hey! That's you.
 | ||||
|     if(w->parent == pilot_stack[i]->id) continue; /* Hey! That's you. */ | ||||
| 
 | ||||
|     if((weapon_isSmart(w)) && (pilot_stack[i]->id == w->target) && | ||||
|        CollideSprite(gfx, wsx, wsy, &w->solid->pos, | ||||
| @ -316,20 +316,20 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) { | ||||
| 
 | ||||
|   (*w->solid->update)(w->solid, dt); | ||||
| 
 | ||||
|   // Update the sound.
 | ||||
|   /* Update the sound. */ | ||||
|   if(w->voice) | ||||
|     voice_update(w->voice, w->solid->pos.x, w->solid->pos.y, | ||||
|                  w->solid->vel.x, w->solid->vel.y); | ||||
| } | ||||
| 
 | ||||
| // Good shot.
 | ||||
| /* Good shot. */ | ||||
| static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer) { | ||||
|   // Someone should let the ai know it's been attacked.
 | ||||
|   /* Someone should let the ai know it's been attacked. */ | ||||
|   if(!pilot_isPlayer(p)) { | ||||
|     if((player_target == p->id) || (RNG(0,2) == 0)) { | ||||
|       if((w->parent == PLAYER_ID) && | ||||
|           (!pilot_isFlag(p, PILOT_HOSTILE) || (RNG(0, 2) == 0))) { | ||||
|         faction_modPlayer(p->faction, -1); // Slowly lower faction.
 | ||||
|         faction_modPlayer(p->faction, -1); /* Slowly lower faction. */ | ||||
|         pilot_setFlag(p, PILOT_HOSTILE); | ||||
|       } | ||||
|       ai_attacked(p, w->parent); | ||||
| @ -342,29 +342,29 @@ static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer) { | ||||
|              VX(w->solid->pos), VY(w->solid->pos), | ||||
|              VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT); | ||||
| 
 | ||||
|   // Let the ship know that is should take some kind of damage.
 | ||||
|   /* Let the ship know that is should take some kind of damage. */ | ||||
|   pilot_hit(p, w->solid, w->parent, | ||||
|       outfit_damageType(w->outfit), outfit_damage(w->outfit)); | ||||
|   // We don't need the weapon particle any longer.
 | ||||
|   /* We don't need the weapon particle any longer. */ | ||||
|   weapon_destroy(w, layer); | ||||
| } | ||||
| 
 | ||||
| static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2* pos, | ||||
|                              const Vec2* vel, unsigned int parent, const unsigned int target) { | ||||
|   Vec2 v; | ||||
|   double mass = 1; // Presumer lasers have a mass of 1.
 | ||||
|   double rdir = dir; // Real direction (accuracy).
 | ||||
|   double mass = 1; /* Presumer lasers have a mass of 1. */ | ||||
|   double rdir = dir; /* Real direction (accuracy). */ | ||||
|   Weapon* w = MALLOC_L(Weapon); | ||||
|   w->parent = parent; // Non-Changeable.
 | ||||
|   w->target = target; // Non-Changeable.
 | ||||
|   w->outfit = outfit; // Non-Changeable.
 | ||||
|   w->parent = parent; /* Non-Changeable. */ | ||||
|   w->target = target; /* Non-Changeable. */ | ||||
|   w->outfit = outfit; /* Non-Changeable. */ | ||||
|   w->update = weapon_update; | ||||
|   w->timer = SDL_GetTicks(); | ||||
|   w->think = NULL; | ||||
| 
 | ||||
|   switch(outfit->type) { | ||||
|   case OUTFIT_TYPE_BOLT: | ||||
|     // Need accuracy and speed based on player. -- Another contribution from VLack.
 | ||||
|     /* Need accuracy and speed based on player. -- Another contribution from VLack. */ | ||||
|     rdir += RNG(-outfit->u.blt.accuracy/2., outfit->u.blt.accuracy/2.)/180.*M_PI; | ||||
|     if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI); | ||||
|     vectcpy(&v, vel); | ||||
| @ -378,7 +378,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2* | ||||
|   case OUTFIT_TYPE_MISSILE_SEEK_AMMO: | ||||
|     mass = w->outfit->mass; | ||||
|     w->solid = solid_create(mass, dir, pos, vel); | ||||
|     w->think = think_seeker; // Eeek!!!
 | ||||
|     w->think = think_seeker; /* Eeek!!! */ | ||||
|     w->voice = sound_addVoice(VOICE_PRIORITY_AMMO, | ||||
|                               w->solid->pos.x, w->solid->pos.y, | ||||
|                               w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0); | ||||
| @ -386,7 +386,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2* | ||||
|   case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO: | ||||
|     mass = w->outfit->mass; | ||||
|     w->solid = solid_create(mass, dir, pos, vel); | ||||
|     w->think = think_smart; // Smartass.
 | ||||
|     w->think = think_smart; /* Smartass. */ | ||||
|     w->voice = sound_addVoice(VOICE_PRIORITY_AMMO, | ||||
|                               w->solid->pos.x, w->solid->pos.y, | ||||
|                               w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0); | ||||
| @ -406,7 +406,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2* | ||||
|                               w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0); | ||||
|     break; | ||||
|   default: | ||||
|     // Just dump it where the player is.
 | ||||
|     /* Just dump it where the player is. */ | ||||
|     w->voice = NULL; | ||||
|     w->solid = solid_create(mass, dir, pos, vel); | ||||
|     break; | ||||
| @ -414,7 +414,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2* | ||||
|   return w; | ||||
| } | ||||
| 
 | ||||
| // Add a new weapon.
 | ||||
| /* Add a new weapon. */ | ||||
| void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, | ||||
|                 const Vec2* vel, unsigned int parent, unsigned int target) { | ||||
| 
 | ||||
| @ -427,7 +427,7 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, | ||||
|   WeaponLayer layer = (parent == PLAYER_ID) ? WEAPON_LAYER_FG : WEAPON_LAYER_BG; | ||||
|   Weapon* w = weapon_create(outfit, dir, pos, vel, parent, target); | ||||
| 
 | ||||
|   // Set the propper layer.
 | ||||
|   /* Set the propper layer. */ | ||||
|   Weapon** curLayer = NULL; | ||||
|   int* mLayer = NULL; | ||||
|   int* nLayer = NULL; | ||||
| @ -446,9 +446,9 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, | ||||
|     ERR("Invalid WEAPON_LAYER specified."); | ||||
|     return; | ||||
|   } | ||||
|   if(*mLayer > *nLayer) // More memory allocated than what we need.
 | ||||
|   if(*mLayer > *nLayer) /* More memory allocated than what we need. */ | ||||
|     curLayer[(*nLayer)++] = w; | ||||
|   else { // Need to allocate more memory.
 | ||||
|   else { /* Need to allocate more memory. */ | ||||
|     switch(layer) { | ||||
|     case WEAPON_LAYER_BG: | ||||
|       (*mLayer) += WEAPON_CHUNK; | ||||
| @ -463,7 +463,7 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Destroy the weapon.
 | ||||
| /* Destroy the weapon. */ | ||||
| static void weapon_destroy(Weapon* w, WeaponLayer layer) { | ||||
|   int i; | ||||
|   Weapon** wlayer; | ||||
| @ -478,7 +478,7 @@ static void weapon_destroy(Weapon* w, WeaponLayer layer) { | ||||
|     nlayer = &nwfrontLayer; | ||||
|     break; | ||||
|   } | ||||
|   for(i = 0; wlayer[i] != w; i++); // Get us to the current posision.
 | ||||
|   for(i = 0; wlayer[i] != w; i++); /* Get us to the current posision. */ | ||||
|   weapon_free(wlayer[i]); | ||||
|   wlayer[i] = NULL; | ||||
|   (*nlayer)--; | ||||
| @ -487,14 +487,14 @@ static void weapon_destroy(Weapon* w, WeaponLayer layer) { | ||||
|     wlayer[i] = wlayer[i+1]; | ||||
| } | ||||
| 
 | ||||
| // Clear the weapon.
 | ||||
| /* Clear the weapon. */ | ||||
| static void weapon_free(Weapon* w) { | ||||
|   sound_delVoice(w->voice); | ||||
|   solid_free(w->solid); | ||||
|   free(w); | ||||
| } | ||||
| 
 | ||||
| // Clear all the weapons, do not free the layers.
 | ||||
| /* Clear all the weapons, do not free the layers. */ | ||||
| void weapon_clear(void) { | ||||
|   int i; | ||||
|   for(i = 0; i < nwbackLayer; i++) | ||||
|  | ||||
| @ -8,16 +8,16 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, | ||||
|                 const Vec2* vel, unsigned int parent, | ||||
|                 const unsigned int target); | ||||
| 
 | ||||
| // Pausing.
 | ||||
| /* Pausing. */ | ||||
| void weapons_pause(void); | ||||
| void weapons_unpause(void); | ||||
| void weapons_delay(unsigned int delay); | ||||
| 
 | ||||
| // Update.
 | ||||
| /* Update. */ | ||||
| void weapons_update(const double dt); | ||||
| void weapons_render(const WeaponLayer layer); | ||||
| 
 | ||||
| // Clean.
 | ||||
| /* Clean. */ | ||||
| void weapon_clear(void); | ||||
| void weapon_exit(void); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										18
									
								
								src/xml.h
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/xml.h
									
									
									
									
									
								
							| @ -8,24 +8,24 @@ | ||||
| #define XML_NODE_START  1 | ||||
| #define XML_NODE_TEXT   3 | ||||
| 
 | ||||
| // Check if node n is of name s.
 | ||||
| /* Check if node n is of name s. */ | ||||
| #define xml_isNode(n,s) (((n)->type == XML_NODE_START) && \ | ||||
|   (strcmp((char*)(n)->name, s)==0)) | ||||
| 
 | ||||
| // Get the next node.
 | ||||
| /* Get the next node. */ | ||||
| #define xml_nextNode(n) \ | ||||
|   ((n!=NULL) && ((n = n->next) != NULL)) | ||||
| 
 | ||||
| // Get the property s of node n. This mallocs.
 | ||||
| /* Get the property s of node n. This mallocs. */ | ||||
| #define xml_nodeProp(n,s) (char*)xmlGetProp(n, (xmlChar*)s) | ||||
| 
 | ||||
| // Get data different ways.
 | ||||
| /* Get data different ways. */ | ||||
| #define xml_get(n)      ((char*)(n)->children->content) | ||||
| #define xml_getInt(n)   (atoi((char*)(n)->children->content)) | ||||
| #define xml_getLong(n)  (atoi((char*)(n)->children->content)) | ||||
| #define xml_getFloat(n) (atof((char*)(n)->children->content)) | ||||
| 
 | ||||
| // Reader crap.
 | ||||
| /* Reader crap. */ | ||||
| #define xmlr_int(n,s,i) \ | ||||
|   if(xml_isNode(n,s)) { i = xml_getInt(n);    continue; } | ||||
| #define xmlr_long(n,s,l) \ | ||||
| @ -39,9 +39,9 @@ | ||||
| #define xmlr_attr(n,s,a) \ | ||||
|   a = xml_nodeProp(n,s) | ||||
| 
 | ||||
| // Writer crap.
 | ||||
| /* Writer crap. */ | ||||
| 
 | ||||
| // Encompassing element.
 | ||||
| /* Encompassing element. */ | ||||
| #define xmlw_startElem(w, str) \ | ||||
|   if(xmlTextWriterStartElement(w, (xmlChar*)str) < 0) { \ | ||||
|     ERR("xmlw: Unable to create start element"); return -1; } | ||||
| @ -50,7 +50,7 @@ | ||||
|   if(xmlTextWriterEndElement(w) < 0) { \ | ||||
|     ERR("xmlw: Unable to create end element"); return -1; } | ||||
| 
 | ||||
| // Other stuff.
 | ||||
| /* Other stuff. */ | ||||
| #define xmlw_elem(w, n, str, args...) \ | ||||
|   if(xmlTextWriterWriteFormatElement(w, (xmlChar*)n, str, ## args) < 0) { \ | ||||
|     ERR("xmlw: Unable to write format element"); return -1; } | ||||
| @ -67,7 +67,7 @@ | ||||
|   if(xmlTextWriterWriteFormatString(w, str, ## val) < 0) { \ | ||||
|     ERR("xmlw: Unable to write element data"); return -1; } | ||||
| 
 | ||||
| // Document level.
 | ||||
| /* Document level. */ | ||||
| #define xmlw_start(w) \ | ||||
|   if(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) { \ | ||||
|     ERR("xmlw: Unable to start document"); return -1; } | ||||
|  | ||||
| @ -18,7 +18,7 @@ | ||||
| #endif | ||||
| #define RGBAMASK RMASK, GMASK, BMASK, AMASK | ||||
| 
 | ||||
| // Logging macros.
 | ||||
| /* Logging macros. */ | ||||
| #define LOG(str, args...)(fprintf(stdout, str"\n", ## args)) | ||||
| #define WARN(str, args...)(fprintf(stderr, "Warning: "str"\n", ## args)) | ||||
| #define ERR(str, args...) { fprintf(stderr, "ERROR %s:%d: "str"\n", \ | ||||
| @ -37,7 +37,7 @@ int main(int argc, char* argv[]) { | ||||
|   SDL_Surface* final, *tmp, **load; | ||||
|   SDL_Rect r; | ||||
| 
 | ||||
|   // Init variables.
 | ||||
|   /* Init variables. */ | ||||
|   r.w = r.h = 0; | ||||
| 
 | ||||
|   if(argc == 2) { | ||||
| @ -55,22 +55,22 @@ int main(int argc, char* argv[]) { | ||||
|   tmp   = NULL; | ||||
|   final = NULL; | ||||
| 
 | ||||
|   // Init SDL.
 | ||||
|   /* Init SDL. */ | ||||
|   if(SDL_Init(SDL_INIT_VIDEO)) ERR("Initializing SDL: %s", SDL_GetError()); | ||||
|   // Create the window.
 | ||||
|   /* Create the window. */ | ||||
|   tmp = SDL_SetVideoMode(320, 240, 0, SDL_NOFRAME); | ||||
|   if(tmp == NULL) ERR("Initializing video surface: %s", SDL_GetError()); | ||||
| 
 | ||||
|   // Open RAM for the images.
 | ||||
|   /* Open RAM for the images. */ | ||||
|   load = malloc(sizeof(SDL_Surface*)*(ws*hs)); | ||||
|   if(load == NULL) ERR("Out of RAM"); | ||||
| 
 | ||||
|   // Load all the images to RAM.
 | ||||
|   /* Load all the images to RAM. */ | ||||
|   for(i = 0; i < (ws*hs); i++) { | ||||
|     // Filenames will be in the sequence of: 000.png, 001.png, ..., 045.png, etc.
 | ||||
|     /* Filenames will be in the sequence of: 000.png, 001.png, ..., 045.png, etc. */ | ||||
|     sprintf(file, "%d%d%d.png", i/100, (i%100)/10, i%10); | ||||
| 
 | ||||
|     // Load the image properly.
 | ||||
|     /* Load the image properly. */ | ||||
|     tmp  = IMG_Load(file); | ||||
|     if(tmp == NULL) ERR("Problem loading file '%s': %s", file, IMG_GetError()); | ||||
|     sflags = tmp->flags & (SDL_SRCALPHA | SDL_SRCCOLORKEY); | ||||
| @ -82,7 +82,7 @@ int main(int argc, char* argv[]) { | ||||
| 
 | ||||
|     load[i] = tmp; | ||||
| 
 | ||||
|     // Check if size has changed.
 | ||||
|     /* Check if size has changed. */ | ||||
|     if(r.w == 0 && r.h == 0) { | ||||
|       r.w = load[i]->w; | ||||
|       r.h = load[i]->h; | ||||
| @ -90,21 +90,21 @@ int main(int argc, char* argv[]) { | ||||
|     else if((r.w != load[i]->w) || (r.h != load[i]->h)) | ||||
|       ERR("File '%s' is not of the same dimensions as the files before!", file); | ||||
| 
 | ||||
|     // Create the suface if it hasn't been created already.
 | ||||
|     /* Create the suface if it hasn't been created already. */ | ||||
|     if(!final) { | ||||
|       final = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, ws*r.w, hs*r.h, | ||||
|             load[i]->format->BitsPerPixel, RGBAMASK); | ||||
|       if(!final) ERR("Problem creating RGB Surface: %s", SDL_GetError()); | ||||
|       tmp = final; | ||||
|     } | ||||
|     // New position.
 | ||||
|     /* New position. */ | ||||
|     r.y = r.h * (i/ws); | ||||
|     r.x = r.w * (i%ws); | ||||
|     if(SDL_BlitSurface(load[i], NULL, final, &r)) | ||||
|       ERR("Problem blitting surface '%s' to final surface: %s", file, SDL_GetError()); | ||||
|     SDL_FreeSurface(load[i]); | ||||
|   } | ||||
|   // Draw the result and cleanup.
 | ||||
|   /* Draw the result and cleanup. */ | ||||
|   save_png(final, "sprite.png"); | ||||
|   SDL_FreeSurface(final); | ||||
|   free(load); | ||||
|  | ||||
| @ -23,7 +23,7 @@ int main(int argc, char** argv) { | ||||
|   argv += 2; | ||||
| 
 | ||||
|   if(nfiles == 0) { | ||||
|     // No files, list what it has.
 | ||||
|     /* No files, list what it has. */ | ||||
|     list = pack_listfiles(packfile, &nlist); | ||||
|     fprintf(stdout, "Packfile '%s' contains:\n", packfile); | ||||
|     for(i = 0; i < nlist; i++) { | ||||
| @ -31,7 +31,7 @@ int main(int argc, char** argv) { | ||||
|       free(list[i]); | ||||
|     } | ||||
|     free(list); | ||||
|   } else { // Create a packfile.
 | ||||
|   } else { /* Create a packfile. */ | ||||
|     pack_files(packfile, (const char**)argv, nfiles); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Allanis
						Allanis