summaryrefslogtreecommitdiff
path: root/src/uqm/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/uqm/init.c')
-rw-r--r--src/uqm/init.c351
1 files changed, 351 insertions, 0 deletions
diff --git a/src/uqm/init.c b/src/uqm/init.c
new file mode 100644
index 0000000..7831d08
--- /dev/null
+++ b/src/uqm/init.c
@@ -0,0 +1,351 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "build.h"
+#include "colors.h"
+#include "cons_res.h"
+#include "races.h"
+#include "element.h"
+#include "tactrans.h"
+#include "pickship.h"
+#include "process.h"
+#include "globdata.h"
+#include "encount.h"
+#include "hyper.h"
+#include "init.h"
+#include "port.h"
+#include "resinst.h"
+#include "libs/reslib.h"
+#include "nameref.h"
+#include "setup.h"
+#include "units.h"
+
+
+FRAME stars_in_space;
+FRAME asteroid[NUM_VIEWS];
+FRAME blast[NUM_VIEWS];
+FRAME explosion[NUM_VIEWS];
+
+
+BOOLEAN
+load_animation (FRAME *pixarray, RESOURCE big_res, RESOURCE med_res, RESOURCE
+ sml_res)
+{
+ DRAWABLE d;
+
+ d = LoadGraphic (big_res);
+ if (!d)
+ return FALSE;
+ pixarray[0] = CaptureDrawable (d);
+
+ if (med_res != NULL_RESOURCE)
+ {
+ d = LoadGraphic (med_res);
+ if (!d)
+ return FALSE;
+ }
+ pixarray[1] = CaptureDrawable (d);
+
+ if (sml_res != NULL_RESOURCE)
+ {
+ d = LoadGraphic (sml_res);
+ if (!d)
+ return FALSE;
+ }
+ pixarray[2] = CaptureDrawable (d);
+
+ return TRUE;
+}
+
+/* Warning: Some ships (such as the Umgah) will alias their pixarrays,
+ so we need to track to make sure that we do not double-free. */
+BOOLEAN
+free_image (FRAME *pixarray)
+{
+ BOOLEAN retval;
+ COUNT i, j;
+ void *already_freed[NUM_VIEWS];
+
+ retval = TRUE;
+ for (i = 0; i < NUM_VIEWS; ++i)
+ {
+ if (pixarray[i] != NULL)
+ {
+ BOOLEAN ok = TRUE;
+ for (j = 0; j < i; j++)
+ {
+ if (already_freed[j] == pixarray[i])
+ {
+ ok = FALSE;
+ break;
+ }
+ }
+ if (ok)
+ {
+ if (!DestroyDrawable (ReleaseDrawable (pixarray[i])))
+ retval = FALSE;
+ }
+ already_freed[i] = pixarray[i];
+ pixarray[i] = NULL;
+ }
+ }
+
+ return (retval);
+}
+
+static BYTE space_ini_cnt;
+
+BOOLEAN
+InitSpace (void)
+{
+ if (space_ini_cnt++ == 0
+ && LOBYTE (GLOBAL (CurrentActivity)) <= IN_ENCOUNTER)
+ {
+ stars_in_space = CaptureDrawable (
+ LoadGraphic (STAR_MASK_PMAP_ANIM));
+ if (stars_in_space == NULL)
+ return FALSE;
+
+ if (!load_animation (explosion,
+ BOOM_BIG_MASK_PMAP_ANIM,
+ BOOM_MED_MASK_PMAP_ANIM,
+ BOOM_SML_MASK_PMAP_ANIM))
+ return FALSE;
+
+ if (!load_animation (blast,
+ BLAST_BIG_MASK_PMAP_ANIM,
+ BLAST_MED_MASK_PMAP_ANIM,
+ BLAST_SML_MASK_PMAP_ANIM))
+ return FALSE;
+
+ if (!load_animation (asteroid,
+ ASTEROID_BIG_MASK_PMAP_ANIM,
+ ASTEROID_MED_MASK_PMAP_ANIM,
+ ASTEROID_SML_MASK_PMAP_ANIM))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+UninitSpace (void)
+{
+ if (space_ini_cnt && --space_ini_cnt == 0)
+ {
+ free_image (blast);
+ free_image (explosion);
+ free_image (asteroid);
+
+ DestroyDrawable (ReleaseDrawable (stars_in_space));
+ stars_in_space = 0;
+ }
+}
+
+static HSTARSHIP
+BuildSIS (void)
+{
+ HSTARSHIP hStarShip;
+ STARSHIP *StarShipPtr;
+
+ hStarShip = Build (&race_q[0], SIS_SHIP_ID);
+ if (!hStarShip)
+ return 0;
+ StarShipPtr = LockStarShip (&race_q[0], hStarShip);
+ StarShipPtr->playerNr = RPG_PLAYER_NUM;
+ StarShipPtr->captains_name_index = 0;
+ UnlockStarShip (&race_q[0], hStarShip);
+
+ return hStarShip;
+}
+
+SIZE
+InitShips (void)
+{
+ SIZE num_ships;
+
+ InitSpace ();
+
+ SetContext (StatusContext);
+ SetContext (SpaceContext);
+
+ InitDisplayList ();
+ InitGalaxy ();
+
+ if (inHQSpace ())
+ {
+ ReinitQueue (&race_q[0]);
+ ReinitQueue (&race_q[1]);
+
+ BuildSIS ();
+ LoadHyperspace ();
+
+ num_ships = 1;
+ }
+ else
+ {
+ COUNT i;
+ RECT r;
+
+ SetContextFGFrame (Screen);
+ r.corner.x = SAFE_X;
+ r.corner.y = SAFE_Y;
+ r.extent.width = SPACE_WIDTH;
+ r.extent.height = SPACE_HEIGHT;
+ SetContextClipRect (&r);
+
+ SetContextBackGroundColor (BLACK_COLOR);
+ {
+ CONTEXT OldContext;
+
+ OldContext = SetContext (ScreenContext);
+
+ SetContextBackGroundColor (BLACK_COLOR);
+ ClearDrawable ();
+
+ SetContext (OldContext);
+ }
+
+ if (LOBYTE (GLOBAL (CurrentActivity)) == IN_LAST_BATTLE)
+ free_gravity_well ();
+ else
+ {
+#define NUM_ASTEROIDS 5
+ for (i = 0; i < NUM_ASTEROIDS; ++i)
+ spawn_asteroid (NULL);
+#define NUM_PLANETS 1
+ for (i = 0; i < NUM_PLANETS; ++i)
+ spawn_planet ();
+ }
+
+ num_ships = NUM_SIDES;
+ }
+
+ // FlushInput ();
+
+ return (num_ships);
+}
+
+// Count the crew elements in the display list.
+static COUNT
+CountCrewElements (void)
+{
+ COUNT result;
+ HELEMENT hElement, hNextElement;
+
+ result = 0;
+ for (hElement = GetHeadElement ();
+ hElement != 0; hElement = hNextElement)
+ {
+ ELEMENT *ElementPtr;
+
+ LockElement (hElement, &ElementPtr);
+ hNextElement = GetSuccElement (ElementPtr);
+ if (ElementPtr->state_flags & CREW_OBJECT)
+ ++result;
+
+ UnlockElement (hElement);
+ }
+
+ return result;
+}
+
+void
+UninitShips (void)
+{
+ COUNT crew_retrieved;
+ int i;
+ HELEMENT hElement, hNextElement;
+ STARSHIP *SPtr[NUM_PLAYERS];
+
+ StopSound ();
+
+ UninitSpace ();
+
+ for (i = 0; i < NUM_PLAYERS; ++i)
+ SPtr[i] = 0;
+
+ // Count the crew floating in space.
+ crew_retrieved = CountCrewElements();
+
+ for (hElement = GetHeadElement ();
+ hElement != 0; hElement = hNextElement)
+ {
+ ELEMENT *ElementPtr;
+
+ LockElement (hElement, &ElementPtr);
+ hNextElement = GetSuccElement (ElementPtr);
+ if ((ElementPtr->state_flags & PLAYER_SHIP)
+ || ElementPtr->death_func == new_ship)
+ {
+ STARSHIP *StarShipPtr;
+
+ GetElementStarShip (ElementPtr, &StarShipPtr);
+
+ // There should only be one ship left in battle.
+ // He gets the crew still floating in space.
+ if (StarShipPtr->RaceDescPtr->ship_info.crew_level)
+ {
+ if (crew_retrieved >=
+ StarShipPtr->RaceDescPtr->ship_info.max_crew -
+ StarShipPtr->RaceDescPtr->ship_info.crew_level)
+ StarShipPtr->RaceDescPtr->ship_info.crew_level =
+ StarShipPtr->RaceDescPtr->ship_info.max_crew;
+ else
+ StarShipPtr->RaceDescPtr->ship_info.crew_level +=
+ crew_retrieved;
+ }
+
+ /* Record crew left after battle */
+ StarShipPtr->crew_level =
+ StarShipPtr->RaceDescPtr->ship_info.crew_level;
+ SPtr[StarShipPtr->playerNr] = StarShipPtr;
+ free_ship (StarShipPtr->RaceDescPtr, TRUE, TRUE);
+ StarShipPtr->RaceDescPtr = 0;
+ }
+ UnlockElement (hElement);
+ }
+
+ GLOBAL (CurrentActivity) &= ~IN_BATTLE;
+
+ if (LOBYTE (GLOBAL (CurrentActivity)) == IN_ENCOUNTER
+ && !(GLOBAL (CurrentActivity) & CHECK_ABORT))
+ {
+ // Encounter battle in full game.
+ // Record the crew left in the last ship standing. The crew left
+ // is first recorded into STARSHIP.crew_level just a few lines
+ // above here.
+ for (i = NUM_PLAYERS - 1; i >= 0; --i)
+ {
+ if (SPtr[i] && !FleetIsInfinite (i))
+ UpdateShipFragCrew (SPtr[i]);
+ }
+ }
+
+ if (LOBYTE (GLOBAL (CurrentActivity)) != IN_ENCOUNTER)
+ {
+ // Remove any ships left from the race queue.
+ for (i = 0; i < NUM_PLAYERS; i++)
+ ReinitQueue (&race_q[i]);
+
+ if (inHQSpace ())
+ FreeHyperspace ();
+ }
+}
+
+