2015-10-20 13:51:49 +02:00
/*
2019-01-01 17:14:11 +01:00
Copyright ( C ) 2015 - 2019 Parallel Realities
2015-10-20 13:51:49 +02:00
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 "galacticMap.h"
static void logic ( void ) ;
static void draw ( void ) ;
static void handleKeyboard ( void ) ;
2015-11-24 08:16:48 +01:00
static void handleMouse ( void ) ;
static void scrollGalaxy ( void ) ;
2015-10-20 13:51:49 +02:00
static void drawStarSystemDetail ( void ) ;
static void selectStarSystem ( void ) ;
static void drawGalaxy ( void ) ;
static void centerOnSelectedStarSystem ( void ) ;
static void doStarSystems ( void ) ;
void destroyGalacticMap ( void ) ;
static void drawPulses ( void ) ;
2015-10-25 13:56:24 +01:00
static void drawInfoBars ( void ) ;
2015-10-20 13:51:49 +02:00
static void doPulses ( void ) ;
static void addPulses ( void ) ;
static void drawMenu ( void ) ;
static void resume ( void ) ;
static void stats ( void ) ;
2016-05-15 09:19:26 +02:00
static void trophies ( void ) ;
2015-10-20 13:51:49 +02:00
static void options ( void ) ;
2016-05-15 09:19:26 +02:00
static void ok ( void ) ;
2015-10-20 13:51:49 +02:00
static void quit ( void ) ;
2015-11-24 08:16:48 +01:00
static void startMission ( void ) ;
2015-10-20 13:51:49 +02:00
static void returnFromOptions ( void ) ;
2015-11-24 08:16:48 +01:00
static void doStarSystemView ( void ) ;
2016-02-14 12:53:03 +01:00
static void updatePandoranAdvance ( void ) ;
static void fallenOK ( void ) ;
2016-08-11 23:48:08 +02:00
static void updateCampaignProgress ( void ) ;
static void campaignCompleteOK ( void ) ;
2016-07-24 09:24:04 +02:00
static Mission * nextAvailableMission ( StarSystem * starSystem ) ;
2017-08-12 09:33:06 +02:00
static void fighterDatabase ( void ) ;
2015-10-20 13:51:49 +02:00
2016-02-23 23:20:07 +01:00
static StarSystem * selectedStarSystem ;
2015-10-20 13:51:49 +02:00
static SDL_Texture * background ;
2018-12-06 09:37:19 +01:00
static AtlasImage * starSystemTexture ;
static AtlasImage * arrowTexture ;
2015-10-20 13:51:49 +02:00
static SDL_Point camera ;
static Pulse pulseHead = { 0 } ;
static Pulse * pulseTail ;
static int pulseTimer ;
static float ssx , ssy ;
2015-10-20 18:20:55 +02:00
static float arrowPulse ;
2015-10-20 13:51:49 +02:00
static int show ;
2016-02-14 12:07:15 +01:00
static int scrollingMap ;
2016-08-11 23:48:08 +02:00
static int campaignComplete = 0 ;
2016-02-25 17:00:42 +01:00
static PointF cameraMin , cameraMax ;
2016-02-13 17:59:18 +01:00
static Widget * startMissionButton ;
2018-04-29 10:58:16 +02:00
static Mission * hoverMission ;
2016-07-19 10:26:19 +02:00
static char * MISSIONS_TEXT ;
static char * PILOT_TEXT ;
static char * CRAFT_TEXT ;
static char * SQUADRON_TEXT ;
static char * COMPLETED_TEXT ;
static char * EPIC_TEXT ;
static char * OPTIONAL_TEXT ;
2015-10-20 13:51:49 +02:00
void initGalacticMap ( void )
{
2016-02-21 17:55:11 +01:00
show = SHOW_GALAXY ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
startSectionTransition ( ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
stopMusic ( ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
app . delegate . logic = & logic ;
app . delegate . draw = & draw ;
memset ( & app . keyboard , 0 , sizeof ( int ) * MAX_KEYBOARD_KEYS ) ;
2016-07-19 10:26:19 +02:00
MISSIONS_TEXT = _ ( " Missions: %d / %d " ) ;
PILOT_TEXT = _ ( " Pilot: %s " ) ;
CRAFT_TEXT = _ ( " Craft: %s " ) ;
SQUADRON_TEXT = _ ( " Squadron: %s " ) ;
COMPLETED_TEXT = _ ( " This mission has been completed. " ) ;
EPIC_TEXT = _ ( " Note: this is an epic mission. " ) ;
OPTIONAL_TEXT = _ ( " Note: this is an optional mission. " ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
background = getTexture ( " gfx/backgrounds/background02.jpg " ) ;
2016-03-09 13:31:33 +01:00
2018-12-06 09:37:19 +01:00
starSystemTexture = getAtlasImage ( " gfx/galaxy/starSystem.png " ) ;
2016-03-09 13:31:33 +01:00
2018-12-06 09:37:19 +01:00
arrowTexture = getAtlasImage ( " gfx/galaxy/arrow.png " ) ;
2016-03-09 13:31:33 +01:00
2015-10-30 08:22:49 +01:00
selectedStarSystem = getStarSystem ( game . selectedStarSystem ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
centerOnSelectedStarSystem ( ) ;
2016-03-09 13:31:33 +01:00
2016-02-29 11:47:10 +01:00
updateAllMissions ( ) ;
2016-03-09 13:31:33 +01:00
2016-02-14 12:53:03 +01:00
updatePandoranAdvance ( ) ;
2016-03-09 13:31:33 +01:00
2016-03-09 16:53:56 +01:00
awardCampaignTrophies ( ) ;
awardStatsTrophies ( ) ;
2016-08-11 23:48:08 +02:00
updateCampaignProgress ( ) ;
2018-04-29 10:58:16 +02:00
hoverMission = NULL ;
2016-03-09 13:31:33 +01:00
2016-05-15 09:19:26 +02:00
app . saveGame = 1 ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
pulseTimer = 0 ;
2016-03-09 13:31:33 +01:00
2015-10-20 18:20:55 +02:00
arrowPulse = 0 ;
2016-05-15 09:19:26 +02:00
selectedStarSystem = NULL ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
/* clear the pulses */
destroyGalacticMap ( ) ;
2016-03-09 13:31:33 +01:00
2017-05-26 08:47:51 +02:00
getWidget ( " close " , " starSystem " ) - > action = resume ;
2016-02-13 17:59:18 +01:00
startMissionButton = getWidget ( " startMission " , " starSystem " ) ;
startMissionButton - > action = startMission ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
getWidget ( " resume " , " galacticMap " ) - > action = resume ;
getWidget ( " stats " , " galacticMap " ) - > action = stats ;
2016-05-15 09:19:26 +02:00
getWidget ( " trophies " , " galacticMap " ) - > action = trophies ;
2017-08-12 09:33:06 +02:00
getWidget ( " fighterDB " , " galacticMap " ) - > action = fighterDatabase ;
2015-10-20 13:51:49 +02:00
getWidget ( " options " , " galacticMap " ) - > action = options ;
getWidget ( " quit " , " galacticMap " ) - > action = quit ;
2016-03-09 13:31:33 +01:00
2016-05-15 09:19:26 +02:00
getWidget ( " ok " , " stats " ) - > action = ok ;
getWidget ( " ok " , " trophies " ) - > action = ok ;
2017-08-12 09:33:06 +02:00
getWidget ( " ok " , " fighterDB " ) - > action = ok ;
2016-03-09 13:31:33 +01:00
2016-02-14 12:53:03 +01:00
getWidget ( " ok " , " fallen " ) - > action = fallenOK ;
2018-05-06 19:50:11 +02:00
autoSizeWidgetButtons ( " galacticMap " , 1 ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
endSectionTransition ( ) ;
2016-08-12 09:56:40 +02:00
SDL_SetWindowGrab ( app . window , 0 ) ;
2016-03-09 13:31:33 +01:00
2016-05-29 12:48:11 +02:00
playMusic ( " music/main/Pressure.ogg " , 1 ) ;
2015-10-20 13:51:49 +02:00
}
2016-08-11 23:48:08 +02:00
static void updateCampaignProgress ( void )
{
StarSystem * starSystem ;
2016-08-12 09:56:59 +02:00
if ( ! campaignComplete & & game . completedMissions = = game . totalMissions )
2016-08-11 23:48:08 +02:00
{
for ( starSystem = game . starSystemHead . next ; starSystem ! = NULL ; starSystem = starSystem - > next )
{
2016-08-12 13:22:39 +02:00
if ( starSystem - > missionHead . next & & starSystem - > missionHead . next - > available )
{
starSystem - > activeMission = starSystem - > missionHead . next ;
}
2016-08-11 23:48:08 +02:00
}
campaignComplete = 1 ;
showOKDialog ( & campaignCompleteOK , _ ( " Congratulations, you have completed the campaign! You may now replay past missions, for fun, to boost stats, or to earn missing trophies! " ) ) ;
}
}
2016-02-14 12:53:03 +01:00
static void updatePandoranAdvance ( void )
{
2016-02-23 23:20:07 +01:00
StarSystem * starSystem , * fallenStarSystem ;
2016-03-09 13:31:33 +01:00
2016-02-23 23:20:07 +01:00
fallenStarSystem = NULL ;
2016-03-09 13:31:33 +01:00
2016-02-14 12:53:03 +01:00
for ( starSystem = game . starSystemHead . next ; starSystem ! = NULL ; starSystem = starSystem - > next )
{
if ( starSystem - > side ! = SIDE_PANDORAN & & starSystem - > fallsToPandorans & & starSystem - > completedMissions = = starSystem - > totalMissions & & starSystem - > totalMissions > 0 )
{
starSystem - > side = SIDE_PANDORAN ;
2016-03-09 13:31:33 +01:00
2016-02-14 12:53:03 +01:00
fallenStarSystem = starSystem ;
}
}
2016-03-09 13:31:33 +01:00
2016-02-23 23:20:07 +01:00
if ( fallenStarSystem )
{
2016-02-27 20:16:17 +01:00
showOKDialog ( & fallenOK , _ ( " %s has fallen to the Pandorans " ) , fallenStarSystem - > name ) ;
2016-02-23 23:20:07 +01:00
}
2016-02-14 12:53:03 +01:00
}
2015-10-20 13:51:49 +02:00
static void logic ( void )
{
handleKeyboard ( ) ;
2016-03-09 13:31:33 +01:00
2015-11-24 08:16:48 +01:00
handleMouse ( ) ;
2016-03-09 13:31:33 +01:00
2015-11-24 08:16:48 +01:00
switch ( show )
{
case SHOW_GALAXY :
doStarSystems ( ) ;
scrollGalaxy ( ) ;
scrollBackground ( - ssx , - ssy ) ;
doStars ( ssx , ssy ) ;
break ;
2016-03-09 13:31:33 +01:00
2015-11-24 08:16:48 +01:00
case SHOW_STAR_SYSTEM :
doStarSystemView ( ) ;
break ;
}
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
doPulses ( ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
if ( pulseTimer % FPS = = 0 )
{
addPulses ( ) ;
}
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
pulseTimer + + ;
pulseTimer % = ( FPS * 60 ) ;
2016-03-09 13:31:33 +01:00
2016-02-27 20:16:17 +01:00
arrowPulse + = 0.1 ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
doWidgets ( ) ;
2016-05-15 09:19:26 +02:00
2017-08-12 09:33:06 +02:00
if ( show = = SHOW_FIGHTER_DB )
{
doFighterDatabase ( ) ;
}
2016-05-31 10:37:46 +02:00
app . doTrophyAlerts = 1 ;
2015-10-20 13:51:49 +02:00
}
static void doStarSystems ( void )
{
StarSystem * starSystem ;
int cx , cy ;
2016-03-09 13:31:33 +01:00
2016-02-14 12:07:15 +01:00
if ( ! scrollingMap )
2015-10-20 13:51:49 +02:00
{
2016-02-14 12:07:15 +01:00
cx = app . mouse . x - 32 ;
cy = app . mouse . y - 32 ;
2016-03-09 13:31:33 +01:00
2016-02-25 17:00:42 +01:00
cameraMin . x = cameraMin . y = 99999 ;
cameraMax . x = cameraMax . y = - 99999 ;
2016-03-09 13:31:33 +01:00
2016-02-14 12:07:15 +01:00
selectedStarSystem = NULL ;
2016-03-09 13:31:33 +01:00
2016-02-14 12:07:15 +01:00
for ( starSystem = game . starSystemHead . next ; starSystem ! = NULL ; starSystem = starSystem - > next )
2015-10-20 13:51:49 +02:00
{
2016-02-25 17:00:42 +01:00
cameraMin . x = MIN ( cameraMin . x , starSystem - > x ) ;
cameraMin . y = MIN ( cameraMin . y , starSystem - > y ) ;
2016-03-09 13:31:33 +01:00
2016-02-25 17:00:42 +01:00
cameraMax . x = MAX ( cameraMax . x , starSystem - > x ) ;
cameraMax . y = MAX ( cameraMax . y , starSystem - > y ) ;
2016-03-09 13:31:33 +01:00
2016-02-21 17:55:11 +01:00
if ( starSystem - > availableMissions > 0 & & collision ( cx , cy , 64 , 64 , starSystem - > x - camera . x , starSystem - > y - camera . y , 4 , 4 ) )
2015-10-20 13:51:49 +02:00
{
2016-02-14 12:07:15 +01:00
if ( selectedStarSystem ! = starSystem )
2015-11-24 08:16:48 +01:00
{
2016-02-14 12:07:15 +01:00
selectedStarSystem = starSystem ;
2016-03-09 13:31:33 +01:00
2016-02-14 12:07:15 +01:00
if ( app . mouse . button [ SDL_BUTTON_LEFT ] )
{
selectStarSystem ( ) ;
2016-03-09 13:31:33 +01:00
2016-02-14 12:07:15 +01:00
app . mouse . button [ SDL_BUTTON_LEFT ] = 0 ;
}
2015-11-24 08:16:48 +01:00
}
2015-10-20 13:51:49 +02:00
}
2015-11-30 10:33:43 +01:00
}
2016-03-09 13:31:33 +01:00
2018-12-14 09:00:16 +01:00
cameraMin . x - = app . winWidth / 2 ;
cameraMin . y - = app . winHeight / 2 ;
2016-03-09 13:31:33 +01:00
2018-12-14 09:00:16 +01:00
cameraMax . x - = app . winWidth / 2 ;
cameraMax . y - = app . winHeight / 2 ;
2015-10-20 13:51:49 +02:00
}
}
2015-11-24 08:16:48 +01:00
static void scrollGalaxy ( void )
{
int lastX , lastY ;
2016-03-09 13:31:33 +01:00
2015-11-24 08:16:48 +01:00
lastX = camera . x ;
lastY = camera . y ;
2016-03-09 13:31:33 +01:00
2015-11-24 08:16:48 +01:00
ssx = ssy = 0 ;
2016-03-09 13:31:33 +01:00
2016-02-14 12:07:15 +01:00
if ( scrollingMap )
2015-11-24 08:16:48 +01:00
{
2016-02-14 12:07:15 +01:00
camera . x - = app . mouse . dx * 1.5 ;
camera . y - = app . mouse . dy * 1.5 ;
2016-03-09 13:31:33 +01:00
2018-12-07 15:49:08 +01:00
ssx = - app . mouse . dx ;
ssx / = 3 ;
ssy = - app . mouse . dy ;
ssy / = 3 ;
2016-03-09 13:31:33 +01:00
2016-02-25 17:00:42 +01:00
camera . x = MAX ( cameraMin . x , MIN ( camera . x , cameraMax . x ) ) ;
camera . y = MAX ( cameraMin . y , MIN ( camera . y , cameraMax . y ) ) ;
2018-12-07 15:49:08 +01:00
if ( lastX = = camera . x )
{
ssx = 0 ;
}
2016-03-09 13:31:33 +01:00
2018-12-07 15:49:08 +01:00
if ( lastY = = camera . y )
{
ssy = 0 ;
}
2015-11-24 08:16:48 +01:00
}
}
static void doStarSystemView ( void )
{
Mission * mission ;
2016-03-09 13:31:33 +01:00
2015-11-24 08:16:48 +01:00
for ( mission = selectedStarSystem - > missionHead . next ; mission ! = NULL ; mission = mission - > next )
{
2018-12-12 09:32:32 +01:00
if ( mission - > available & & collision ( app . uiMouse . x - app . mouse . w / 2 , app . uiMouse . y - app . mouse . h / 2 , app . mouse . w , app . mouse . h , mission - > rect . x , mission - > rect . y , mission - > rect . w , mission - > rect . h ) )
2015-11-24 08:16:48 +01:00
{
2018-04-29 10:58:16 +02:00
hoverMission = mission ;
if ( app . mouse . button [ SDL_BUTTON_LEFT ] )
2015-11-24 08:16:48 +01:00
{
2018-04-29 10:58:16 +02:00
if ( game . currentMission ! = mission )
{
playSound ( SND_GUI_CLICK ) ;
}
2016-03-09 13:31:33 +01:00
2018-04-29 10:58:16 +02:00
game . currentMission = mission ;
return ;
}
2015-11-24 08:16:48 +01:00
}
}
2016-07-19 09:15:18 +02:00
/* allow closing by pressing the right mouse button */
if ( app . mouse . button [ SDL_BUTTON_RIGHT ] )
{
show = SHOW_GALAXY ;
playSound ( SND_GUI_CLOSE ) ;
}
2015-11-24 08:16:48 +01:00
}
2015-10-20 13:51:49 +02:00
static void addPulses ( void )
{
Pulse * pulse ;
StarSystem * starSystem ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
for ( starSystem = game . starSystemHead . next ; starSystem ! = NULL ; starSystem = starSystem - > next )
{
2016-08-11 23:48:08 +02:00
if ( starSystem - > completedMissions < starSystem - > availableMissions | | ( campaignComplete & & starSystem - > activeMission ) )
2015-10-20 13:51:49 +02:00
{
pulse = malloc ( sizeof ( Pulse ) ) ;
memset ( pulse , 0 , sizeof ( Pulse ) ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
pulse - > x = starSystem - > x ;
pulse - > y = starSystem - > y ;
pulse - > life = 255 ;
2016-05-15 11:50:09 +02:00
switch ( starSystem - > type )
2015-11-02 20:10:07 +01:00
{
2016-05-15 11:50:09 +02:00
case SS_NORMAL :
2016-06-07 10:24:09 +02:00
if ( ! starSystem - > activeMission - > isOptional )
{
pulse - > r = 255 ;
}
else
{
pulse - > r = 128 ;
pulse - > g = 128 ;
pulse - > b = 255 ;
}
2016-05-15 11:50:09 +02:00
break ;
case SS_SOL :
pulse - > g = 255 ;
break ;
case SS_PANDORAN :
2016-05-15 12:59:37 +02:00
pulse - > r = 128 ;
pulse - > g = 128 ;
2016-05-15 11:50:09 +02:00
pulse - > b = 255 ;
break ;
2015-11-02 20:10:07 +01:00
}
2016-05-15 11:50:09 +02:00
2015-12-21 15:19:21 +01:00
pulseTail - > next = pulse ;
pulseTail = pulse ;
2015-10-20 13:51:49 +02:00
}
}
}
static void doPulses ( void )
{
Pulse * pulse , * prev ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
prev = & pulseHead ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
for ( pulse = pulseHead . next ; pulse ! = NULL ; pulse = pulse - > next )
{
pulse - > size + = 0.5 ;
pulse - > life - - ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
if ( pulse - > life < = 0 )
{
if ( pulse = = pulseTail )
{
pulseTail = prev ;
}
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
prev - > next = pulse - > next ;
free ( pulse ) ;
pulse = prev ;
}
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
prev = pulse ;
}
}
static void draw ( void )
{
drawBackground ( background ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
drawStars ( ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
drawGalaxy ( ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
drawPulses ( ) ;
2016-03-09 13:31:33 +01:00
2015-10-25 13:56:24 +01:00
drawInfoBars ( ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
switch ( show )
{
2015-11-24 08:16:48 +01:00
case SHOW_STAR_SYSTEM :
drawStarSystemDetail ( ) ;
2015-10-20 13:51:49 +02:00
break ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
case SHOW_MENU :
drawMenu ( ) ;
break ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
case SHOW_STATS :
drawStats ( ) ;
break ;
2016-05-15 09:19:26 +02:00
case SHOW_TROPHIES :
drawTrophies ( ) ;
break ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
case SHOW_OPTIONS :
drawOptions ( ) ;
break ;
2017-08-12 09:33:06 +02:00
case SHOW_FIGHTER_DB :
drawFighterDatabase ( ) ;
break ;
2015-10-20 13:51:49 +02:00
}
}
static void drawPulses ( void )
{
Pulse * pulse ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
for ( pulse = pulseHead . next ; pulse ! = NULL ; pulse = pulse - > next )
{
drawCircle ( pulse - > x - camera . x , pulse - > y - camera . y , pulse - > size , pulse - > r , pulse - > g , pulse - > b , pulse - > life ) ;
}
}
static void centerOnSelectedStarSystem ( void )
{
camera . x = selectedStarSystem - > x ;
2018-12-14 09:00:16 +01:00
camera . x - = app . winWidth / 2 ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
camera . y = selectedStarSystem - > y ;
2018-12-14 09:00:16 +01:00
camera . y - = app . winHeight / 2 ;
2015-10-20 13:51:49 +02:00
}
static void drawGalaxy ( void )
{
SDL_Rect r ;
StarSystem * starSystem ;
SDL_Color color ;
2015-10-20 18:20:55 +02:00
float ax , ay , aa ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
for ( starSystem = game . starSystemHead . next ; starSystem ! = NULL ; starSystem = starSystem - > next )
{
2015-10-20 18:20:55 +02:00
r . x = starSystem - > x - camera . x ;
r . y = starSystem - > y - camera . y ;
2016-03-09 13:31:33 +01:00
2015-10-20 18:20:55 +02:00
blit ( starSystemTexture , r . x , r . y , 1 ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
switch ( starSystem - > side )
{
case SIDE_CSN :
color = colors . cyan ;
break ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
case SIDE_UNF :
color = colors . white ;
break ;
2016-03-09 13:31:33 +01:00
2016-02-24 08:16:23 +01:00
case SIDE_PANDORAN :
2015-10-20 13:51:49 +02:00
color = colors . red ;
break ;
}
2016-03-09 13:31:33 +01:00
2015-10-20 18:20:55 +02:00
drawText ( r . x , r . y + 12 , 14 , TA_CENTER , color , starSystem - > name ) ;
2016-03-09 13:31:33 +01:00
2016-02-21 17:55:11 +01:00
if ( starSystem - > completedMissions < starSystem - > availableMissions )
2015-10-20 18:20:55 +02:00
{
ax = r . x ;
ay = r . y ;
aa = - 1 ;
2016-03-09 13:31:33 +01:00
2018-12-12 09:32:32 +01:00
ax = MAX ( MIN ( app . winWidth - 64 , ax ) , 64 ) ;
ay = MAX ( MIN ( app . winHeight - 64 , ay ) , 64 ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 18:20:55 +02:00
if ( r . x < 0 )
{
ax = 64 + ( sin ( arrowPulse ) * 10 ) ;
aa = 270 ;
}
2018-12-12 09:32:32 +01:00
else if ( r . x > app . winWidth )
2015-10-20 18:20:55 +02:00
{
2018-12-12 09:32:32 +01:00
ax = app . winWidth - 64 + ( sin ( arrowPulse ) * 10 ) ;
2015-10-20 18:20:55 +02:00
aa = 90 ;
}
else if ( r . y < 0 )
{
ay = 64 + ( sin ( arrowPulse ) * 10 ) ;
aa = 0 ;
}
2018-12-12 09:32:32 +01:00
else if ( r . y > app . winHeight )
2015-10-20 18:20:55 +02:00
{
2018-12-12 09:32:32 +01:00
ay = app . winHeight - 64 + ( sin ( arrowPulse ) * 10 ) ;
2015-10-20 18:20:55 +02:00
aa = 180 ;
}
2016-03-09 13:31:33 +01:00
2015-10-20 18:20:55 +02:00
if ( aa ! = - 1 )
{
2016-05-15 11:50:09 +02:00
switch ( starSystem - > type )
2015-12-21 15:19:21 +01:00
{
2016-05-15 11:50:09 +02:00
case SS_NORMAL :
2018-12-06 17:52:13 +01:00
setAtlasColor ( 255 , 0 , 0 , 255 ) ;
2016-05-15 11:50:09 +02:00
break ;
case SS_SOL :
2018-12-06 17:52:13 +01:00
setAtlasColor ( 0 , 255 , 0 , 255 ) ;
2016-05-15 11:50:09 +02:00
break ;
case SS_PANDORAN :
2018-12-06 17:52:13 +01:00
setAtlasColor ( 64 , 128 , 255 , 255 ) ;
2016-05-15 11:50:09 +02:00
break ;
2015-12-21 15:19:21 +01:00
}
2016-05-15 11:50:09 +02:00
2015-10-20 18:20:55 +02:00
blitRotated ( arrowTexture , ax , ay , aa ) ;
2018-12-06 17:52:13 +01:00
setAtlasColor ( 255 , 255 , 255 , 255 ) ;
2015-10-20 18:20:55 +02:00
}
}
2015-10-20 13:51:49 +02:00
}
2015-10-25 13:56:24 +01:00
}
static void drawInfoBars ( void )
{
SDL_Rect r ;
2016-03-09 13:31:33 +01:00
2015-11-24 08:16:48 +01:00
if ( show ! = SHOW_STAR_SYSTEM & & selectedStarSystem ! = NULL )
2015-10-20 13:51:49 +02:00
{
r . x = 0 ;
2018-12-12 09:32:32 +01:00
r . y = app . winHeight - 35 ;
r . w = app . winWidth ;
2015-10-20 13:51:49 +02:00
r . h = 35 ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
SDL_SetRenderDrawBlendMode ( app . renderer , SDL_BLENDMODE_BLEND ) ;
SDL_SetRenderDrawColor ( app . renderer , 0 , 0 , 0 , 200 ) ;
SDL_RenderFillRect ( app . renderer , & r ) ;
SDL_SetRenderDrawBlendMode ( app . renderer , SDL_BLENDMODE_NONE ) ;
2016-03-09 13:31:33 +01:00
2018-12-12 09:32:32 +01:00
drawText ( app . winWidth / 2 , app . winHeight - 30 , 18 , TA_CENTER , colors . white , selectedStarSystem - > description ) ;
2015-10-20 13:51:49 +02:00
}
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
r . x = 0 ;
r . y = 0 ;
2018-12-12 09:32:32 +01:00
r . w = app . winWidth ;
2015-10-20 13:51:49 +02:00
r . h = 35 ;
SDL_SetRenderDrawBlendMode ( app . renderer , SDL_BLENDMODE_BLEND ) ;
SDL_SetRenderDrawColor ( app . renderer , 0 , 0 , 0 , 200 ) ;
SDL_RenderFillRect ( app . renderer , & r ) ;
SDL_SetRenderDrawBlendMode ( app . renderer , SDL_BLENDMODE_NONE ) ;
2016-03-09 13:31:33 +01:00
2018-12-12 09:32:32 +01:00
drawText ( ( app . winWidth / 2 ) , 5 , 18 , TA_CENTER , colors . white , MISSIONS_TEXT , game . completedMissions , game . availableMissions ) ;
2015-10-20 13:51:49 +02:00
}
static void selectStarSystem ( void )
{
2016-02-21 17:55:11 +01:00
if ( selectedStarSystem - > availableMissions > 0 )
2015-10-30 08:22:49 +01:00
{
2015-11-24 08:16:48 +01:00
show = SHOW_STAR_SYSTEM ;
2015-10-30 08:22:49 +01:00
STRNCPY ( game . selectedStarSystem , selectedStarSystem - > name , MAX_NAME_LENGTH ) ;
2016-07-24 09:24:04 +02:00
game . currentMission = nextAvailableMission ( selectedStarSystem ) ;
2015-11-24 08:16:48 +01:00
playSound ( SND_GUI_SELECT ) ;
2015-10-30 08:22:49 +01:00
}
2015-10-20 13:51:49 +02:00
}
2016-07-24 09:24:04 +02:00
static Mission * nextAvailableMission ( StarSystem * starSystem )
{
Mission * m ;
for ( m = starSystem - > missionHead . next ; m ! = NULL ; m = m - > next )
{
if ( m - > available & & ! m - > completed )
{
return m ;
}
}
return starSystem - > missionHead . next ;
}
2015-10-20 13:51:49 +02:00
static void drawStarSystemDetail ( void )
{
2018-04-29 10:58:16 +02:00
int y ;
2015-10-20 13:51:49 +02:00
Mission * mission ;
SDL_Rect r ;
2018-12-12 09:32:32 +01:00
SDL_SetRenderTarget ( app . renderer , app . uiBuffer ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
r . w = 900 ;
r . h = 600 ;
2018-12-13 08:59:31 +01:00
r . x = ( UI_WIDTH / 2 ) - ( r . w / 2 ) ;
r . y = ( UI_HEIGHT / 2 ) - ( r . h / 2 ) ;
2015-10-20 13:51:49 +02:00
SDL_SetRenderDrawBlendMode ( app . renderer , SDL_BLENDMODE_BLEND ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
SDL_SetRenderDrawColor ( app . renderer , 0 , 0 , 0 , 225 ) ;
SDL_RenderFillRect ( app . renderer , & r ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
SDL_SetRenderDrawColor ( app . renderer , 255 , 255 , 255 , 200 ) ;
SDL_RenderDrawRect ( app . renderer , & r ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
SDL_SetRenderDrawBlendMode ( app . renderer , SDL_BLENDMODE_NONE ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
y = 70 ;
2016-03-09 13:31:33 +01:00
2018-12-13 08:59:31 +01:00
drawText ( UI_WIDTH / 2 , y , 28 , TA_CENTER , colors . cyan , selectedStarSystem - > name ) ;
2016-03-09 13:31:33 +01:00
2016-02-13 17:59:18 +01:00
SDL_RenderDrawLine ( app . renderer , r . x , 120 , r . x + r . w - 1 , 120 ) ;
2016-03-09 13:31:33 +01:00
2018-04-29 17:44:36 +02:00
SDL_RenderDrawLine ( app . renderer , 515 , 120 , 515 , 659 ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
y + = 80 ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
for ( mission = selectedStarSystem - > missionHead . next ; mission ! = NULL ; mission = mission - > next )
{
2018-04-29 10:58:16 +02:00
mission - > rect . x = 200 ;
mission - > rect . y = y - 2 ;
mission - > rect . w = 300 ;
mission - > rect . h = 38 ;
if ( mission = = hoverMission )
2015-10-20 13:51:49 +02:00
{
2018-04-29 10:58:16 +02:00
SDL_SetRenderDrawColor ( app . renderer , 16 , 32 , 64 , 255 ) ;
SDL_RenderFillRect ( app . renderer , & mission - > rect ) ;
2016-03-09 13:31:33 +01:00
2018-04-29 10:58:16 +02:00
SDL_SetRenderDrawColor ( app . renderer , 32 , 64 , 128 , 255 ) ;
SDL_RenderDrawRect ( app . renderer , & mission - > rect ) ;
}
2016-03-09 13:31:33 +01:00
2018-04-29 10:58:16 +02:00
if ( mission = = game . currentMission )
{
SDL_SetRenderDrawColor ( app . renderer , 32 , 64 , 128 , 255 ) ;
SDL_RenderFillRect ( app . renderer , & mission - > rect ) ;
2016-06-07 09:30:33 +02:00
2018-04-29 10:58:16 +02:00
SDL_SetRenderDrawColor ( app . renderer , 64 , 96 , 196 , 255 ) ;
SDL_RenderDrawRect ( app . renderer , & mission - > rect ) ;
}
if ( mission - > available )
{
drawText ( 210 , y , 22 , TA_LEFT , mission - > completed ? colors . lightGrey : colors . yellow , mission - > name ) ;
y + = 42 ;
2016-06-07 09:30:33 +02:00
}
2015-10-20 13:51:49 +02:00
}
2016-03-09 13:31:33 +01:00
2016-02-27 17:16:21 +01:00
if ( game . currentMission - > available )
2015-10-20 13:51:49 +02:00
{
2016-07-19 10:26:19 +02:00
drawText ( 525 , 135 , 18 , TA_LEFT , colors . lightGrey , PILOT_TEXT , game . currentMission - > pilot ) ;
drawText ( 525 , 160 , 18 , TA_LEFT , colors . lightGrey , CRAFT_TEXT , game . currentMission - > craft ) ;
drawText ( 525 , 185 , 18 , TA_LEFT , colors . lightGrey , SQUADRON_TEXT , game . currentMission - > squadron ) ;
2016-03-09 13:31:33 +01:00
2018-12-07 15:49:08 +01:00
app . textWidth = 525 ;
2018-12-06 09:37:19 +01:00
2016-02-27 17:16:21 +01:00
drawText ( 525 , 230 , 22 , TA_LEFT , colors . white , game . currentMission - > description ) ;
2018-12-06 09:37:19 +01:00
app . textWidth = 0 ;
2015-10-20 13:51:49 +02:00
}
2016-03-09 13:31:33 +01:00
2016-02-27 17:16:21 +01:00
if ( game . currentMission - > completed )
2016-02-13 17:59:18 +01:00
{
2018-12-13 08:59:31 +01:00
drawText ( 525 , UI_HEIGHT - 95 , 18 , TA_LEFT , colors . green , COMPLETED_TEXT ) ;
2016-02-13 17:59:18 +01:00
}
2016-02-27 17:16:21 +01:00
else if ( game . currentMission - > epic )
2015-10-20 13:51:49 +02:00
{
2018-12-13 08:59:31 +01:00
drawText ( 525 , UI_HEIGHT - 95 , 18 , TA_LEFT , colors . yellow , EPIC_TEXT ) ;
2016-05-15 12:59:37 +02:00
}
2016-05-15 14:53:19 +02:00
else if ( game . currentMission - > isOptional )
2016-05-15 12:59:37 +02:00
{
2018-12-13 08:59:31 +01:00
drawText ( 525 , UI_HEIGHT - 95 , 18 , TA_LEFT , colors . cyan , OPTIONAL_TEXT ) ;
2015-10-20 13:51:49 +02:00
}
2016-03-09 13:31:33 +01:00
2016-08-11 23:48:08 +02:00
startMissionButton - > enabled = ( ! game . currentMission - > completed | | selectedStarSystem - > type = = SS_SOL | | campaignComplete ) ;
2016-03-09 13:31:33 +01:00
2015-11-24 08:16:48 +01:00
drawWidgets ( " starSystem " ) ;
2018-12-12 09:32:32 +01:00
SDL_SetRenderTarget ( app . renderer , app . backBuffer ) ;
2015-10-20 13:51:49 +02:00
}
2016-02-14 12:53:03 +01:00
static void fallenOK ( void )
{
show = SHOW_GALAXY ;
2016-03-09 13:31:33 +01:00
2016-02-23 23:20:07 +01:00
app . modalDialog . type = MD_NONE ;
2016-02-14 12:53:03 +01:00
}
2016-08-11 23:48:08 +02:00
static void campaignCompleteOK ( void )
{
show = SHOW_GALAXY ;
app . modalDialog . type = MD_NONE ;
campaignComplete = 2 ;
}
2015-10-20 13:51:49 +02:00
static void handleKeyboard ( void )
{
2016-03-05 14:49:07 +01:00
if ( app . keyboard [ SDL_SCANCODE_ESCAPE ] & & ! app . awaitingWidgetInput )
2015-10-20 13:51:49 +02:00
{
switch ( show )
{
2015-11-24 08:16:48 +01:00
case SHOW_GALAXY :
selectWidget ( " resume " , " galacticMap " ) ;
show = SHOW_MENU ;
break ;
2016-03-09 13:31:33 +01:00
2015-11-24 08:16:48 +01:00
case SHOW_STAR_SYSTEM :
show = SHOW_GALAXY ;
break ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
case SHOW_MENU :
show = SHOW_GALAXY ;
break ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
case SHOW_OPTIONS :
case SHOW_STATS :
2016-05-15 09:19:26 +02:00
case SHOW_TROPHIES :
2017-08-12 09:33:06 +02:00
case SHOW_FIGHTER_DB :
2015-10-20 13:51:49 +02:00
show = SHOW_MENU ;
selectWidget ( " resume " , " galacticMap " ) ;
break ;
}
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
playSound ( SND_GUI_CLOSE ) ;
2016-03-09 13:31:33 +01:00
2016-03-05 16:35:09 +01:00
clearInput ( ) ;
2015-10-20 13:51:49 +02:00
}
}
2015-11-24 08:16:48 +01:00
static void handleMouse ( void )
2015-10-20 13:51:49 +02:00
{
2016-02-14 12:07:15 +01:00
if ( app . mouse . button [ SDL_BUTTON_LEFT ] )
2015-10-20 13:51:49 +02:00
{
2016-02-14 12:07:15 +01:00
if ( app . mouse . dx ! = 0 | | app . mouse . dy ! = 0 )
{
scrollingMap = 1 ;
}
}
2016-07-23 16:53:31 +02:00
else
{
scrollingMap = 0 ;
}
2017-05-26 08:47:51 +02:00
2017-05-09 13:08:51 +02:00
setMouseCursor ( app . mouse . button [ SDL_BUTTON_LEFT ] & & show = = SHOW_GALAXY ) ;
2015-10-20 13:51:49 +02:00
}
2015-11-24 08:16:48 +01:00
static void startMission ( void )
2015-10-20 13:51:49 +02:00
{
2015-11-24 08:16:48 +01:00
initBattle ( ) ;
2016-03-09 13:31:33 +01:00
2016-02-27 17:16:21 +01:00
loadMission ( game . currentMission - > filename ) ;
2015-10-20 13:51:49 +02:00
}
static void drawMenu ( void )
{
SDL_Rect r ;
2018-12-13 08:59:31 +01:00
2015-10-20 13:51:49 +02:00
SDL_SetRenderDrawBlendMode ( app . renderer , SDL_BLENDMODE_BLEND ) ;
SDL_SetRenderDrawColor ( app . renderer , 0 , 0 , 0 , 128 ) ;
SDL_RenderFillRect ( app . renderer , NULL ) ;
SDL_SetRenderDrawBlendMode ( app . renderer , SDL_BLENDMODE_NONE ) ;
2018-12-21 08:27:47 +01:00
SDL_SetRenderTarget ( app . renderer , app . uiBuffer ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
r . w = 400 ;
2016-05-15 09:19:26 +02:00
r . h = 500 ;
2018-12-13 08:59:31 +01:00
r . x = ( UI_WIDTH / 2 ) - r . w / 2 ;
r . y = ( UI_HEIGHT / 2 ) - r . h / 2 ;
2016-03-09 13:31:33 +01:00
2018-12-11 09:24:25 +01:00
SDL_SetRenderDrawColor ( app . renderer , 0 , 0 , 0 , 255 ) ;
2015-10-20 13:51:49 +02:00
SDL_RenderFillRect ( app . renderer , & r ) ;
SDL_SetRenderDrawColor ( app . renderer , 200 , 200 , 200 , 255 ) ;
SDL_RenderDrawRect ( app . renderer , & r ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
drawWidgets ( " galacticMap " ) ;
2018-12-13 08:59:31 +01:00
SDL_SetRenderTarget ( app . renderer , app . backBuffer ) ;
2015-10-20 13:51:49 +02:00
}
static void resume ( void )
{
show = SHOW_GALAXY ;
}
static void options ( void )
{
show = SHOW_OPTIONS ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
initOptions ( returnFromOptions ) ;
}
2017-08-12 09:33:06 +02:00
static void fighterDatabase ( void )
{
show = SHOW_FIGHTER_DB ;
initFighterDatabaseDisplay ( ) ;
}
2015-10-20 13:51:49 +02:00
static void stats ( void )
{
selectWidget ( " ok " , " stats " ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
show = SHOW_STATS ;
2016-03-09 13:31:33 +01:00
2015-10-25 01:01:46 +02:00
initStatsDisplay ( ) ;
2015-10-20 13:51:49 +02:00
}
2016-05-15 09:19:26 +02:00
static void trophies ( void )
{
selectWidget ( " ok " , " trophies " ) ;
show = SHOW_TROPHIES ;
initTrophiesDisplay ( ) ;
}
static void ok ( void )
2015-10-20 13:51:49 +02:00
{
selectWidget ( " resume " , " galacticMap " ) ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
show = SHOW_MENU ;
}
static void returnFromOptions ( void )
{
show = SHOW_MENU ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
selectWidget ( " resume " , " galacticMap " ) ;
}
static void quit ( void )
{
initTitle ( ) ;
}
void destroyGalacticMap ( void )
{
Pulse * pulse ;
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
while ( pulseHead . next )
{
pulse = pulseHead . next ;
pulseHead . next = pulse - > next ;
free ( pulse ) ;
}
2016-03-09 13:31:33 +01:00
2015-10-20 13:51:49 +02:00
pulseTail = & pulseHead ;
}