OSDN Git Service

ゴミデーターを削除
[marathon/ShapeFusion.git] / ShapeFusionDocManager.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 #include "ShapeFusionDocManager.h"
20
21 #include "BigEndianBuffer.h"
22
23 #include <wx/filename.h>
24 #include <wx/wfstream.h>
25
26 static wxDocTemplate* FindTemplate(wxList& templates, const wxString& description)
27 {
28         for (unsigned int i = 0; i < templates.GetCount(); ++i) {
29                 wxDocTemplate* temp = reinterpret_cast<wxDocTemplate*>(templates.Item(i)->GetData());
30                 if (temp->GetDescription() == description) {
31                         return temp;
32                 }
33         }
34
35         return 0;
36
37
38 wxDocTemplate* ShapeFusionDocManager::FindTemplateForPath(const wxString& path)
39 {
40         // if we recognize the extension, assume it's correct
41         wxFileName filename(path);
42         wxString ext = filename.GetExt();
43         
44         if (ext == wxT("sndA") || ext == wxT("snd2")) {
45                 return ::FindTemplate(GetTemplates(), wxT("Sounds"));
46         } else if (ext == wxT("shpA") || ext == wxT("shp2")) {
47                 return ::FindTemplate(GetTemplates(), wxT("Shapes"));
48         }
49
50         wxFileInputStream stream(path);
51         if (!stream.IsOk()) {
52                 return 0;
53         }
54
55
56         // check for sounds file
57         {
58                 stream.SeekI(0, wxFromStart);
59
60                 unsigned char header[8];
61                 stream.Read(header, 8);
62
63                 BigEndianBuffer buffer(header, 4);
64                 
65                 unsigned long version = buffer.ReadULong();
66                 if ((version == 0 || version == 1) 
67                     && strncmp(reinterpret_cast<const char*>(&header[4]), "snd2", 4) == 0) {
68                         return ::FindTemplate(GetTemplates(), wxT("Sounds"));
69                 }
70         }
71
72         stream.SeekI(0, wxFromEnd);
73         long filesize = stream.TellI();
74         stream.SeekI(0, wxFromStart);
75
76         // check for shapes file
77         {
78                 bool is_shapes = true;
79                 for (int i = 0; i < 32; ++i) {
80                         unsigned char header[32];
81                         stream.Read(header, 32);
82                         
83                         BigEndianBuffer buffer(header, 20);
84                         unsigned long status_flags = buffer.ReadULong();
85                         long offset = buffer.ReadLong();
86                         long length = buffer.ReadLong();
87                         long offset16 = buffer.ReadLong();
88                         long length16 = buffer.ReadLong();
89
90                         if (status_flags != 0
91                             || (offset != -1 && (offset >= filesize || offset + length > filesize))
92                             || (offset16 != -1 && (offset16 >= filesize || offset16 + length16 > filesize))) {
93                                 is_shapes = false;
94                                 break;
95                         }
96                 }
97
98                 if (is_shapes) {
99                         return ::FindTemplate(GetTemplates(), wxT("Shapes"));
100                 }
101         }
102
103         // check for physics
104         {
105                 stream.SeekI(0, wxFromStart);
106                 unsigned char header[128];
107                 stream.Read(header, 128);
108                 
109                 BigEndianBuffer header_buffer(header, 128);
110                 int version = header_buffer.ReadShort();
111                 int data_version = header_buffer.ReadShort();
112                 if ((version == 0 || version == 1 || version == 2 || version == 4) && (data_version == 0 || data_version == 1 || data_version == 2)) {
113                         header_buffer.Position(72);
114                         long directory_offset = header_buffer.ReadLong();
115                         if (directory_offset >= filesize)
116                                 return 0;
117
118                         unsigned char tag[4];
119                         stream.Read(tag, 4);
120                         if (strncmp(reinterpret_cast<const char*>(tag), "MNpx", 4) == 0) {
121                                 return ::FindTemplate(GetTemplates(), wxT("Physics"));
122                         }
123                 }
124         }
125         
126         return 0;       
127 }
128
129 wxDocTemplate* ShapeFusionDocManager::SelectDocumentPath(wxDocTemplate** templates, int noTemplates, wxString& path, long, bool)
130 {
131         wxString pathTmp = wxFileSelector(_("Select a file"),
132                                             m_lastDirectory);
133
134         wxDocTemplate* theTemplate = 0;
135
136         if (!pathTmp.empty()) {
137                 if (!wxFileExists(pathTmp))
138                 {
139                         wxString msgTitle;
140                         if (!wxTheApp->GetAppName().empty()) {
141                                 msgTitle = wxTheApp->GetAppName();
142                         } else {
143                                 msgTitle = wxString(_("File error"));
144                         }
145
146                         (void)wxMessageBox(_("Sorry, could not open this file."), msgTitle, wxOK | wxICON_EXCLAMATION);
147                         
148                         path = wxEmptyString;
149                         return 0;
150                 }
151                 m_lastDirectory = wxPathOnly(pathTmp);
152                 
153                 path = pathTmp;
154
155                 theTemplate = FindTemplateForPath(path);
156                 
157                 if (!theTemplate)
158                 {
159                         (void) wxMessageBox(_("Sorry, the format for this file is unknown."), _("Open File"), wxOK | wxICON_EXCLAMATION);
160                 }
161                 
162                 return FindTemplateForPath(path);
163         } else {
164                 path = wxEmptyString;
165         }
166
167         return theTemplate;
168                                             
169 }