1 /* -*- C++ -*-
2 *
3 * ONScripter_file.cpp - FILE I/O of ONScripter
4 *
5 * Copyright (c) 2001-2018 Ogapee. All rights reserved.
6 *
7 * ogapee@aqua.dti2.ne.jp
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include "ONScripter.h"
25
26 #if defined(LINUX) || defined(MACOSX) || defined(IOS)
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 #include <time.h>
31 #elif defined(WIN32)
32 #include <windows.h>
33 extern "C" { FILE __iob_func[3] = { *stdin,*stdout,*stderr }; }
34 #elif defined(MACOS9)
35 #include <DateTimeUtils.h>
36 #include <Files.h>
37 extern "C" void c2pstrcpy(Str255 dst, const char *src); //#include <TextUtils.h>
38 #elif defined(PSP)
39 #include <pspiofilemgr.h>
40 #endif
41
42 #define SAVEFILE_MAGIC_NUMBER "ONS"
43 #define SAVEFILE_VERSION_MAJOR 2
44 #define SAVEFILE_VERSION_MINOR 8
45
46 #define READ_LENGTH 4096
47
searchSaveFile(SaveFileInfo & save_file_info,int no)48 void ONScripter::searchSaveFile( SaveFileInfo &save_file_info, int no )
49 {
50 char file_name[256];
51
52 script_h.getStringFromInteger( save_file_info.sjis_no, no, (num_save_file >= 10)?2:1 );
53 #if defined(LINUX) || defined(MACOSX) || defined(IOS)
54 sprintf( file_name, "%ssave%d.dat", save_dir?save_dir:archive_path, no );
55 struct stat buf;
56 struct tm *tm;
57 if ( stat( file_name, &buf ) != 0 ){
58 save_file_info.valid = false;
59 return;
60 }
61 time_t mtime = buf.st_mtime;
62 tm = localtime( &mtime );
63
64 save_file_info.month = tm->tm_mon + 1;
65 save_file_info.day = tm->tm_mday;
66 save_file_info.hour = tm->tm_hour;
67 save_file_info.minute = tm->tm_min;
68 #elif defined(WIN32)
69 sprintf( file_name, "%ssave%d.dat", save_dir?save_dir:archive_path, no );
70 HANDLE handle;
71 FILETIME tm, ltm;
72 SYSTEMTIME stm;
73
74 WCHAR file_nameW[256];
75 MultiByteToWideChar(CP_ACP, 0, file_name, -1, file_nameW, 256);
76 handle = CreateFile( file_nameW, GENERIC_READ, 0, NULL,
77 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
78 if ( handle == INVALID_HANDLE_VALUE ){
79 save_file_info.valid = false;
80 return;
81 }
82
83 GetFileTime( handle, NULL, NULL, &tm );
84 FileTimeToLocalFileTime( &tm, <m );
85 FileTimeToSystemTime( <m, &stm );
86 CloseHandle( handle );
87
88 save_file_info.month = stm.wMonth;
89 save_file_info.day = stm.wDay;
90 save_file_info.hour = stm.wHour;
91 save_file_info.minute = stm.wMinute;
92 #elif defined(MACOS9)
93 sprintf( file_name, "%ssave%d.dat", save_dir?save_dir:archive_path, no );
94 CInfoPBRec pb;
95 Str255 p_file_name;
96 FSSpec file_spec;
97 DateTimeRec tm;
98 c2pstrcpy( p_file_name, file_name );
99 if ( FSMakeFSSpec(0, 0, p_file_name, &file_spec) != noErr ){
100 save_file_info.valid = false;
101 return;
102 }
103 pb.hFileInfo.ioNamePtr = file_spec.name;
104 pb.hFileInfo.ioVRefNum = file_spec.vRefNum;
105 pb.hFileInfo.ioFDirIndex = 0;
106 pb.hFileInfo.ioDirID = file_spec.parID;
107 if (PBGetCatInfoSync(&pb) != noErr) {
108 save_file_info.valid = false;
109 return;
110 }
111 SecondsToDate( pb.hFileInfo.ioFlMdDat, &tm );
112 save_file_info.month = tm.month;
113 save_file_info.day = tm.day;
114 save_file_info.hour = tm.hour;
115 save_file_info.minute = tm.minute;
116 #elif defined(PSP)
117 sprintf( file_name, "%ssave%d.dat", save_dir?save_dir:archive_path, no );
118 SceIoStat buf;
119 if ( sceIoGetstat(file_name, &buf)<0 ){
120 save_file_info.valid = false;
121 return;
122 }
123
124 save_file_info.month = buf.st_mtime.month;
125 save_file_info.day = buf.st_mtime.day;
126 save_file_info.hour = buf.st_mtime.hour;
127 save_file_info.minute = buf.st_mtime.minute;
128 #else
129 sprintf( file_name, "save%d.dat", no );
130 FILE *fp;
131 if ( (fp = fopen( file_name, "rb", true )) == NULL ){
132 save_file_info.valid = false;
133 return;
134 }
135 fclose( fp );
136
137 save_file_info.month = 1;
138 save_file_info.day = 1;
139 save_file_info.hour = 0;
140 save_file_info.minute = 0;
141 #endif
142 save_file_info.valid = true;
143 script_h.getStringFromInteger( save_file_info.sjis_month, save_file_info.month, 2 );
144 script_h.getStringFromInteger( save_file_info.sjis_day, save_file_info.day, 2 );
145 script_h.getStringFromInteger( save_file_info.sjis_hour, save_file_info.hour, 2 );
146 script_h.getStringFromInteger( save_file_info.sjis_minute, save_file_info.minute, 2, true );
147 }
148
readSaveStrFromFile(int no)149 char *ONScripter::readSaveStrFromFile( int no )
150 {
151 char filename[32];
152 sprintf( filename, "save%d.dat", no );
153 size_t len = loadFileIOBuf( filename );
154 if (len == 0){
155 fprintf( stderr, "readSaveStrFromFile: can't open save file %s\n", filename );
156 return NULL;
157 }
158
159 int p = len - 1;
160 if ( p < 3 || file_io_buf[p] != '*' || file_io_buf[p-1] != '"' ) return NULL;
161 p -= 2;
162
163 while( file_io_buf[p] != '"' && p>0 ) p--;
164 if ( file_io_buf[p] != '"' ) return NULL;
165
166 len = len - p - 3;
167 char *buf = new char[len+1];
168
169 unsigned int i;
170 for (i=0 ; i<len ; i++)
171 buf[i] = file_io_buf[p+i+1];
172 buf[i] = 0;
173
174 return buf;
175 }
176
loadSaveFile(int no)177 int ONScripter::loadSaveFile( int no )
178 {
179 char filename[32];
180 sprintf( filename, "save%d.dat", no );
181 if (loadFileIOBuf( filename ) == 0){
182 fprintf( stderr, "can't open save file %s\n", filename );
183 return -1;
184 }
185
186 /* ---------------------------------------- */
187 /* Load magic number */
188 int i;
189 for ( i=0 ; i<(int)strlen( SAVEFILE_MAGIC_NUMBER ) ; i++ )
190 if ( readChar() != SAVEFILE_MAGIC_NUMBER[i] ) break;
191
192 if ( i != (int)strlen( SAVEFILE_MAGIC_NUMBER ) ){
193 file_io_buf_ptr = 0;
194 printf("Save file version is unknown\n" );
195 return loadSaveFile2( SAVEFILE_VERSION_MAJOR*100 + SAVEFILE_VERSION_MINOR );
196 }
197
198 int file_version = readChar() * 100;
199 file_version += readChar();
200 printf("Save file version is %d.%d\n", file_version/100, file_version%100 );
201 if ( file_version > SAVEFILE_VERSION_MAJOR*100 + SAVEFILE_VERSION_MINOR ){
202 fprintf( stderr, "Save file is newer than %d.%d, please use the latest ONScripter.\n", SAVEFILE_VERSION_MAJOR, SAVEFILE_VERSION_MINOR );
203 return -1;
204 }
205
206 if ( file_version >= 200 )
207 return loadSaveFile2( file_version );
208
209 fprintf( stderr, "Save file is too old.\n");
210
211 return -1;
212 }
213
saveMagicNumber(bool output_flag)214 void ONScripter::saveMagicNumber( bool output_flag )
215 {
216 for ( unsigned int i=0 ; i<strlen( SAVEFILE_MAGIC_NUMBER ) ; i++ )
217 writeChar( SAVEFILE_MAGIC_NUMBER[i], output_flag );
218 writeChar( SAVEFILE_VERSION_MAJOR, output_flag );
219 writeChar( SAVEFILE_VERSION_MINOR, output_flag );
220 }
221
storeSaveFile()222 void ONScripter::storeSaveFile()
223 {
224 file_io_buf_ptr = 0;
225 saveMagicNumber( false );
226 saveSaveFile2( false );
227 allocFileIOBuf();
228 saveMagicNumber( true );
229 saveSaveFile2( true );
230 save_data_len = file_io_buf_ptr;
231 memcpy(save_data_buf, file_io_buf, save_data_len);
232 }
233
writeSaveFile(int no,const char * savestr)234 int ONScripter::writeSaveFile( int no, const char *savestr )
235 {
236 saveAll();
237
238 char filename[32];
239 sprintf( filename, "save%d.dat", no );
240
241 memcpy(file_io_buf, save_data_buf, save_data_len);
242 file_io_buf_ptr = save_data_len;
243 if (saveFileIOBuf( filename, 0, savestr )){
244 fprintf( stderr, "can't open save file %s for writing\n", filename );
245 return -1;
246 }
247
248 size_t magic_len = strlen(SAVEFILE_MAGIC_NUMBER)+2;
249 sprintf( filename, RELATIVEPATH "sav%csave%d.dat", DELIMITER, no );
250 if (saveFileIOBuf( filename, magic_len, savestr ))
251 fprintf( stderr, "can't open save file %s for writing (not an error)\n", filename );
252
253 return 0;
254 }
255