]> icculus.org git repositories - taylor/freespace2.git/blob - src/missionui/missionloopbrief.cpp
fix issue with looping audio streams
[taylor/freespace2.git] / src / missionui / missionloopbrief.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/MissionUI/MissionLoopBrief.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Campaign Loop briefing screen
16  *
17  * $Log$
18  * Revision 1.4  2004/09/20 01:31:44  theoddone33
19  * GCC 3.4 fixes.
20  *
21  * Revision 1.3  2002/06/09 04:41:23  relnev
22  * added copyright header
23  *
24  * Revision 1.2  2002/05/07 03:16:46  theoddone33
25  * The Great Newline Fix
26  *
27  * Revision 1.1.1.1  2002/05/03 03:28:10  root
28  * Initial import.
29  *
30  * 
31  * 4     9/06/99 9:44p Jefff
32  * break out of loop support
33  * 
34  * 3     9/06/99 6:38p Dave
35  * Improved CD detection code.
36  * 
37  * 2     8/27/99 12:04a Dave
38  * Campaign loop screen.
39  *  
40  *
41  * $NoKeywords: $
42  */
43
44 #include "missionloopbrief.h"
45 #include "missionscreencommon.h"
46 #include "2d.h"
47 #include "bmpman.h"
48 #include "gamesnd.h"
49 #include "eventmusic.h"
50 #include "audiostr.h"
51 #include "key.h"
52 #include "gamesequence.h"
53 #include "missioncampaign.h"
54 #include "animplay.h"
55 #include "freespace.h"
56
57 // ---------------------------------------------------------------------------------------------------------------------------------------
58 // MISSION LOOP BRIEF DEFINES/VARS
59 //
60
61 const char *Loop_brief_fname[GR_NUM_RESOLUTIONS] = {
62         "LoopBrief",            // GR_640
63         "2_LoopBrief",          // GR_1024
64 };
65
66 const char *Loop_brief_mask[GR_NUM_RESOLUTIONS] = {
67         "LoopBrief-m",          // GR_640
68         "2_Loopbrief-m",        // GR_1024
69 };
70
71 #define NUM_LOOP_BRIEF_BUTTONS                          2
72 #define LOOP_BRIEF_DECLINE                                              0
73 #define LOOP_BRIEF_ACCEPT                                               1
74 ui_button_info Loop_buttons[GR_NUM_RESOLUTIONS][NUM_LOOP_BRIEF_BUTTONS] = {
75         { // GR_640
76                 ui_button_info("LBB_00",                529,    437,    -1,     -1,     0),
77                 ui_button_info("LBB_01",                575,    433,    -1,     -1,     1),
78         },
79         { // GR_1024
80                 ui_button_info("2_LBB_00",              846,    699,    -1,     -1,     0),
81                 ui_button_info("2_LBB_01",              920,    693,    -1,     -1,     1),
82         }
83 };
84
85 #define NUM_LOOP_TEXT                                                   2
86 UI_XSTR Loop_text[GR_NUM_RESOLUTIONS][NUM_LOOP_TEXT] = {
87         { // GR_640
88                 { "Decline",            1467,   514,    413,    UI_XSTR_COLOR_PINK,     -1,     &Loop_buttons[0][LOOP_BRIEF_DECLINE].button },
89                 { "Accept",                     1035,   573,    413,    UI_XSTR_COLOR_PINK,     -1,     &Loop_buttons[0][LOOP_BRIEF_ACCEPT].button },
90         },      
91         { // GR_1024
92                 { "Decline",            1467,   855,    670,    UI_XSTR_COLOR_PINK,     -1,     &Loop_buttons[1][LOOP_BRIEF_DECLINE].button },
93                 { "Accept",                     1035,   928,    670,    UI_XSTR_COLOR_PINK,     -1,     &Loop_buttons[1][LOOP_BRIEF_ACCEPT].button },
94         }
95 };
96
97 // loop brief anim
98 int Loop_brief_anim_coords[GR_NUM_RESOLUTIONS][2] = {
99         { // GR_640
100                 24, 267
101         },
102         { // GR_640
103                 167, 491
104         }
105 };
106
107 // text window coords
108 int Loop_brief_text_coords[GR_NUM_RESOLUTIONS][4] = {
109         { // GR_640
110                 25,     107,    591,    143
111         },
112         { // GR_1024
113                 40,     171,    945,    229
114         }
115 };
116
117 UI_WINDOW Loop_brief_window;
118 int Loop_brief_bitmap;
119
120 anim *Loop_anim;
121 anim_instance *Loop_anim_instance;
122
123 int Loop_sound;
124
125 // ---------------------------------------------------------------------------------------------------------------------------------------
126 // MISSION LOOP BRIEF FUNCTIONS
127 //
128
129 // button press
130 void loop_brief_button_pressed(int i)
131 {       
132         switch(i){
133         case LOOP_BRIEF_DECLINE:                
134                 gameseq_post_event(GS_EVENT_START_GAME);
135                 gamesnd_play_iface(SND_USER_SELECT);
136                 break;
137
138         case LOOP_BRIEF_ACCEPT:
139                 // select the loop mission              
140                 Campaign.loop_enabled = 1;
141                 Campaign.loop_reentry = Campaign.next_mission;                  // save reentry pt, so we can break out of loop
142                 Campaign.next_mission = Campaign.loop_mission;          
143
144                 gameseq_post_event(GS_EVENT_START_GAME);
145                 gamesnd_play_iface(SND_USER_SELECT);
146                 break;
147         }
148 }
149
150 // init
151 void loop_brief_init()
152 {
153         int idx;
154         ui_button_info *b;
155
156         // load the background bitmap
157         Loop_brief_bitmap = bm_load(Loop_brief_fname[gr_screen.res]);
158         SDL_assert(Loop_brief_bitmap != -1);
159
160         // window
161         Loop_brief_window.create(0, 0, gr_screen.max_w, gr_screen.max_h, 0);
162         Loop_brief_window.set_mask_bmap(Loop_brief_mask[gr_screen.res]);        
163
164         // add the buttons
165         for (idx=0; idx<NUM_LOOP_BRIEF_BUTTONS; idx++) {
166                 b = &Loop_buttons[gr_screen.res][idx];
167
168                 b->button.create(&Loop_brief_window, "", b->x, b->y, 60, 30, 0, 1);             
169                 b->button.set_highlight_action(common_play_highlight_sound);
170                 b->button.set_bmaps(b->filename);
171                 b->button.link_hotspot(b->hotspot);
172         }
173
174         // add text
175         for(idx=0; idx<NUM_LOOP_TEXT; idx++){
176                 Loop_brief_window.add_XSTR(&Loop_text[gr_screen.res][idx]);
177         }
178
179         // load animation if any
180         Loop_anim = NULL;
181         Loop_anim_instance = NULL;
182         if(Campaign.missions[Campaign.current_mission].mission_loop_brief_anim != NULL){
183                 Loop_anim = anim_load(Campaign.missions[Campaign.current_mission].mission_loop_brief_anim);
184         } else {
185                 Loop_anim = anim_load("CB_default");
186         }
187
188         // fire up an anim instance
189         if(Loop_anim != NULL){
190                 anim_play_struct aps;
191
192                 anim_play_init(&aps, Loop_anim, Loop_brief_anim_coords[gr_screen.res][0], Loop_brief_anim_coords[gr_screen.res][1]);
193                 aps.framerate_independent = 1;
194                 aps.looped = 1;
195                 aps.screen_id = GS_STATE_LOOP_BRIEF;
196                 Loop_anim_instance = anim_play(&aps);
197         }
198
199         // init brief text
200         if(Campaign.missions[Campaign.current_mission].mission_loop_desc != NULL){
201                 brief_color_text_init(Campaign.missions[Campaign.current_mission].mission_loop_desc, Loop_brief_text_coords[gr_screen.res][2]);
202         }
203
204         // open sound
205         if(Campaign.missions[Campaign.current_mission].mission_loop_brief_sound != NULL){
206                 Loop_sound = audiostream_open(Campaign.missions[Campaign.current_mission].mission_loop_brief_sound, ASF_VOICE);
207
208                 if(Loop_sound != -1){
209                         audiostream_play(Loop_sound, Master_voice_volume, 0);
210                 }
211         }
212
213         // music
214         common_music_init(SCORE_BRIEFING);
215 }
216
217 // do
218 void loop_brief_do()
219 {
220         int k;
221         int idx;
222
223         // process keys
224         k = Loop_brief_window.process();        
225
226         switch (k) {
227         case SDLK_ESCAPE:
228                 gameseq_post_event(GS_EVENT_MAIN_MENU);
229                 break;
230         }       
231
232         // process button presses
233         for (idx=0; idx<NUM_LOOP_BRIEF_BUTTONS; idx++){
234                 if (Loop_buttons[gr_screen.res][idx].button.pressed()){
235                         loop_brief_button_pressed(idx);
236                 }
237         }
238         
239         common_music_do();
240
241         // clear
242         GR_MAYBE_CLEAR_RES(Loop_brief_bitmap);
243         if (Loop_brief_bitmap >= 0) {
244                 gr_set_bitmap(Loop_brief_bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
245                 gr_bitmap(0, 0);
246         } 
247         
248         // draw the window
249         Loop_brief_window.draw();               
250
251         // render the briefing text
252         brief_render_text(0, Loop_brief_text_coords[gr_screen.res][0], Loop_brief_text_coords[gr_screen.res][1], Loop_brief_text_coords[gr_screen.res][3], flFrametime);
253
254         // render all anims
255         anim_render_all(GS_STATE_LOOP_BRIEF, flFrametime);
256
257         gr_flip();
258 }
259
260 // close
261 void loop_brief_close()
262 {
263         // this makes sure that we're all cool no matter how the user decides to exit
264         mission_campaign_mission_over();
265
266         // free the bitmap
267         if (Loop_brief_bitmap >= 0){
268                 bm_unload(Loop_brief_bitmap);
269         }               
270         Loop_brief_bitmap = -1;
271
272         // destroy the window
273         Loop_brief_window.destroy();
274
275         // free up anim stuff
276         if(Loop_anim_instance != NULL){
277                 anim_release_render_instance(Loop_anim_instance);
278                 Loop_anim_instance = NULL;
279         }
280         if(Loop_anim != NULL){
281                 anim_free(Loop_anim);
282                 Loop_anim = NULL;
283         }
284
285         // stop voice
286         if(Loop_sound != -1){
287                 audiostream_stop(Loop_sound);
288                 audiostream_close_file(Loop_sound);
289                 Loop_sound = -1;
290         }
291
292         // stop music
293         common_music_close();
294 }