1 extern "C"
2 {
3 #include "3dc.h"
4 #include "ourasert.h"
5 #include "psndplat.h"
6 #include "dxlog.h"
7 #include "cd_player.h"
8 #include "avp_menus.h"
9 #include "gamedef.h"
10
11 #include "avp_envinfo.h"
12 };
13
14 #include "list_tem.hpp"
15
16 //lists of tracks for each level
17 List<int> LevelCDTracks[AVP_ENVIRONMENT_END_OF_LIST];
18
19 //lists of tracks for each species in multiplayer games
20 List<int> MultiplayerCDTracks[3];
21
22 static int LastTrackChosen=-1;
23
24 extern "C"
25 {
26
EmptyCDTrackList()27 void EmptyCDTrackList()
28 {
29 for(int i=0;i<AVP_ENVIRONMENT_END_OF_LIST;i++)
30 {
31 while(LevelCDTracks[i].size()) LevelCDTracks[i].delete_first_entry();
32 }
33
34 for(int i=0;i<3;i++)
35 {
36 while(MultiplayerCDTracks[i].size()) MultiplayerCDTracks[i].delete_first_entry();
37 }
38 }
39
40 #define CDTrackFileName "cd tracks.txt"
41
42
ExtractTracksForLevel(char * & buffer,List<int> & track_list)43 static void ExtractTracksForLevel(char* & buffer,List<int> & track_list)
44 {
45 //search for a line starting with a #
46 while(*buffer)
47 {
48 if(*buffer=='#') break;
49 //search for next line
50 while(*buffer)
51 {
52 if(*buffer=='\n')
53 {
54 buffer++;
55 if(*buffer=='\r') buffer++;
56 break;
57 }
58 buffer++;
59 }
60
61 }
62
63 while(*buffer)
64 {
65 //search for a track number or comment
66 if(*buffer==';')
67 {
68 //comment , so no further info on this line
69 break;
70 }
71 else if(*buffer=='\n' || *buffer=='\r')
72 {
73 //reached end of line
74 break;
75 }
76 else if(*buffer>='0' && *buffer<='9')
77 {
78 int track=-1;
79 //find a number , add it to the list
80 sscanf(buffer,"%d",&track);
81
82 if(track>=0)
83 {
84 track_list.add_entry(track);
85 }
86
87 //skip to the next non numerical character
88 while(*buffer>='0' && *buffer<='9') buffer++;
89 }
90 else
91 {
92 buffer++;
93 }
94 }
95
96 //go to the next line
97 while(*buffer)
98 {
99 if(*buffer=='\n')
100 {
101 buffer++;
102 if(*buffer=='\r') buffer++;
103 break;
104 }
105 buffer++;
106 }
107
108 }
109
LoadCDTrackList()110 void LoadCDTrackList()
111 {
112 //clear out the old list first
113 EmptyCDTrackList();
114
115 FILE *file = OpenGameFile(CDTrackFileName, FILEMODE_READONLY, FILETYPE_OPTIONAL);
116
117 if(file==NULL)
118 {
119 LOGDXFMT(("Failed to open %s",CDTrackFileName));
120 return;
121 }
122
123 char* buffer;
124 int file_size;
125
126 fseek(file, 0, SEEK_END);
127 file_size = ftell(file);
128 rewind(file);
129
130 //copy the file contents into a buffer
131 buffer=new char[file_size+1];
132 fread(buffer, 1, file_size, file);
133 buffer[file_size]='\0';
134 fclose(file);
135
136 char* bufferptr=buffer;
137
138
139 //first extract the multiplayer tracks
140 for(int i=0;i<3;i++)
141 {
142 ExtractTracksForLevel(bufferptr,MultiplayerCDTracks[i]);
143 }
144
145 //now the level tracks
146 for(int i=0 ;i<AVP_ENVIRONMENT_END_OF_LIST;i++)
147 {
148 ExtractTracksForLevel(bufferptr,LevelCDTracks[i]);
149 }
150
151
152 delete [] buffer;
153 }
154
155 static unsigned int TrackSelectCounter=0;
156
PickCDTrack(List<int> & track_list)157 static BOOL PickCDTrack(List<int>& track_list)
158 {
159 //make sure we have some tracks in the list
160 if(!track_list.size()) return FALSE;
161
162 //pick the next track in the list
163 unsigned int index=TrackSelectCounter % track_list.size();
164
165 TrackSelectCounter++;
166
167 //play it
168 CDDA_Stop();
169 CDDA_Play(track_list[index]);
170
171 LastTrackChosen = track_list[index];
172 return TRUE;
173 }
174
175
CheckCDAndChooseTrackIfNeeded()176 void CheckCDAndChooseTrackIfNeeded()
177 {
178 static enum playertypes lastPlayerType;
179
180 //are we bothering with cd tracks
181 if(!CDDA_IsOn()) return;
182 //is our current track still playing
183 if(CDDA_IsPlaying())
184 {
185 //if in a multiplayer game see if we have changed character type
186 if(AvP.Network == I_No_Network || AvP.PlayerType==lastPlayerType)
187 return;
188
189 //have changed character type , is the current track in the list for this character type
190 if(MultiplayerCDTracks[AvP.PlayerType].contains(LastTrackChosen))
191 return;
192
193 //Lets choose a new track then
194 }
195
196
197 if(AvP.Network == I_No_Network)
198 {
199 int level=NumberForCurrentLevel();
200 if(level>=0 && level<AVP_ENVIRONMENT_END_OF_LIST)
201 {
202 //pick track based on level
203 if(PickCDTrack(LevelCDTracks[level]))
204 {
205 return;
206 }
207
208 }
209 }
210
211
212 //multiplayer (or their weren't ant level specific tracks)
213 lastPlayerType=AvP.PlayerType;
214 PickCDTrack(MultiplayerCDTracks[AvP.PlayerType]);
215
216
217 }
218
ResetCDPlayForLevel()219 void ResetCDPlayForLevel()
220 {
221 //check the number of tracks available while we're at it
222 CDDA_CheckNumberOfTracks();
223
224 TrackSelectCounter=0;
225 CDDA_Stop();
226 }
227
228 };
229