OSDN Git Service

イニシャルコミット。
[marathon/ShapeFusion.git] / Sounds / SoundsDocument.cpp
1 /*
2  * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton)
3  *
4  * ShapeFusion is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * ShapeFusion is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with ShapeFusion; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19 // For compilers that support precompilation, includes "wx/wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #include "wx/wx.h"
28 #endif
29
30 #if wxUSE_STD_IOSTREAM
31     #include "wx/ioswrap.h"
32 #else
33     #include "wx/txtstrm.h"
34 #endif
35
36 #include "SoundsDocument.h"
37 #include "SoundsView.h"
38
39 // Construct four-character-code
40 #define FOUR_CHARS_TO_INT(a,b,c,d) (((unsigned int)(a) << 24) | ((unsigned int)(b) << 16) | ((unsigned int)(c) << 8) | (unsigned int)(d))
41
42 enum {
43         _sound_8bit = 0,
44         _sound_16bit,
45         NUMBER_OF_SOUND_SOURCES
46 };
47
48 IMPLEMENT_DYNAMIC_CLASS(SoundsDocument, wxDocument)
49
50 SoundsDocument::SoundsDocument(): wxDocument(), SoundsElement(true), mM2Demo(false)
51 {
52         // We need storage for our sound sources...
53         mSoundDefinitions.resize(NUMBER_OF_SOUND_SOURCES);
54 }
55
56 SoundsDocument::~SoundsDocument()
57 {
58 }
59
60 SoundsDefinition *SoundsDocument::GetSoundDefinition(unsigned short source_index, unsigned short sound_index)
61 {
62         if (source_index > mSoundDefinitions.size())
63                 return NULL;
64         if (sound_index > mSoundDefinitions[source_index].size())
65                 return NULL;
66         return mSoundDefinitions[source_index][sound_index];
67 }
68
69 SoundsDefinition *SoundsDocument::Get8BitSoundDefinition(unsigned short sound_index)
70 {
71         return GetSoundDefinition(_sound_8bit, sound_index);
72 }
73
74 SoundsDefinition *SoundsDocument::Get16BitSoundDefinition(unsigned short sound_index)
75 {
76         return GetSoundDefinition(_sound_16bit, sound_index);
77 }
78
79 void SoundsDocument::AddSoundDefinition(void)
80 {
81         // As there's always two versions (8-bit/16-bit) of the same sound, we add both there...
82         SoundsDefinition        *snd8 = new SoundsDefinition(),
83                                                 *snd16 = new SoundsDefinition();
84
85         // We add 8-bit...
86         mSoundDefinitions[_sound_8bit].push_back(snd8);
87         // ... and 16-bit
88         mSoundDefinitions[_sound_16bit].push_back(snd16);
89         
90         // We mark ourselves as modified...
91         Modify(true);
92 }
93
94 void SoundsDocument::DeleteSoundDefinition(unsigned int index)
95 {
96         // We check we really have that much sounds...
97         if (index > mSoundDefinitions[_sound_8bit].size())
98                 return;
99         
100         // We remove 8-bit version
101         mSoundDefinitions[_sound_8bit].erase(mSoundDefinitions[_sound_8bit].begin() + index);
102         // We remove 16-bit version
103         mSoundDefinitions[_sound_16bit].erase(mSoundDefinitions[_sound_16bit].begin() + index);
104         
105         // We mark ourselves as modified...
106         Modify(true);
107 }
108
109 bool SoundsDocument::DoOpenDocument(const wxString& file)
110 {
111         bool wxOpen = wxDocument::DoOpenDocument(file);
112         
113         if (!(wxOpen && mGoodData)) {
114                 wxLogError(wxT("[SoundsDocument] There was an error while loading, see log"));
115                 return false;
116         }
117         return true;
118 }
119
120 unsigned int SoundsDocument::GetSizeInFile(void)
121 {
122         unsigned int size = SIZEOF_sound_file_header;
123         
124         for (unsigned int i = 0; i < mSoundDefinitions.size(); i++)
125                 for (unsigned int j = 0; j < mSoundDefinitions[i].size(); j++)
126                         size += mSoundDefinitions[i][j]->GetSizeInFile();
127         
128         return size;
129 }
130
131 #if wxUSE_STD_IOSTREAM
132 wxSTD ostream& SoundsDocument::SaveObject(wxSTD ostream& stream)
133 #else
134 wxOutputStream& SoundsDocument::SaveObject(wxOutputStream& stream)
135 #endif
136 {
137         BigEndianBuffer filebuffer(GetSizeInFile());
138         
139         unsigned int source_count = mSoundDefinitions.size();
140         unsigned int sound_count = mSoundDefinitions[0].size();
141         
142         filebuffer.WriteLong(mVersion);
143         filebuffer.WriteLong(mTag);
144         
145         if (mM2Demo) {
146                 filebuffer.WriteShort(mSoundCount);
147                 filebuffer.WriteShort(0);
148         } else {
149                 filebuffer.WriteShort(source_count);
150                 filebuffer.WriteShort(sound_count);
151         }
152         
153         filebuffer.Position(SIZEOF_sound_file_header);
154         
155         unsigned int current_sound_offset = SIZEOF_sound_file_header
156                         + source_count * sound_count * SIZEOF_sound_definition;
157         
158         for (unsigned int i = 0; i < mSoundDefinitions.size(); i++) {
159                 for (unsigned int j = 0; j < mSoundDefinitions[i].size(); j++) {
160                         mSoundDefinitions[i][j]->SaveObject(filebuffer, current_sound_offset);
161                 }
162         }
163         
164 #if wxUSE_STD_IOSTREAM
165         stream.write((char *)filebuffer.Data(), filebuffer.Size());
166 #else
167         stream.Write((char *)filebuffer.Data(), filebuffer.Size());
168 #endif
169
170         return stream;
171 }
172
173 #if wxUSE_STD_IOSTREAM
174 wxSTD istream& SoundsDocument::LoadObject(wxSTD istream& stream)
175 #else
176 wxInputStream& SoundsDocument::LoadObject(wxInputStream& stream)
177 #endif
178 {
179 #if wxUSE_STD_IOSTREAM
180         stream.seekg(0, std::ios::end);
181         wxInt32 filesize = stream.tellg();
182         stream.seekg(0, std::ios::beg);
183 #else
184         wxInt32 filesize = stream.GetSize();
185 #endif
186
187         BigEndianBuffer filebuffer(filesize);
188         
189 #if wxUSE_STD_IOSTREAM
190         stream.read((char *)filebuffer.Data(), filebuffer.Size());
191 #else
192         stream.Read((char *)filebuffer.Data(), filebuffer.Size());
193 #endif
194         
195         mVersion = filebuffer.ReadLong();
196         mTag = filebuffer.ReadLong();
197         mSourceCount = filebuffer.ReadShort();
198         mSoundCount = filebuffer.ReadShort();
199         
200         if ((mVersion != 0 && mVersion != 1) || mTag != FOUR_CHARS_TO_INT('s','n','d','2')) {
201                 wxLogError(wxT("[SoundsDocument] Error loading : Incorrect version/tag, (%d/%x)"), mVersion, mTag);
202                 return stream;
203         }
204         
205         if (mSoundCount < 0 || mSourceCount < 0) {
206                 wxLogError(wxT("[SoundsDocument] Error loading : Incorrect Sound/Source count (%d/%d)"), mSoundCount, mSourceCount);
207                 return stream;
208         }
209         
210         if (mSoundCount == 0) {
211                 /* Handling Marathon 2 Demo
212                  * We have to swap our counts
213                  */
214                 mSoundCount = mSourceCount;
215                 mSourceCount = 1;
216                 mM2Demo = true;
217         }
218         
219         if (IsVerbose()) {
220                 wxLogDebug(wxT("[SoundsDocument] Version:               %d"), mVersion);
221                 wxLogDebug(wxT("[SoundsDocument] Tag:                   %d"), mTag);
222                 wxLogDebug(wxT("[SoundsDocument] Source Count:  %d"), mSourceCount);
223                 wxLogDebug(wxT("[SoundsDocument] Sound Count:   %d"), mSoundCount);
224         }
225         
226         /* We move to the end of the Sound file header */
227         filebuffer.Position(SIZEOF_sound_file_header);
228         
229         /* Now we load 8-bit and 16-bit sounds */
230         for (int i = 0; i < mSourceCount; i++) {
231                 for (int j = 0; j < mSoundCount; j++) {
232                         SoundsDefinition *snd = new SoundsDefinition(IsVerbose());
233                         
234                         if (IsVerbose())
235                                 wxLogDebug(wxT("[SoundsDocument] Loading source %d, sound %d"), i, j);
236                         
237                         unsigned int oldpos = filebuffer.Position();
238                         
239                         snd->LoadObject(filebuffer);
240                         
241                         if (!snd->IsGood()) {
242                                 wxLogError(wxT("[SoundsDocument] Error loading sound definition. Skipping..."));
243                                 return stream;
244                         }
245                         
246                         filebuffer.Position(oldpos + SIZEOF_sound_definition);
247                         
248                         mSoundDefinitions[i].push_back(snd);
249                 }
250         }
251         
252         mGoodData = true;
253         return stream;
254 }
255