Mercurial > otakunoraifu
annotate scn2k/scn2k_impl.cc @ 66:d112357a0ec1
Fix a bug with savegames introduced with changeset c7bcc0ec2267.
Warning: savegames created since c7bcc0ec2267 are probably corrupted,
you may have to start the game over.
If you chose not to do so, you should replace all occurrences of 'TextWindow' by 'TextImplWindow',
and 'Text Window' by 'TextImpl Window' in your save files.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Sat, 11 Dec 2010 18:36:20 +0100 |
parents | 4416cfac86ae |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * Copyright (c) 2004-2006 Kazunori "jagarl" Ueno | |
3 * All rights reserved. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions | |
7 * are met: | |
8 * 1. Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright | |
11 * notice, this list of conditions and the following disclaimer in the | |
12 * documentation and/or other materials provided with the distribution. | |
13 * 3. The name of the author may not be used to endorse or promote products | |
14 * derived from this software without specific prior written permission. | |
15 * | |
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 */ | |
27 | |
28 #include <stdexcept> | |
52 | 29 #include "scn2k_impl.h" |
30 #include "system/file.h" | |
31 #include "system/system_config.h" | |
32 #include "window/picture.h" | |
33 #include "window/system.h" | |
0 | 34 |
35 // #define DEBUG 1 | |
36 | |
37 using namespace std; | |
38 | |
39 /********************************************** | |
40 ** Scn2k | |
41 */ | |
42 | |
43 void kconv(const unsigned char* src, unsigned char* dest); | |
44 void kconv_rev(const unsigned char* src, unsigned char* dest); | |
45 string kconv(const string& s); | |
46 string kconv_rev(const string& s); | |
47 | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
48 Scn2k::Scn2k(Event::Container& _event, PicContainer& _parent) : |
0 | 49 Event::Time(_event), |
50 event(_event), | |
51 parent(_parent), | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
52 text_exec(_event, _parent), |
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
53 grp_exec(_event, _parent, flag, flag.cgm_data) |
0 | 54 { |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
55 config = AyuSysConfig::GetInstance(); |
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
56 |
0 | 57 system_version = 0; |
58 skip_mode = SKIP_NO; | |
59 | |
52 | 60 script_start = NULL; |
61 script = NULL; | |
62 script_end = NULL; | |
0 | 63 |
64 backlog_script_scn = -1; | |
52 | 65 backlog_script_start = NULL; |
66 backlog_script_end = NULL; | |
0 | 67 |
68 save_scn = 0; | |
69 save_point = 0; | |
70 scn_number = 0; | |
71 scn_point = 0; | |
72 cmd_stack_str = cmd_stack_str_orig; | |
73 | |
52 | 74 dialog = NULL; |
0 | 75 dialog_type = CMD_NOP; |
52 | 76 menu = NULL; |
0 | 77 menu_mouseshown = false; |
78 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
79 /* マウスカーソルを作成 */ |
0 | 80 mouse_type = 0; |
52 | 81 mouse_surface = NULL; |
0 | 82 mouse_pressed = 0; |
83 ShowCursor(); | |
84 | |
85 LoadSys(); | |
86 text_exec.InitWindow(); | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
87 grp_exec.InitSel(); |
0 | 88 } |
89 | |
90 Scn2k::~Scn2k() { | |
50 | 91 if (script_start) delete[] script_start; |
0 | 92 HideCursor(); |
93 SaveSys(); | |
94 } | |
95 | |
96 char* Scn2k::OpenScript(int new_scn_number, char*& end, int* call_vec, int& system_version) { | |
97 char fname[1024]; | |
98 const char* data; | |
99 char* ret_data; | |
100 int offset = 0; | |
101 int scenario_magic; | |
102 | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
103 FileSearcher* file_searcher = FileSearcher::GetInstance(); |
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
104 |
0 | 105 sprintf(fname, "SEEN%04d.TXT", new_scn_number); |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
106 ARCINFO* info = file_searcher->Find(FileSearcher::SCN, fname, ""); |
52 | 107 if (info == NULL) goto err; |
0 | 108 data = info->Read(); |
109 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
110 /* version 確認 */ |
0 | 111 scenario_magic = read_little_endian_int(data + 4); |
112 if (scenario_magic != 0x2712 && scenario_magic != 0x1adb2) { | |
113 fprintf(stderr,"Invalid scenario header : scenario number %d\n",new_scn_number); | |
114 goto err; | |
115 } | |
116 if (read_little_endian_int(data) == 0x1cc) { | |
117 system_version = 0; | |
118 offset = 0x1cc + read_little_endian_int(data+0x20) + 4; | |
119 } else if (read_little_endian_int(data) == 0x1d0) { | |
120 system_version = 1; | |
121 offset = read_little_endian_int(data + 0x20); | |
122 } else { | |
123 fprintf(stderr,"Invalid scenario header : scenario number %d\n",new_scn_number); | |
124 goto err; | |
125 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
126 /* header から subroutine number とりだし */ |
0 | 127 if (call_vec) { |
128 int i; | |
129 for (i=0; i<100; i++) { | |
130 call_vec[i] = read_little_endian_int(data + 0x34 + i * 4); | |
131 } | |
132 } | |
133 ret_data = new char[info->Size() - offset + 1024]; | |
134 memcpy(ret_data, data+offset, info->Size()-offset); | |
135 memset(ret_data+info->Size()-offset, 0, 1024); | |
136 end = ret_data + info->Size() - offset; | |
137 delete info; | |
138 return ret_data; | |
139 | |
140 err: | |
141 delete info; | |
142 fprintf(stderr,"Cannot open scenario number %d\n",new_scn_number); | |
143 throw std::invalid_argument("Scn2k::OpenScript"); | |
144 | |
145 return false; | |
146 } | |
52 | 147 |
0 | 148 bool Scn2k::ChangeScript(int new_scn_number, int call_no) { |
149 int old_scn_number = scn_number; | |
150 int old_scn_pt = script - script_start; | |
151 int scn_pt = 0; | |
152 | |
153 if (script_start) delete[] script_start; | |
52 | 154 script_start = NULL; |
155 script = NULL; | |
156 script_end = NULL; | |
0 | 157 |
158 int call_vec[100]; | |
159 | |
160 try { | |
161 script_start = OpenScript(new_scn_number, script_end, call_vec, system_version); | |
162 } catch(...) { | |
163 fprintf(stderr,"\tFrom script %d pt %d\n",old_scn_number, old_scn_pt); | |
164 throw; | |
165 } | |
166 if (call_no > 0 && call_no < 100) { | |
167 scn_pt = call_vec[call_no]; | |
168 if (scn_pt == 0) { | |
169 fprintf(stderr,"Invalid subroutine number: scn %d sub %d\n",new_scn_number, call_no); | |
170 scn_pt = 0; | |
171 } | |
172 } else if (call_no < 0) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
173 scn_pt = -call_no; // デバッグ用 |
0 | 174 } |
175 | |
176 scn_number = new_scn_number; | |
177 scn_point = scn_pt; | |
178 script = script_start + scn_pt; | |
179 if (script < script_start || script >= script_end) | |
180 fprintf(stderr,"scn %d pt %d: Cannot jump to %d:%d; fall back to the top\n",old_scn_number, old_scn_pt, scn_number, scn_pt); | |
181 return true; | |
182 } | |
52 | 183 |
0 | 184 bool Scn2k::ReadCmdAt(Cmd& cmd, int scn, int pt) { |
185 const char* d; | |
52 | 186 if (scn == scn_number) { |
0 | 187 d = script_start + pt; |
188 if (d < script_start || d >= script_end) { | |
189 fprintf(stderr,"Cannot read script at current scn %d pt %d\n", scn, pt); | |
190 return false; | |
191 } | |
192 } else { | |
193 if (backlog_script_scn != scn) { | |
194 if (backlog_script_start) delete[] backlog_script_start; | |
195 backlog_script_start = OpenScript(scn, backlog_script_end, 0, system_version); | |
196 } | |
197 d = backlog_script_start + pt; | |
198 if (d < backlog_script_start || d >= backlog_script_end) { | |
199 fprintf(stderr,"Cannot read script at scn %d pt %d\n", scn, pt); | |
200 return false; | |
201 } | |
202 } | |
203 | |
204 cmd.GetCmd(flag, d); | |
205 return true; | |
206 } | |
207 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
208 extern bool save_req, load_req; // キーボードからセーブ・ロードできるように |
0 | 209 extern bool pressAreq; |
210 | |
211 void Scn2k::Elapsed(unsigned int current_time) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
212 SetWakeup(current_time + 10); // 10msに一回シナリオスクリプト解釈 |
52 | 213 if (script == NULL) return; |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
214 //VarInfo info; info.type = 6; info.number = 0; // PB の「一回ゲームを開始したことがある」フラグ |
0 | 215 //flag.Set(info,1); |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
216 //info.type = 0; info.number = 604; // Princess Bride: クリア対象設定フラグ (聖) |
0 | 217 //flag.Set(info, 1); |
218 | |
219 | |
220 Cmd cmd(flag, system_version); | |
221 int cnt1; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
222 int cnt2 = 1000; // flag / jump / flag 系コマンドの最大実行回数 |
0 | 223 |
224 /* XXX */ | |
225 if (save_req) { | |
226 save_req = false; | |
227 load_req = false; | |
228 cmd.cmd_type = CMD_SAVEREQ; | |
229 } else if (load_req) { | |
230 load_req = false; | |
231 save_req = false; | |
232 cmd.cmd_type = CMD_LOADREQ; | |
233 } | |
234 if (pressAreq) { | |
235 pressAreq = false; | |
236 LoadRollback(cmd); | |
237 return; | |
238 } | |
239 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
240 /* キー入力などに対応 */ |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
241 // メニュー内以外で shift キーが押されたらスキップ開始 |
0 | 242 if ( (skip_mode&SKIP_IN_MENU) == 0) { |
243 if (event.pressed(KEY_SHIFT)) { | |
244 if (skip_mode & SKIP_TEXT) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
245 ; // スキップ中ならなにもしない |
0 | 246 } else { |
247 SetSkipMode(SkipMode(SKIP_TEXT | SKIP_GRP_NOEFFEC | SKIPEND_KEY)); | |
248 } | |
249 } else { | |
250 if ( skip_mode & SKIPEND_KEY) { | |
251 if ( (skip_mode & SKIPEND_TEXT) && (skip_mode & SKIP_TEXT)) { | |
252 SkipMode new_skip_mode = SkipMode(skip_mode & (~SKIPEND_KEY)); | |
253 if ( (new_skip_mode & SKIP_GRP_FAST) || (new_skip_mode & SKIP_GRP_NODRAW)) { | |
254 new_skip_mode = SkipMode(skip_mode & (~SKIP_GRP_NOEFFEC)); | |
255 } | |
256 SetSkipMode(new_skip_mode); | |
257 } else { | |
258 SetSkipMode(SKIP_NO); | |
259 } | |
260 } | |
261 } | |
262 } | |
263 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
264 for (cnt1=0; cnt1<20; cnt1++) { // 一回につき 20 個のコマンド実行 |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
265 // 他のコマンド実行中なら終了 |
0 | 266 if ( (cmd.cmd_type == CMD_NOP && SysWait(cmd)) || |
267 // (cmd.cmd_type == CMD_NOP && text_exec.Wait(current_time, cmd)) || | |
268 // (cmd.cmd_type == CMD_NOP && grp_exec.Wait(current_time, cmd))) { | |
269 (cmd.cmd_type == CMD_NOP && grp_exec.Wait(current_time, cmd)) || | |
270 (cmd.cmd_type == CMD_NOP && text_exec.Wait(current_time, cmd))) { | |
271 break; | |
272 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
273 // コマンド読み込み |
0 | 274 for (; cnt2 > 0; cnt2--) { |
275 scn_point = script - script_start; | |
276 eprintf("%d / %d :", script - script_start, script_end-script_start); | |
277 // fprintf(stderr,"%d: %d / %d :",scn_number, script - script_start, script_end-script_start); | |
278 cmd.GetCmd(flag, script); | |
279 // if (cmd.cmd_type != CMD_NOP) { | |
280 if (0) { | |
281 fprintf(stderr,"%d / %d : 0x23 - cmd %02x-%02x:%04x:%02x[%2d] \n", | |
282 scn_point, script_end-script_start, | |
283 cmd.cmd1,cmd.cmd2,cmd.cmd3,cmd.cmd4,cmd.argc); | |
52 | 284 int i; |
285 for (i = 0; i<cmd.args.size(); i++) { | |
0 | 286 if (i == 0) fprintf(stderr,"\t"); |
287 VarInfo info = cmd.args[i]; | |
288 if (info.type == TYPE_STR || info.type == TYPE_VARSTR) | |
289 fprintf(stderr,"\"%s\",", cmd.Str(info)); | |
290 else | |
291 fprintf(stderr,"%d,",info.value); | |
292 } | |
293 fprintf(stderr,"\n"); | |
294 } | |
295 cmd.scn = scn_number; | |
296 cmd.pos = scn_point; | |
297 if (cmd.IsError()) break; | |
298 if (cmd.cmd_type == CMD_NOP) continue; | |
299 if (cmd.cmd_type == CMD_JMP) { | |
300 // local jump | |
301 if (cmd.cmd1 == 0 && cmd.cmd2 == 1 && cmd.cmd3 == 16) { | |
302 int i; | |
303 for (i=0; i<cmd.args.size()-1; i++) { | |
304 VarInfo var; | |
305 var.type = 11; | |
306 var.number = i; | |
307 flag.Set(var, cmd.args[i].value); | |
308 } | |
309 cmd.args[0].value = cmd.args[i].value; | |
310 } | |
311 if ( cmd.cmd1 == 0 && cmd.cmd2 == 1 && (cmd.cmd3 == 5 || cmd.cmd3 == 8 || cmd.cmd3 == 16) ) { // local call / simple switch | |
312 int scn_pt = script - script_start; | |
313 // fprintf(stderr,"\nlocal call %d:%d from %d\n",scn_number,cmd.args[0].value,scn_pt); | |
314 stack.push_back(StackItem(-1, scn_pt)); | |
315 } | |
52 | 316 if (cmd.cmd1 == 0 && cmd.cmd2 == 1 && cmd.cmd3 == 1) {//TODO |
0 | 317 fprintf(stderr,"*** unsupported: cond 1\n"); |
318 } | |
319 script = script_start + cmd.args[0].value; | |
320 if (script < script_start || script >= script_end) { | |
43
01aa5ddf7dc8
A lot of very minor improvements (deleted some unused variables, and other things like that...)
thib
parents:
19
diff
changeset
|
321 fprintf(stderr,"scn %d pt %d: Cannot jump to %d; fall back to the top\n", scn_number, scn_point, cmd.args[0].value); |
0 | 322 script = script_start; |
323 } | |
324 cmd.clear(); | |
325 continue; | |
326 } | |
327 if (flag.Exec(cmd)) continue; | |
328 break; | |
329 } | |
330 if (cmd.IsError()) { | |
331 fprintf(stderr,"cmd error occured: scn %d pt %d / cur %d",scn_number,scn_point,script-script_start); | |
332 while(script < script_end) { | |
333 if (*script == 0x29 && script[1] == 0x0a) {script++;break;} | |
334 if (*script == 0 && script[1] == 0x0a) {script++;break;} | |
335 if (*script == 0 && script[1] == 0x23) {script++;break;} | |
336 script++; | |
337 fprintf(stderr," -> fall back to %d\n",script-script_start); | |
338 } | |
339 const char* dprev = script - 0x60; | |
340 if (dprev < script_start) dprev = script_start; | |
341 int ilen = (script-dprev+65)/16; | |
342 int i; for (i=0; i<ilen; i++) { | |
343 fprintf(stderr, "%6d: ",dprev-script_start); | |
344 int j; for (j=0; j<16; j++) { | |
345 if (dprev >= script_end) break; | |
346 fprintf(stderr, "%02x ",*(unsigned char*)(dprev)); | |
347 dprev++; | |
348 } | |
349 fprintf(stderr, "\n"); | |
350 } | |
351 break; | |
352 } | |
52 | 353 |
0 | 354 if (cmd.cmd_type == CMD_NOP) continue; |
355 | |
356 if (cmd.cmd_type == CMD_TEXT && cmd.pos != -1) { | |
357 set<int>& readflag = text_readflag[scn_number]; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
358 if (readflag.find(cmd.pos) == readflag.end()) { // 未読テキスト発見 |
0 | 359 readflag.insert(cmd.pos); |
360 if (skip_mode & SKIPEND_TEXT) { | |
361 if (!(skip_mode & SKIPEND_KEY)) SetSkipMode(SKIP_NO); | |
362 } | |
363 } | |
364 } | |
365 text_exec.Exec(cmd); | |
366 grp_exec.Exec(cmd); | |
367 SysExec(cmd); | |
368 if (cmd.cmd_type == CMD_WAITFRAMEUPDATE) { | |
369 SetWakeup(Event::Time::FRAME_UPDATE); | |
370 break; | |
371 } else if (cmd.cmd_type != CMD_NOP) { | |
372 #if DEBUG | |
373 fprintf(stderr,"%d-%d / %d : unsupported command; 0x23 - cmd %02x-%02x:%04x:%02x[%2d] \n", | |
374 cmd.scn, script - script_start, script_end-script_start, | |
375 cmd.cmd1,cmd.cmd2,cmd.cmd3,cmd.cmd4,cmd.argc); | |
52 | 376 int i; |
377 for (i = 0; i<cmd.args.size(); i++) { | |
0 | 378 if (i == 0) fprintf(stderr,"\t"); |
379 VarInfo info = cmd.args[i]; | |
380 if (info.type == TYPE_STR || info.type == TYPE_VARSTR) | |
381 fprintf(stderr,"\"%s\",", cmd.Str(info)); | |
382 else | |
383 fprintf(stderr,"%d,",info.value); | |
384 } | |
385 fprintf(stderr,"\n"); | |
386 #endif | |
387 cmd.clear(); | |
388 } | |
389 } | |
390 } | |
391 | |
392 void Scn2k::ShowCursor(void) { | |
393 HideCursor(); | |
394 char key[1024]; | |
57 | 395 sprintf(key, "#MOUSE_CURSOR.%03d.NAME", mouse_type); |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
396 const char* name = config->GetParaStr(key); |
52 | 397 if (name == NULL || name[0] == 0) mouse_surface = DEFAULT_MOUSECURSOR; |
57 | 398 else |
61
bdd8a5ff8f46
Revert an old change that disabled cursors...
Thibaut GIRKA <thib@sitedethib.com>
parents:
57
diff
changeset
|
399 mouse_surface = parent.Root().NewSurface(name, COLOR_MASK); |
57 | 400 if (mouse_surface == NULL) |
401 mouse_surface = DEFAULT_MOUSECURSOR; | |
0 | 402 System::Main::SetCursor(mouse_surface, Rect(8, 8, 8+32, 8+32)); |
403 } | |
404 | |
405 void Scn2k::HideCursor(void) { | |
406 if (mouse_surface) { | |
407 System::Main::SetCursor(0, Rect(0,0)); | |
408 if (mouse_surface != DEFAULT_MOUSECURSOR) | |
409 parent.Root().DeleteSurface(mouse_surface); | |
52 | 410 mouse_surface = NULL; |
0 | 411 } |
412 } | |
413 | |
414 bool Scn2k::SysWait(Cmd& cmd) { | |
415 if (menu) { | |
416 menu->Exec(cmd); | |
52 | 417 if (menu->status & Scn2kMenu::MENU_DELETE || menu->pimpl == NULL) { |
0 | 418 delete menu; |
52 | 419 menu = NULL; |
0 | 420 if (! menu_mouseshown) HideCursor(); |
421 else ShowCursor(); | |
422 SetSkipMode(SkipMode(skip_mode & (~SKIP_IN_MENU) )); | |
423 } | |
424 if (cmd.cmd_type == CMD_NOP) return true; | |
425 else return false; /* exec command */ | |
426 } | |
427 return false; | |
428 } | |
429 | |
430 void DllCall_LB(Cmd& cmd, Flags& flags); | |
431 void Scn2k::SysExec(Cmd& cmd) { | |
432 if (cmd.cmd_type == CMD_SYSVAR) { | |
433 int i; | |
434 for (i=0; i<cmd.args.size(); i++) { | |
435 if (cmd.args[i].type == TYPE_SYS) { | |
436 if (cmd.args[i].number == TYPE_SYS_SYS) { | |
437 flag.SetSys(cmd.args[i].value); | |
438 } else if (cmd.args[i].number == TYPE_SYS_SKIPMODE) { | |
439 SetSkipMode(SkipMode(cmd.args[i].value)); | |
440 } | |
441 } else if (cmd.args[i].type == TYPE_VARSTR) { | |
442 flag.SetStr(cmd.args[i].number, cmd.Str(cmd.args[i])); | |
443 } else { | |
444 flag.Set(cmd.args[i], cmd.args[i].value); | |
445 } | |
446 } | |
447 cmd.clear(); | |
448 } | |
449 if (cmd.cmd_type == CMD_SAVEPOINT || cmd.cmd_type == CMD_ROLLBACKPOINT) { | |
450 if (text_exec.backlog_item.scn != -1) { | |
451 text_exec.backlog.push_back(text_exec.backlog_item); | |
452 text_exec.backlog_item.Clear(); | |
453 } | |
454 save_scn = scn_number; | |
455 save_point = scn_point; | |
456 if (!new_rollback_save.empty()) { | |
457 rollback_save.push_back(new_rollback_save); | |
458 new_rollback_save = ""; | |
459 } | |
460 if (cmd.cmd_type == CMD_ROLLBACKPOINT) SaveRollback(); | |
461 cmd.clear(); | |
462 } | |
463 if (cmd.cmd_type == CMD_SAVEREQ || cmd.cmd_type == CMD_SAVE) { | |
464 Save(cmd); | |
465 return; | |
466 } | |
467 if (cmd.cmd_type == CMD_LOADREQ || cmd.cmd_type == CMD_LOAD) { | |
468 Load(cmd); | |
469 return; | |
470 } | |
471 if (cmd.cmd_type == CMD_BACKLOGREQ || cmd.cmd_type == CMD_BACKLOGREQ_FWD) { | |
472 if (menu) { | |
473 fprintf(stderr,"BACKLOG_REQ requested!!!\n"); | |
474 return; | |
475 } | |
476 if (cmd.cmd_type == CMD_BACKLOGREQ_FWD) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
477 cmd.clear(); // backlog mode 以外で fwd を押されてもなにもしない |
0 | 478 return; |
479 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
480 SetSkipMode(SKIP_IN_MENU); // テキストスキップ等はここで中断 |
0 | 481 menu = new Scn2kMenu(Scn2kMenu::MENU_BACKLOG, *this, flag, text_exec, system_version); |
482 menu->InitPanel(event, parent); | |
483 menu->InitTitle(Scn2kSaveTitle(*this)); | |
484 if (mouse_surface) menu_mouseshown = true; | |
485 else menu_mouseshown = false; | |
486 ShowCursor(); | |
487 return; | |
488 } | |
489 if (cmd.cmd_type == CMD_MENUREQ) { | |
490 int scn=0, pt=0; | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
491 config->GetParam("#CANCELCALL", 2, &scn, &pt); |
0 | 492 if (scn) { |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
493 // 右クリックされたら global call を行う |
0 | 494 cmd.cmd_type = CMD_OTHER; |
495 cmd.cmd1 = 0; | |
496 cmd.cmd2 = 1; | |
497 cmd.cmd3 = 0x0c; | |
498 cmd.cmd4 = 1; | |
499 cmd.args.clear(); | |
500 cmd.args.push_back(VarInfo(SCN_INFO_MENU)); | |
501 cmd.args.push_back(0); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
502 SetSkipMode(SKIP_IN_MENU); // テキストスキップ等はここで中断 |
0 | 503 } |
504 } | |
505 if (cmd.cmd_type == CMD_SAVECMDGRP || cmd.cmd_type == CMD_SAVECMDGRP_START || cmd.cmd_type == CMD_SAVECMDGRP_ONCE || cmd.cmd_type == CMD_SAVECMD_ONCE) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
506 // 画像コマンド等はスタックに保存し、セーブ時に保存できるようにする |
0 | 507 if (cmd.cmd_type == CMD_SAVECMDGRP_START) { |
508 vector<CmdSimplified>::iterator it, cur; | |
509 cur = cmd_stack.begin(); | |
510 cmd_stack_str = cmd_stack_str_orig; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
511 /* 画像関連コマンド以外を別にする */ |
0 | 512 for (it=cmd_stack.begin(); it != cmd_stack.end(); it++) { |
513 if (it->type != CMD_SAVECMDGRP && it->type != CMD_SAVECMDGRP_START && it->type != CMD_SAVECMDGRP_ONCE) { | |
514 cur->copy(*it, cmd_stack_str); | |
515 cur++; | |
516 } | |
517 } | |
518 cmd_stack.erase(cur, cmd_stack.end()); | |
519 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
520 if (cmd.cmd_type == CMD_SAVECMD_ONCE || cmd.cmd_type == CMD_SAVECMDGRP_ONCE) { // 同じコマンドがあれば削除する |
0 | 521 vector<CmdSimplified>::iterator it; |
522 for (it = cmd_stack.end(); it != cmd_stack.begin(); ) { | |
523 --it; | |
524 if (it->cmd1 == cmd.cmd1 && it->cmd2 == cmd.cmd2 && it->cmd3 == cmd.cmd3 && it->cmd4 == cmd.cmd4) { | |
525 cmd_stack.erase(it); | |
526 break; | |
527 } | |
528 } | |
529 } | |
530 CmdSimplified cmd_item; | |
531 cmd.write(cmd_item, cmd_stack_str); | |
532 cmd_stack.push_back(cmd_item); | |
533 cmd.clear(); | |
534 if (cmd_stack_str > cmd_stack_str_orig + 30000) { // char cmd_stack_str_orig[32768] | |
535 fprintf(stderr,"Error in Scn2k::SysExec: too long cmdstack (%d): stack string overflow\n",cmd_stack.size()); | |
536 cmd_stack_str = cmd_stack_str_orig; | |
537 cmd_stack.clear(); | |
538 } | |
539 } | |
540 if (cmd.cmd_type != CMD_OTHER) return; | |
541 if (cmd.cmd1 == 0 && cmd.cmd2 == 1) { | |
542 if (cmd.cmd3 == 0x0b) { // global jump | |
6 | 543 int call_no = 0; |
15 | 544 if (cmd.args.size() >= 2) call_no = cmd.args[1].value; |
0 | 545 eprintf("global jump to %d\n",cmd.args[0].value); |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
546 if (! ChangeScript(cmd.args[0].value, call_no)) return; // 読み込めない; abort. |
0 | 547 cmd.clear(); |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
548 } else if (cmd.cmd3 == 0x0c || cmd.cmd3 == 0x12) { // call (0x12 の方は微妙) |
0 | 549 int new_scn = cmd.args[0].value; |
550 int new_pt = 0; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
551 if (cmd.args.size() >= 2) { // subroutine number が付く |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
552 // 引数が付くのもあるらしい |
0 | 553 new_pt = cmd.args[1].value; |
554 } | |
555 if (new_scn == SCN_INFO_MENU) { // menu call | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
556 config->GetParam("#CANCELCALL", 2, &new_scn, &new_pt); |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
557 stack.push_back(StackItem(SCN_INFO, SCN_INFO_MENU)); // menu call を示す特殊な記号 |
0 | 558 } else { |
559 int i; | |
560 VarInfo var; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
561 // ローカル変数を伴う subroutine call |
0 | 562 var.type = 11; |
563 var.number = 0; | |
564 int saved_vars = 0; | |
565 for (i=0; i<40; i++) { | |
566 int val = flag.Get(var.type, i); | |
567 if (val != 0) { | |
568 stack.push_back(StackItem(SCN_INFO_LOCALS + i, val)); | |
569 saved_vars++; | |
570 } | |
571 } | |
572 var.type = TYPE_VARLOCSTR; | |
573 for (i=0; i<3; i++) { | |
574 string s = flag.Str(var.type, i); | |
575 if (s.size()) { | |
576 int sp = stack_strbuffer.size(); | |
577 stack.push_back(StackItem(SCN_INFO_LOCALSTR+i, sp)); | |
578 stack_strbuffer.push_back(s); | |
579 saved_vars++; | |
580 } | |
581 } | |
582 stack.push_back(StackItem(SCN_INFO, SCN_INFO_LOCALS + saved_vars)); | |
583 | |
584 var.type = 11; | |
585 var.number = 0; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
586 // 特殊な subroutine call なので、余計な情報を引数に渡す |
0 | 587 for (i=2; i<cmd.args.size(); i++) { |
588 flag.Set(var, cmd.args[i].value); | |
589 // fprintf(stderr,"<%d:%d>=%d;",var.type,var.number,cmd.args[i].value); | |
590 var.number++; | |
591 } | |
592 // fprintf(stderr,"%d; ",stack.size()); | |
593 } | |
594 int scn_pt = script - script_start; | |
595 stack.push_back(StackItem(scn_number, scn_pt)); | |
596 // fprintf(stderr,"\nglobal call %d:%d from %d:%d\n",new_scn,new_pt,scn_number,scn_pt); | |
597 eprintf("global call to %d, %d\n",new_scn, new_pt); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
598 if (! ChangeScript(new_scn, new_pt)) return; // 読み込めない; abort. |
0 | 599 cmd.clear(); |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
600 } else if (cmd.cmd3 == 0x65) { // 文字列の返り値をセットする |
0 | 601 int arg1 = cmd.args[0].value; |
602 string s = cmd.Str(cmd.args[1]); | |
603 int sp = stack_strbuffer.size(); | |
604 stack.push_back(StackItem(SCN_INFO_RETSTR+arg1, sp)); | |
605 stack_strbuffer.push_back(s); | |
606 cmd.clear(); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
607 } else if (cmd.cmd3 == 0x0d || cmd.cmd3 == 0x0a || cmd.cmd3 == 0x11 || cmd.cmd3 == 0x13) { // return (0a: local return) (0x13はよくわからない) |
0 | 608 // fprintf(stderr,"global return : stack size %d\n",stack.size()); |
609 if (stack.empty()) { | |
610 cmd.clear(); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
611 return; // スタックがおかしい:abort |
0 | 612 } |
613 map<int, string> retstr; | |
614 while( (!stack.empty()) && stack.back().scn_number >= SCN_INFO_RETSTR) { | |
615 int ret_num = stack.back().scn_number - SCN_INFO_RETSTR; | |
616 // fprintf(stderr,"\nRetStr;"); | |
617 string str = stack_strbuffer.back(); | |
618 stack_strbuffer.pop_back(); | |
619 retstr[ret_num] = str; | |
620 stack.pop_back(); | |
621 } | |
622 if (stack.empty()) { | |
623 cmd.clear(); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
624 return; // スタックがおかしい:abort |
0 | 625 } |
626 StackItem s = stack.back(); | |
627 stack.pop_back(); | |
628 bool localvar_init = false; | |
629 while( (!stack.empty()) && stack.back().scn_number == SCN_INFO) { | |
630 int mode = stack.back().scn_pt; | |
631 stack.pop_back(); | |
632 if (mode == SCN_INFO_MENU) { | |
633 // fprintf(stderr,"\nInfo Menu;"); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
634 // menu モード終了 |
0 | 635 SetSkipMode(SkipMode(skip_mode & (~SKIP_IN_MENU) )); |
636 } else if (mode >= SCN_INFO_LOCALS && mode <= SCN_INFO_LOCALS+50) { | |
637 // fprintf(stderr,"\nInfo Local;"); | |
638 int i; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
639 // ローカル変数を元に戻す |
0 | 640 VarInfo var; |
641 var.type = 11; | |
642 var.number = 0; | |
643 for (i=0; i<40; i++) { | |
644 var.number = i; | |
645 flag.Set(var, 0); | |
646 } | |
647 var.type = TYPE_VARLOCSTR; | |
648 for (i=0; i<3; i++) { | |
649 var.number = i; | |
650 flag.SetStr(var, ""); | |
651 } | |
652 int args = mode - SCN_INFO_LOCALS; | |
653 // fprintf(stderr," args = %d; ",args); | |
654 for (i=0; i<args; i++) { | |
655 if (stack.empty() || stack.back().scn_number < SCN_INFO) { | |
656 fprintf(stderr,"Fatal : Invalid stack found in preserved local variables!\n"); | |
657 break; | |
658 } | |
659 var.number = stack.back().scn_number; | |
660 // fprintf(stderr,"%d:%d; ",stack.back().scn_number,stack.back().scn_pt); | |
661 if (var.number >= SCN_INFO_LOCALS && var.number < SCN_INFO_LOCALSTR) { | |
662 var.type = 11; | |
663 var.number -= SCN_INFO_LOCALS; | |
664 flag.Set(var, stack.back().scn_pt); | |
665 } else if (var.number >= SCN_INFO_LOCALSTR && var.number < SCN_INFO_RETSTR) { | |
666 var.type = TYPE_VARLOCSTR; | |
667 var.number -= SCN_INFO_LOCALSTR; | |
668 flag.SetStr(var, stack_strbuffer.back()); | |
669 stack_strbuffer.pop_back(); | |
670 } | |
671 stack.pop_back(); | |
672 } | |
673 } | |
674 // fprintf(stderr,"stack size %d string size %d\n",stack.size(),stack_strbuffer.size()); | |
675 } | |
676 if (cmd.cmd3 == 0x11 || cmd.cmd3 == 0x13) { | |
677 // fprintf(stderr,"\nSet RetLocal;"); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
678 // 返り値をセットする |
0 | 679 map<int,string>::iterator it; |
680 VarInfo var; | |
681 var.type = TYPE_VARLOCSTR; | |
682 for (it=retstr.begin(); it!=retstr.end(); it++) { | |
683 var.number = it->first; | |
684 flag.SetStr(var, it->second); | |
685 } | |
686 var.type = 11; | |
687 // fprintf(stderr,"return : cmd.cmd3 == 0x11; size %d\n",cmd.args.size()); | |
688 if (cmd.args.size() == 1) { | |
689 // fprintf(stderr,"return value %d\n",cmd.args[0].value); | |
690 flag.SetSys(cmd.args[0].value); | |
691 } else { | |
692 int i;for (i=0; i<cmd.args.size(); i++) { | |
693 var.number = i; | |
694 flag.Set(var, cmd.args[i].value); | |
695 } | |
696 } | |
697 } | |
698 // fprintf(stderr,"global return : return to %d:%d\n",s.scn_number,s.scn_pt); | |
699 // fprintf(stderr,"\nglobal return %d:%d from %d:%d\n",s.scn_number,s.scn_pt,scn_number, script - script_start); | |
700 if (s.scn_number != -1) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
701 if (! ChangeScript(s.scn_number, 0)) return; // 読み込めない; abort. |
0 | 702 } |
703 script = script_start + s.scn_pt; | |
704 cmd.clear(); | |
705 } | |
706 } else if (cmd.cmd1 == 2 && cmd.cmd2 == 1 && cmd.cmd3 == 12) { // DLL Call | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
707 const char* regname = config->GetParaStr("#REGNAME"); |
52 | 708 const char key_lb[] = "KEY\\LittleBusters";//FIXME: too specific to be here? |
0 | 709 if (strcmp(regname, key_lb) == 0) { |
710 DllCall_LB(cmd, flag); | |
711 cmd.clear(); | |
712 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
713 } else if (cmd.cmd1 == 0 && cmd.cmd2 == 0x04) { // メニューモード |
0 | 714 if (cmd.cmd3 == 300 || cmd.cmd3 == 301 || cmd.cmd3 == 302) { |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
715 // メニューからのreturn |
0 | 716 cmd.cmd2 = 1; |
717 cmd.cmd3 = 0x0d; | |
718 SysExec(cmd); | |
719 } | |
720 } else if (cmd.cmd1 == 1 && cmd.cmd2 == 0x04) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
721 if (cmd.cmd3 == 0 && cmd.cmd4 == 0) { // タイトル名設定 |
0 | 722 const char* name = cmd.Str(cmd.args[0]); |
52 | 723 if (name == NULL) name = ""; |
0 | 724 window_title = name; |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
725 const char* config_name = config->GetParaStr("#CAPTION"); |
52 | 726 if (config_name == NULL) config_name = ""; |
0 | 727 string setname = kconv(string(config_name) + " " + window_title); |
728 parent.Root().SetWindowCaption(setname.c_str()); | |
729 cmd.clear(); | |
730 } else if (cmd.cmd3 == 0x82 && cmd.cmd4 == 0) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
731 /* cmd.cmd3 == 0x82 : マウスの press 状態クリアかも */ |
0 | 732 event.presscount(MOUSE_LEFT); |
733 event.presscount(MOUSE_RIGHT); | |
734 cmd.clear(); | |
735 } else if (cmd.cmd3 == 0x85 && cmd.cmd4 == 0) { | |
736 int x,y,left,right; | |
737 event.MousePos(x,y); | |
738 if (event.presscount(MOUSE_LEFT)) left = 2; | |
739 else if (event.pressed(MOUSE_LEFT)) left = 1; | |
740 else left = 0; | |
741 | |
742 if (event.presscount(MOUSE_RIGHT)) right = 2; | |
743 else if (event.pressed(MOUSE_RIGHT)) right = 1; | |
744 else right = 0; | |
745 | |
746 // eprintf("mouse pos\n"); | |
747 flag.Set(cmd.args[0], x); | |
748 flag.Set(cmd.args[1], y); | |
749 flag.Set(cmd.args[2], left); | |
750 flag.Set(cmd.args[3], right); | |
751 cmd.clear(); | |
752 } else if (cmd.cmd3 == 0x15e || cmd.cmd3 == 0x161 || cmd.cmd3 == 0x162 || cmd.cmd3 == 0x14c || cmd.cmd3 == 0x7d1) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
753 /* 15e, 161, 162, 14c, 7d1 : なんらかのシステム情報を返す(skip modeなど?) */ |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
754 /* 7d1: == 1 || 14c: == 1 || (15e==1&&161==1&&162==0) || (press_val == 2) : スキップ中? タイトル画面のアニメーション終了 */ |
0 | 755 flag.SetSys(0); |
756 cmd.clear(); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
757 } else if (cmd.cmd3 == 0x4b0) { // 終了 |
0 | 758 System::Main::Quit(); |
52 | 759 //script = NULL; script_start = NULL; script_end = NULL; |
0 | 760 cmd.clear(); |
761 cmd.cmd_type = CMD_WAITFRAMEUPDATE; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
762 } else if (cmd.cmd3 == 0x4b4 || cmd.cmd3 == 0x4b5) { // 選択肢巻き戻し |
0 | 763 LoadRollback(cmd); |
764 } else if (cmd.cmd3 == 0x58d) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
765 // 前にロード|セーブされた番号を返す。 |
16
92765a5661f7
added "new" label on last savegame and corrected StatSaveFile
thib
parents:
15
diff
changeset
|
766 int lastsave; |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
767 config->GetParam("#LASTSAVE", 1, &lastsave); |
16
92765a5661f7
added "new" label on last savegame and corrected StatSaveFile
thib
parents:
15
diff
changeset
|
768 flag.SetSys(lastsave-1); |
0 | 769 } else if (cmd.cmd3 == 0x585) { |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
770 // 第一引数の記録された日付、タイトルなどが返される |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
771 // データがないなら sys に 0が、あるなら 1 が返る |
0 | 772 int y,m,d,wd,h,min,s,ms; |
773 string title; | |
774 fprintf(stderr,"StatSave %d:",cmd.args[0].value+1); | |
775 if (StatSaveFile(cmd.args[0].value+1,y,m,d,wd,h,min,s,ms,title) == true) { | |
776 flag.Set(cmd.args[1], y); | |
777 flag.Set(cmd.args[2], m); | |
778 flag.Set(cmd.args[3], d); | |
779 flag.Set(cmd.args[4], wd); | |
780 flag.Set(cmd.args[5], h); | |
781 flag.Set(cmd.args[6], min); | |
782 flag.Set(cmd.args[7], s); | |
783 flag.Set(cmd.args[8], ms); | |
784 if (cmd.args[9].type == TYPE_VARSTR) { | |
12 | 785 flag.SetStr(cmd.args[9], kconv_rev(title)); |
0 | 786 } |
787 flag.SetSys(1); | |
788 } else { | |
789 flag.SetSys(0); | |
790 } | |
791 cmd.clear(); | |
792 } else if (cmd.cmd3 == 0xc23) { // save | |
793 Save(cmd); | |
794 } else if (cmd.cmd3 == 0xc25) { // load | |
795 Load(cmd); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
796 } else if (cmd.cmd3 == 0x4b1 || cmd.cmd3 == 0x4b3) { // menu へ戻る (4b3: バッドエンド) |
0 | 797 int scn_start; |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
798 if (config->GetParam("#SEEN_MENU", 1, &scn_start) == 0) { |
0 | 799 ChangeScript(scn_start, 0); |
800 save_scn = 0; | |
801 save_point = 0; | |
802 window_title = ""; | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
803 const char* window_title_config = config->GetParaStr("#CAPTION"); |
0 | 804 if (window_title_config) window_title = window_title_config; |
805 parent.Root().SetWindowCaption(kconv(window_title).c_str()); | |
806 stack.clear(); | |
807 cmd_stack.clear(); | |
808 cmd_stack_str = cmd_stack_str_orig; | |
809 flag.Load(""); | |
810 text_exec.Load(""); | |
811 grp_exec.Load(""); | |
812 SetSkipMode(SKIP_NO); | |
813 } | |
814 } else if (cmd.cmd3 == 0xcc) { | |
815 eprintf("show mouse cursor\n"); | |
816 ShowCursor(); | |
817 cmd.clear(); | |
818 } else if (cmd.cmd3 == 0xcd) { | |
819 eprintf("hide mouse cursor\n"); | |
820 HideCursor(); | |
821 cmd.clear(); | |
822 } else if (cmd.cmd3 == 0xcf) { | |
823 mouse_type = cmd.args[0].value; | |
824 eprintf("change mouse cursor : %d\n", mouse_type); | |
825 if (mouse_surface) ShowCursor(); | |
826 cmd.clear(); | |
827 } | |
828 } | |
829 | |
830 } | |
831 | |
52 | 832 #include <sys/types.h> |
833 #include <sys/stat.h> | |
834 #include <errno.h> | |
835 #include <unistd.h> | |
0 | 836 |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
837 // セーブファイルの名前をつくる |
0 | 838 string Scn2k::MakeSaveFile(void) const { |
839 struct stat sstatus; | |
840 string dir = "~/.xkanon"; | |
841 | |
842 if (dir.c_str()[0] == '~' && dir.c_str()[1] == '/') { | |
843 char* home = getenv("HOME"); | |
52 | 844 if (home != NULL) { |
0 | 845 string new_dir = string(home) + (dir.c_str()+1); |
846 dir = new_dir; | |
847 } | |
848 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
849 // savepathにファイル名が入っていれば、それをセーブファイルとして使う |
0 | 850 if (stat(dir.c_str(), &sstatus) == -1) { |
851 if (errno != ENOENT) { | |
852 fprintf(stderr,"Cannot open save file; dir %s is not directory\n",dir.c_str()); | |
853 return ""; | |
854 } | |
855 if (mkdir(dir.c_str(), S_IRWXU) != 0 && errno != EEXIST) { | |
856 fprintf(stderr, "Cannot create directory %s ; Please create manually!!\n",dir.c_str()); | |
857 } | |
858 } else { | |
859 if ( (sstatus.st_mode & S_IFMT) == S_IFREG) { | |
860 return dir; | |
861 } | |
862 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
863 // ファイル名を作る |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
864 const char* regname = config->GetParaStr("#REGNAME"); |
0 | 865 |
866 char* fname = new char[strlen(regname)+1]; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
867 /* レジストリ名をファイル名として有効なものにする */ |
0 | 868 int i; for (i=0; regname[i]!=0; i++) { |
869 char c = regname[i]; | |
870 if (c == '\\' || c == '/' || c == ':' || c <= 0x20) c = '_'; | |
871 fname[i] = tolower(c); | |
872 } | |
873 fname[i] = 0; | |
874 dir += "/save."; | |
875 dir += fname; | |
8 | 876 delete[] fname; |
0 | 877 return dir; |
878 } | |
52 | 879 |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
880 // セーブファイルの名前をつくる |
0 | 881 string Scn2kSaveTitle::operator() (int number) const { |
882 int y,m,d,wd,h,min,sec,msec; | |
883 string title; | |
884 if (! impl.StatSaveFile(number, y,m,d,wd,h,min,sec,msec,title)) { | |
885 return ""; | |
886 } else { | |
887 char buf[1024]; | |
888 sprintf(buf, "%2d/%2d %2d:%2d ",m,d,h,min); | |
889 return string(buf) + title; | |
890 } | |
52 | 891 } |
0 | 892 |
893 void Scn2k::SaveSys(void) { | |
894 char buf[1024]; | |
895 string save; | |
896 string path = MakeSaveFile(); | |
897 | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
898 sprintf(buf, "KEY=%s\n", config->GetParaStr("#REGNAME")); |
52 | 899 save += buf; |
0 | 900 string save_config; |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
901 config->DiffOriginal(save_config); |
0 | 902 save += "CONFIG="; |
903 save += save_config; | |
904 save += "\n"; | |
905 string save_flag; flag.SaveSys(save_flag); | |
906 save += save_flag; | |
907 string save_grp; grp_exec.SaveSys(save_grp); | |
908 save += save_grp; | |
909 map<int,set<int> >::iterator it; | |
910 save += "[TextRead]\n"; | |
911 for (it=text_readflag.begin(); it != text_readflag.end(); it++) { | |
912 set<int>& read_flag = it->second; | |
913 set<int>::iterator jt; | |
914 char buf[1024]; | |
915 sprintf(buf,"T<%05d>=",it->first); | |
916 string save_readflag = buf; | |
917 for (jt=read_flag.begin(); jt != read_flag.end(); jt++) { | |
918 sprintf(buf, "%d,", *jt); | |
919 save_readflag += buf; | |
920 } | |
921 save_readflag += "\n"; | |
922 save += save_readflag; | |
923 } | |
924 | |
925 path += ".0"; | |
926 FILE* f = fopen(path.c_str(), "w"); | |
52 | 927 if (f == NULL) { |
0 | 928 fprintf(stderr,"Cannot open save file %s\n",path.c_str()); |
929 return; | |
930 } | |
931 fwrite(save.c_str(), save.length(), 1, f); | |
932 fclose(f); | |
933 return; | |
934 } | |
935 | |
936 void Scn2k::LoadSys(void) { | |
937 char buf[1024]; | |
938 string path = MakeSaveFile(); | |
939 path += ".0"; | |
940 FILE* f = fopen(path.c_str(), "r"); | |
52 | 941 if (f == NULL) { |
0 | 942 fprintf(stderr, "Cannot open save file %s\n",path.c_str()); |
943 } else { | |
52 | 944 fseek(f, 0, SEEK_END); |
0 | 945 int sz = ftell(f); |
52 | 946 fseek(f, 0, SEEK_SET); |
0 | 947 char* savedata = new char[sz+1]; |
948 fread(savedata, sz, 1, f); | |
949 savedata[sz] = 0; | |
950 fclose(f); | |
951 | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
952 sprintf(buf, "KEY=%s\n", config->GetParaStr("#REGNAME")); |
0 | 953 if (strncmp(savedata, buf, strlen(buf)) != 0) { |
43
01aa5ddf7dc8
A lot of very minor improvements (deleted some unused variables, and other things like that...)
thib
parents:
19
diff
changeset
|
954 fprintf(stderr,"Invalid header in save file %s: it must be started with \"%s\"\n", path.c_str(), buf); |
0 | 955 } else { |
956 char* config_str = strstr(savedata, "\nCONFIG="); | |
957 if (config_str) { | |
958 config_str += strlen("\nCONFIG="); | |
959 char* strend = strchr(config_str, '\n'); | |
960 if (strend) { | |
961 int l = strend - config_str; | |
962 char* config_copy = new char[l+1]; | |
963 strncpy(config_copy, config_str, l); | |
964 config_copy[l] = 0; | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
965 config->PatchOriginal(config_copy); |
0 | 966 delete[] config_copy; |
967 } | |
968 } | |
969 flag.LoadSys(savedata); | |
970 grp_exec.LoadSys(savedata); | |
971 char* save = strstr(savedata, "\n[TextRead]\n"); | |
972 if (save) { | |
973 save += strlen("\n[TextRead]\n"); | |
974 do { | |
975 if (save[0] == '[') break; // next section | |
976 char* next_save = strchr(save, '\n'); | |
977 if (next_save) { | |
978 *next_save++ = 0; | |
979 } | |
980 // T<XXXXX>=YYY,YYY,YYY,... | |
981 if (strncmp(save,"T<",2) == 0) { | |
982 int scn_num = atoi(save+2); | |
983 set<int>& read_flag = text_readflag[scn_num]; | |
984 save += strlen("T<XXXXX>="); | |
985 while(save && *save) { | |
986 if (save[0] >= '0' && save[0] <= '9') { | |
987 int num = atoi(save); | |
988 read_flag.insert(num); | |
989 } | |
990 save = strchr(save, ','); | |
991 if (save) save++; | |
992 } | |
993 } | |
994 save = next_save; | |
995 } while(save); | |
996 } | |
997 | |
998 } | |
999 delete[] savedata; | |
1000 } | |
1001 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1002 /* 初期化 */ |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
1003 int scn_start; config->GetParam("#SEEN_START", 1, &scn_start); |
0 | 1004 ChangeScript(scn_start, 0); |
1005 save_scn = 0; | |
1006 save_point = 0; | |
1007 window_title = ""; | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
1008 const char* window_title_config = config->GetParaStr("#CAPTION"); |
0 | 1009 if (window_title_config) window_title = window_title_config; |
1010 parent.Root().SetWindowCaption(kconv(window_title).c_str()); | |
1011 stack.clear(); | |
1012 cmd_stack.clear(); | |
1013 cmd_stack_str = cmd_stack_str_orig; | |
1014 | |
1015 return; | |
1016 } | |
1017 | |
1018 bool Scn2k::StatSaveFile(int num, int& year, int& month, int& day, int& wday, int& hour,int& min, int& sec, int& msec, string& title) const { | |
1019 char buf[1024]; | |
1020 string path = MakeSaveFile(); | |
19 | 1021 if (num <= 0 || num > 100) return false; |
0 | 1022 sprintf(buf,".%d",num); |
1023 path += buf; | |
1024 | |
1025 struct stat sb; | |
1026 if (stat(path.c_str(), &sb) == -1) return false; | |
1027 struct tm* t = localtime(&sb.st_mtime); | |
16
92765a5661f7
added "new" label on last savegame and corrected StatSaveFile
thib
parents:
15
diff
changeset
|
1028 year = t->tm_year; |
0 | 1029 month = t->tm_mon + 1; |
1030 day = t->tm_mday; | |
1031 hour = t->tm_hour; | |
1032 min = t->tm_min; | |
16
92765a5661f7
added "new" label on last savegame and corrected StatSaveFile
thib
parents:
15
diff
changeset
|
1033 sec = t->tm_sec; |
92765a5661f7
added "new" label on last savegame and corrected StatSaveFile
thib
parents:
15
diff
changeset
|
1034 msec = 0; |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1035 /* タイトルの取得 */ |
0 | 1036 FILE* savefile = fopen(path.c_str(), "rb"); |
52 | 1037 if (savefile == NULL) return false; |
0 | 1038 char regname[1024]; |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
1039 sprintf(regname, "KEY=%s\n", config->GetParaStr("#REGNAME")); |
0 | 1040 fgets(buf,1000,savefile); |
1041 if (strncmp(regname, buf, strlen(regname)) != 0) { | |
1042 fprintf(stderr,"invalid save file %s (registory name is not %s)\n",path.c_str(),regname); | |
1043 fclose(savefile); | |
1044 return false; | |
1045 } | |
1046 title="none"; | |
1047 while(!feof(savefile)) { | |
1048 fgets(buf,1000,savefile); | |
1049 if (strncmp(buf,"Title=",6) == 0) { | |
1050 if (buf[strlen(buf)-2] == 0x0a) buf[strlen(buf)-2] = 0; | |
1051 if (strlen(buf) > 20) buf[20] = 0, buf[21] = 0; | |
1052 title = kconv(buf+6); | |
1053 break; | |
1054 } | |
1055 } | |
1056 fclose(savefile); | |
1057 return true; | |
1058 } | |
1059 | |
1060 void Scn2k::SaveRollback(void) { | |
1061 fprintf(stderr,"Save rollback\n"); | |
1062 new_rollback_save = ""; | |
1063 string save_sys; SaveImpl(save_sys); | |
1064 string save_flag; flag.Save(save_flag); | |
1065 string save_text; text_exec.Save(save_text, true); | |
1066 string save_grp; grp_exec.Save(save_grp); | |
1067 new_rollback_save += save_sys; | |
1068 new_rollback_save += save_flag; | |
1069 new_rollback_save += save_text; | |
1070 new_rollback_save += save_grp; | |
1071 } | |
1072 | |
1073 void Scn2k::LoadRollback(Cmd& cmd) { | |
1074 if (rollback_save.empty()) return; | |
1075 new_rollback_save = ""; | |
1076 string savedata = rollback_save.back(); | |
1077 rollback_save.pop_back(); | |
1078 LoadImpl(savedata.c_str()); | |
1079 flag.Load(savedata.c_str()); | |
1080 text_exec.Load(savedata.c_str()); | |
1081 grp_exec.Load(savedata.c_str()); | |
1082 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1083 /* 画面の回復など */ |
0 | 1084 SetSkipMode(SKIP_NO); |
1085 vector<CmdSimplified>::iterator it; | |
1086 cmd.clear(); | |
1087 for (it = cmd_stack.begin(); it != cmd_stack.end(); it++) { | |
1088 cmd.read(*it); | |
1089 cmd.cmd_type = CMD_OTHER; | |
1090 flag.Exec(cmd); | |
1091 text_exec.Exec(cmd); | |
1092 grp_exec.Exec(cmd); | |
1093 } | |
1094 cmd.clear(); | |
1095 return; | |
1096 } | |
1097 | |
1098 void Scn2k::Save(Cmd& cmd) { | |
1099 if (cmd.cmd_type == CMD_SAVEREQ) { | |
52 | 1100 if (menu == NULL) { |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1101 SetSkipMode(SKIP_IN_MENU); // テキストスキップ等はここで中断 |
0 | 1102 menu = new Scn2kMenu(Scn2kMenu::MENU_SAVE, *this, flag, text_exec, system_version); |
1103 menu->InitPanel(event, parent); | |
1104 menu->InitTitle(Scn2kSaveTitle(*this)); | |
1105 if (mouse_surface) menu_mouseshown = true; | |
1106 else menu_mouseshown = false; | |
1107 ShowCursor(); | |
1108 return; | |
1109 } | |
1110 } | |
1111 char buf[1024]; | |
1112 string save; | |
52 | 1113 FILE* f = NULL; |
0 | 1114 if (save_scn == 0) { |
1115 fprintf(stderr,"Cannot decide save point\n"); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1116 return; // セーブ位置が保存されてない |
0 | 1117 } |
1118 string path = MakeSaveFile(); | |
1119 int file_number = 1; | |
1120 if (cmd.args.size() == 1) | |
1121 file_number = cmd.args[0].value + 1; | |
1122 if (file_number <= 0) { | |
1123 fprintf(stderr, "Cannot open save file %s\n",path.c_str()); | |
1124 return; | |
1125 } | |
1126 sprintf(buf, ".%d",file_number); | |
1127 path += buf; | |
1128 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1129 /* セーブファイル確認 */ |
0 | 1130 |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
1131 sprintf(buf, "KEY=%s\n", config->GetParaStr("#REGNAME")); save += buf; |
0 | 1132 string save_sys; SaveImpl(save_sys); |
1133 string save_flag; flag.Save(save_flag); | |
1134 string save_text; text_exec.Save(save_text, false); | |
1135 string save_grp; grp_exec.Save(save_grp); | |
1136 save += save_sys; | |
1137 save += save_flag; | |
1138 save += save_text; | |
1139 save += save_grp; | |
1140 vector<string>::iterator it; | |
1141 for (it=rollback_save.begin(); it != rollback_save.end(); it++) { | |
1142 save += "[Rollback Data]\n"; | |
1143 save += *it; | |
1144 save += "[Rollback End]\n"; | |
1145 } | |
1146 | |
1147 f = fopen(path.c_str(), "w"); | |
52 | 1148 if (f == NULL) { |
0 | 1149 fprintf(stderr,"Cannot open save file %s\n",path.c_str()); |
1150 return; | |
1151 } | |
1152 fwrite(save.c_str(), save.length(), 1, f); | |
1153 fclose(f); | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
1154 config->SetParam("#LASTSAVE", 1, file_number); |
0 | 1155 cmd.clear(); |
1156 } | |
1157 | |
1158 void Scn2k::Load(Cmd& cmd) { | |
1159 if (cmd.cmd_type == CMD_LOADREQ) { | |
52 | 1160 if (menu == NULL) { |
0 | 1161 menu = new Scn2kMenu(Scn2kMenu::MENU_LOAD, *this, flag, text_exec, system_version); |
1162 menu->InitPanel(event, parent); | |
1163 menu->InitTitle(Scn2kSaveTitle(*this)); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1164 SetSkipMode(SKIP_IN_MENU); // テキストスキップ等はここで中断 |
0 | 1165 if (mouse_surface) menu_mouseshown = true; |
1166 else menu_mouseshown = false; | |
1167 ShowCursor(); | |
1168 return; | |
1169 } | |
1170 } | |
1171 char buf[1024]; | |
1172 string path = MakeSaveFile(); | |
1173 int file_number = 1; | |
1174 if (cmd.args.size() == 1) | |
1175 file_number = cmd.args[0].value + 1; | |
1176 sprintf(buf, ".%d",file_number); | |
1177 path += buf; | |
52 | 1178 FILE* f = NULL; |
0 | 1179 if (file_number > 0) f = fopen(path.c_str(), "r"); |
52 | 1180 if (f == NULL) { |
0 | 1181 fprintf(stderr, "Cannot open save file %s\n",path.c_str()); |
1182 return; | |
1183 } | |
1184 | |
52 | 1185 fseek(f, 0, SEEK_END); |
0 | 1186 int sz = ftell(f); |
52 | 1187 fseek(f, 0, SEEK_SET); |
0 | 1188 char* savedata = new char[sz+1]; |
1189 fread(savedata, sz, 1, f); | |
1190 savedata[sz] = 0; | |
1191 fclose(f); | |
1192 | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
1193 sprintf(buf, "KEY=%s\n", config->GetParaStr("#REGNAME")); |
0 | 1194 if (strncmp(savedata, buf, strlen(buf)) != 0) { |
43
01aa5ddf7dc8
A lot of very minor improvements (deleted some unused variables, and other things like that...)
thib
parents:
19
diff
changeset
|
1195 fprintf(stderr,"Invalid header in save file %s: it must be started with \"%s\"\n", path.c_str(), buf); |
0 | 1196 delete[] savedata; |
1197 return; | |
1198 } | |
1199 LoadImpl(savedata); | |
1200 flag.Load(savedata); | |
1201 text_exec.Load(savedata); | |
1202 grp_exec.Load(savedata); | |
1203 rollback_save.clear(); | |
1204 new_rollback_save = ""; | |
1205 char* rollback_data = savedata; | |
52 | 1206 while( (rollback_data = strstr(rollback_data,"[Rollback Data]\n")) != NULL) { |
0 | 1207 rollback_data += strlen("[Rollback Data]\n"); |
1208 char* rollback_end = strstr(rollback_data, "[Rollback End]\n"); | |
52 | 1209 if (rollback_end == NULL) rollback_end = rollback_data + strlen(rollback_data); |
0 | 1210 string s(rollback_data, rollback_end); |
1211 rollback_save.push_back(s); | |
1212 rollback_data = rollback_end; | |
1213 } | |
1214 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1215 /* 画面の回復など */ |
0 | 1216 SetSkipMode(SKIP_NO); |
1217 vector<CmdSimplified>::iterator it; | |
1218 for (it = cmd_stack.begin(); it != cmd_stack.end(); it++) { | |
1219 cmd.read(*it); | |
1220 cmd.cmd_type = CMD_OTHER; | |
1221 flag.Exec(cmd); | |
1222 text_exec.Exec(cmd); | |
1223 grp_exec.Exec(cmd); | |
1224 } | |
1225 cmd.clear(); | |
50 | 1226 |
1227 delete[] savedata; | |
0 | 1228 } |
1229 | |
1230 void Scn2k::SaveImpl(string& save) { | |
1231 char buf[1024]; | |
1232 | |
1233 /* save point */ | |
1234 sprintf(buf, "\n[SCENARIO]\nScn=%d\nPoint=%d\n",save_scn, save_point); save += buf; | |
1235 sprintf(buf, "Title=%s\nMouseType=%d\nMouseShown=1\n",window_title.c_str(), mouse_type); save += buf; | |
1236 vector<StackItem>::iterator sit; | |
1237 for (sit=stack.begin(); sit!=stack.end(); sit++) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1238 if (sit->scn_number == SCN_INFO && sit->scn_pt == SCN_INFO_MENU) break; // メニューに入る直前までのスタックを保存 |
0 | 1239 sprintf(buf, "Stack=%d,%d\n",sit->scn_number,sit->scn_pt); |
1240 save += buf; | |
1241 } | |
1242 vector<string>::reverse_iterator ssit; | |
1243 for (ssit=stack_strbuffer.rbegin(); ssit != stack_strbuffer.rend(); ssit++) { | |
1244 sprintf(buf, "StackStr=%s\n",ssit->c_str()); | |
1245 save += buf; | |
1246 } | |
1247 vector<CmdSimplified>::iterator cit; | |
1248 for (cit=cmd_stack.begin(); cit != cmd_stack.end(); cit++) { | |
1249 if (cit->type == CMD_SAVECMDGRP || cit->type == CMD_SAVECMDGRP_ONCE || cit->type == CMD_SAVECMDGRP_START) { | |
1250 save += "CmdG="; | |
1251 } else { | |
1252 save += "Cmd="; | |
1253 } | |
1254 string s; cit->Save(s); | |
1255 save += s; | |
1256 save += "\n"; | |
1257 } | |
1258 } | |
1259 | |
1260 void Scn2k::LoadImpl(const char* save) { | |
1261 save_scn = 0; | |
1262 save_point = 0; | |
1263 window_title = ""; | |
1264 stack.clear(); | |
1265 cmd_stack.clear(); | |
1266 cmd_stack_str = cmd_stack_str_orig; | |
1267 | |
1268 save = strstr(save, "\n[SCENARIO]\n"); | |
52 | 1269 if (save == NULL) return; |
0 | 1270 save += strlen("\n[SCENARIO]\n"); |
1271 while(save[0] != 0 && save[0] != '[') { // while next section start | |
1272 if (strncmp(save, "Scn=", 4) == 0) { | |
1273 sscanf(save, "Scn=%d", &save_scn); | |
1274 } else if (strncmp(save, "Point=", 6) == 0) { | |
1275 sscanf(save, "Point=%d", &save_point); | |
1276 } else if (strncmp(save, "Title=", 6) == 0) { | |
1277 save += 6; | |
62
3b1593186f12
fix pointers used to get strchr result
Thibaut GIRKA <thib@sitedethib.com>
parents:
61
diff
changeset
|
1278 const char* s = strchr(save, '\n'); |
52 | 1279 if (s == NULL) window_title = save; |
0 | 1280 else window_title.assign(save, s-save); |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
1281 const char* config_name = config->GetParaStr("#CAPTION"); |
52 | 1282 if (config_name == NULL) config_name = ""; |
0 | 1283 string setname = kconv(string(config_name)+" "+window_title); |
1284 parent.Root().SetWindowCaption(setname.c_str()); | |
1285 } else if (strncmp(save, "MouseType=", 10) == 0) { | |
1286 sscanf(save, "MouseType=%d", &mouse_type); | |
1287 } else if (strncmp(save, "MouseShown=", 11) == 0) { | |
1288 int v; | |
1289 sscanf(save, "MouseShown=%d", &v); | |
1290 if (v) ShowCursor(); | |
1291 else HideCursor(); | |
1292 } else if (strncmp(save, "Stack=", 6) == 0) { | |
1293 int scn, pt; | |
1294 sscanf(save, "Stack=%d,%d", &scn, &pt); | |
1295 stack.push_back( StackItem(scn, pt)); | |
1296 } else if (strncmp(save, "StackStr=", 9) == 0) { | |
1297 save += 9; | |
62
3b1593186f12
fix pointers used to get strchr result
Thibaut GIRKA <thib@sitedethib.com>
parents:
61
diff
changeset
|
1298 const char* s = strchr(save, '\n'); |
52 | 1299 if (s == NULL) stack_strbuffer.push_back(""); |
0 | 1300 else stack_strbuffer.push_back(string(save, s-save)); |
1301 } else if (strncmp(save, "Cmd=", 4) == 0) { | |
1302 CmdSimplified cmd; | |
1303 cmd.Load(save+4, cmd_stack_str); | |
1304 cmd_stack.push_back(cmd); | |
1305 } else if (strncmp(save, "CmdG=", 5) == 0) { | |
1306 CmdSimplified cmd; | |
1307 cmd.Load(save+5, cmd_stack_str); | |
1308 cmd.type = CMD_SAVECMDGRP; | |
1309 cmd_stack.push_back(cmd); | |
1310 } | |
1311 save = strchr(save, '\n'); | |
52 | 1312 if (save != NULL) save++; |
0 | 1313 } |
1314 ChangeScript(save_scn, 0); | |
1315 script = script_start + save_point; | |
1316 } | |
52 | 1317 |
0 | 1318 void Scn2k::SetSkipMode(SkipMode mode) { |
1319 if (skip_mode != mode) { | |
1320 skip_mode = mode; | |
1321 text_exec.SetSkipMode(mode); | |
1322 grp_exec.SetSkipMode(mode); | |
1323 } | |
1324 } | |
1325 | |
1326 /*********************************************************** | |
1327 ** | |
1328 ** DLL Call Implementation | |
1329 ** | |
1330 **/ | |
1331 static double* lb_ef_param = 0; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1332 void DLLCall_LB_EF00_0(Cmd& cmd, Flags& flags) { // エフェクトの設定 |
0 | 1333 if (lb_ef_param == 0) { |
1334 lb_ef_param = new double[sizeof(double) * 0x60 * 8]; | |
1335 } | |
1336 int i,j; | |
1337 int param_top, param_size; | |
1338 if (cmd.args[2].value == 1) { | |
1339 param_top = 0; | |
1340 param_size = 0x20; | |
1341 } else { | |
1342 param_top = cmd.args[3].value; | |
1343 param_size = cmd.args[4].value; | |
1344 if (param_top < 0) param_top = 0; | |
1345 if (param_top > 0x20) param_top = 0x20; | |
1346 if (param_size+param_top > 0x20) param_size = 0x20 - param_top; | |
1347 } | |
1348 for (i=0; i<8; i++) { | |
1349 double* param = lb_ef_param + i*0x60 + param_top*3; | |
1350 for (j=0; j<param_size; j++) { | |
1351 *param++ = random() % 800 - 400; | |
1352 *param++ = random() % 600 - 300; | |
1353 *param++ = random() % 700 - 350; | |
1354 } | |
1355 } | |
1356 if (cmd.args[5].value != 1) return; | |
52 | 1357 |
1358 static int random_dirtable[] = { | |
0 | 1359 0, 2, 1, 3, 0, 2, 1, 3, |
1360 1, 3, 2, 0, 1, 3, 2, 0, | |
1361 0, 0, 0, 0, 3, 1, 2, 0, | |
1362 3, 1, 3, 1, 0, 2, 3, 1 | |
1363 }; | |
52 | 1364 |
0 | 1365 int* dir = &random_dirtable[(random()&3) * 8]; |
1366 for (i=0; i<8; i++) { | |
1367 double* param = lb_ef_param + i*0x60; | |
1368 double x = random()%600 - 300; | |
1369 double y = random()%480-240; | |
1370 if (x < 0) x -= 80; | |
1371 else x += 80; | |
1372 if (y < 0) y -= 80; | |
1373 else y += 80; | |
1374 switch(*dir++) { | |
1375 case 0: | |
1376 if (x < 0) x = -x; | |
1377 if (y < 0) y = -y; | |
1378 break; | |
1379 case 1: | |
1380 if (x > 0) x = -x; | |
1381 if (y < 0) y = -y; | |
1382 break; | |
1383 case 2: | |
1384 if (x < 0) x = -x; | |
1385 if (y > 0) y = -y; | |
1386 break; | |
1387 case 4: | |
1388 if (x > 0) x = -x; | |
1389 if (y > 0) y = -y; | |
1390 break; | |
1391 } | |
1392 param[9] = x*1.2; | |
1393 param[10] = y*1.2; | |
1394 param[11] *= 1.2; | |
1395 param[12] *= -0.08; | |
1396 param[13] *= -0.08; | |
1397 param[14] *= -0.08; | |
1398 param[15] = -param[9]; | |
1399 param[16] = -param[10]; | |
1400 param[17] = -param[11]; | |
1401 } | |
1402 return; | |
1403 } | |
52 | 1404 |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1405 void DLLCall_LB_EF00_1(Cmd& cmd, Flags& flags) { // 計算を行う |
0 | 1406 if (lb_ef_param == 0) { |
1407 fprintf(stderr,"Warning : DLLCall_LB_EF00_1 : Script error : effect calculation was called before setting\n"); | |
1408 return; | |
1409 } | |
1410 int index = cmd.args[2].value; | |
1411 int v5_1154 = flags.Get(5, 1154+index); | |
1412 int j = ((v5_1154) & 0x1f) + index * 0x20; | |
1413 int k = ((v5_1154+1) & 0x1f) + index * 0x20; | |
1414 int l = ((v5_1154+2) & 0x1f) + index * 0x20; | |
1415 int m = ((v5_1154+3) & 0x1f) + index * 0x20; | |
1416 j *= 3; | |
1417 k *= 3; | |
1418 l *= 3; | |
1419 m *= 3; | |
1420 | |
1421 // 0 < x < 1 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1422 // va - vd は 0-1 の範囲で対称性を持つ3次関数 |
0 | 1423 double x = double(flags.Get(5, 1162 + index)) * 0.001; |
1424 double va = (x * x * x)/6; | |
1425 double vb = (-x*x*x + 3*x*x - 3*x + 1) / 6; | |
1426 double vc = (3*x*x*x - 6*x*x + 4) / 6; | |
1427 double vd = (-3*x*x*x+3*x*x+3*x+1) / 6; | |
1428 | |
1429 double r1 = va * lb_ef_param[m+3] + vd * lb_ef_param[l+3] + vc * lb_ef_param[k+3] + vb * lb_ef_param[j+3]; | |
1430 double r2 = va * lb_ef_param[m+2] + vd * lb_ef_param[l+2] + vc * lb_ef_param[k+2] + vb * lb_ef_param[j+2]; | |
1431 double r3 = va * lb_ef_param[m+1] + vd * lb_ef_param[l+1] + vc * lb_ef_param[k+1] + vb * lb_ef_param[j+1]; | |
1432 if (r1 != 400) { | |
1433 r2 = r2 * 800 / (400-r1); | |
1434 r3 = r3 * 700 / (400-r1); | |
1435 } | |
1436 VarInfo var; | |
1437 var.type = 5; | |
1438 var.number = 1151; | |
1439 flags.Set(var, int(r2)); | |
1440 var.number = 1152; | |
1441 flags.Set(var, int(r3)); | |
1442 var.number = 1153; | |
1443 flags.Set(var, int(r1)); | |
1444 return; | |
1445 } | |
1446 | |
1447 | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1448 void DllCall_LB(Cmd& cmd, Flags& flags) { // リトルバスターズ!の EF00.dll をエミュレート |
0 | 1449 if (cmd.args[0].value == 1) { |
1450 // "EF00.dll" | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1451 if (cmd.args[1].value == 0) { // エフェクトの設定 |
0 | 1452 DLLCall_LB_EF00_0(cmd, flags); |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1453 } else if (cmd.args[1].value == 1) { // 計算を行う |
0 | 1454 DLLCall_LB_EF00_1(cmd, flags); |
1455 } | |
1456 } else { | |
1457 fprintf(stderr,"Unsupported DLL call for DLL<%d>\n",cmd.args[0].value); | |
1458 } | |
1459 return; | |
1460 } | |
1461 | |
1462 /********************************************************** | |
1463 ** | |
1464 ** MenuImpl | |
1465 ** | |
1466 */ | |
1467 | |
52 | 1468 #include "window/widget.h" |
1469 #include "window/menuitem.h" | |
0 | 1470 |
1471 void DSurfaceFill(Surface* src, const Rect& rect, int r, int g, int b, int a = 0xff); | |
1472 | |
1473 struct Scn2kMenuImpl { | |
1474 Scn2kMenu& interface; | |
1475 MenuItem* menu; | |
1476 Event::Container* pevent; | |
1477 PicContainer* pparent; | |
1478 | |
1479 virtual void InitPanel(Event::Container& event, PicContainer& parent) = 0; | |
1480 virtual void InitTitle(const SaveTitle&) = 0; | |
1481 virtual void Cancel(void) = 0; | |
1482 virtual void Exec(Cmd& cmd) = 0; | |
1483 Scn2kMenuImpl(Scn2kMenu& _interface) : interface(_interface) { | |
52 | 1484 menu = NULL; |
1485 pevent = NULL; | |
1486 pparent = NULL; | |
0 | 1487 } |
1488 virtual ~Scn2kMenuImpl() { | |
1489 if (menu) delete menu; | |
52 | 1490 menu = NULL; |
0 | 1491 } |
1492 }; | |
1493 | |
1494 struct LoadMenu : Scn2kMenuImpl { | |
1495 vector<string> title; | |
1496 vector<int> title_valid; | |
1497 RadioButton* btn_local; | |
1498 RadioButton* btn_page; | |
1499 RadioButton* btn_set; | |
1500 Scale* btn_scale; | |
1501 Dialog* awk_dialog; | |
1502 int btn_page_val, btn_set_val, btn_local_val, select_page, select_value; | |
1503 LoadMenu(Scn2kMenu& _interface); | |
1504 ~LoadMenu(); | |
1505 void InitPanel(Event::Container& event, PicContainer& parent); | |
1506 void InitTitle(const SaveTitle&); | |
1507 void Cancel(void); | |
1508 void Exec(Cmd& cmd); | |
1509 static void ChangeBtnPage(void* pointer, MenuItem* widget); | |
1510 static void ChangeBtnLocal(void* pointer, MenuItem* widget); | |
1511 static void ChangeBtnScale(void* pointer, Scale* widget); | |
1512 static void ChangeBtnSet(void* pointer, MenuItem* widget); | |
1513 static void ChangeDialog(void* pointer, Dialog* widget); | |
1514 bool in_setpage; | |
1515 void SetPage(int new_page); | |
1516 void SetValue(int new_value); | |
1517 void PressOk(void); | |
1518 }; | |
1519 LoadMenu::LoadMenu(Scn2kMenu& _interface) : Scn2kMenuImpl(_interface) { | |
52 | 1520 btn_local = NULL; |
1521 btn_scale = NULL; | |
1522 btn_set = NULL; | |
0 | 1523 btn_page_val = 0; |
1524 btn_set_val = -1; | |
1525 btn_local_val = -1; | |
52 | 1526 awk_dialog = NULL; |
0 | 1527 in_setpage = false; |
1528 select_page = 0; | |
1529 select_value = -1; | |
1530 } | |
1531 LoadMenu::~LoadMenu() { | |
1532 if (awk_dialog) delete awk_dialog; | |
1533 } | |
1534 void LoadMenu::InitPanel(Event::Container& event, PicContainer& parent) { | |
1535 pevent = &event; | |
1536 pparent = &parent; | |
1537 | |
1538 if (menu) delete menu; | |
52 | 1539 menu = NULL; |
0 | 1540 menu = new MenuItem(&parent, Rect(80,30,560, 450), 1, 3, 0); |
1541 Surface* surface = parent.Root().NewSurface(menu->Pic()->Width(), menu->Pic()->Height(), ALPHA_MASK); | |
1542 if (interface.type == Scn2kMenu::MENU_LOAD) { | |
1543 menu->SetLabelTop(new Label(menu->PicNode(), Rect(0,0), true, "Load", 26), Rect(0,0,10,0), Rect(0,0,0,20)); | |
1544 DSurfaceFill(surface, Rect(*surface), 0, 0, 0x80, 0x80); | |
1545 } else { | |
1546 menu->SetLabelTop(new Label(menu->PicNode(), Rect(0,0), true, "Save", 26), Rect(0,0,10,0), Rect(0,0,0,20)); | |
1547 DSurfaceFill(surface, Rect(*surface), 0, 0x80, 0, 0x80); | |
1548 } | |
1549 menu->Pic()->SetSurface(surface, 0, 0); | |
1550 menu->Pic()->SetSurfaceFreeFlag(); | |
1551 | |
1552 btn_page = new RadioButton(event, menu->PicNode(), Rect(0, 0, 480, 40), 10, 1, &btn_page_val, | |
1553 Rect(0,0,0,0), 18, Color(0,0,0),Color(0xff,0,0),Color(0xff,0x80,0)); | |
1554 btn_page->set_func = &ChangeBtnPage; | |
1555 btn_page->set_pointer = this; | |
1556 btn_page->SetLabelLeft(new Label(btn_page->PicNode(), Rect(0,0), true, "Page", 18), Rect(0, 0, 180, 0), Rect(0,0)); | |
1557 btn_page->Add(" 1 "); | |
1558 btn_page->Add(" 2 "); | |
1559 btn_page->Add(" 3 "); | |
1560 btn_page->Add(" 4 "); | |
1561 btn_page->Add(" 5 "); | |
1562 btn_page->Add(" 6 "); | |
1563 btn_page->Add(" 7 "); | |
1564 btn_page->Add(" 8 "); | |
1565 btn_page->Add(" 9 "); | |
1566 btn_page->Add(" 10 "); | |
1567 btn_page->pack(); | |
1568 /* | |
1569 surface = parent.Root().NewSurface(btn_page->Pic()->Width(), btn_page->Pic()->Height(), ALPHA_MASK); | |
1570 DSurfaceFill(surface, Rect(*surface), 0xff, 0, 0, 0x80); | |
1571 btn_page->Pic()->SetSurface(surface, 0, 0); | |
1572 btn_page->Pic()->SetSurfaceFreeFlag(); | |
1573 */ | |
1574 menu->item[0] = btn_page; | |
1575 btn_set = new RadioButton(event, menu->PicNode(), Rect(0, 0, 480, 40), 2, 1, &btn_set_val, | |
1576 Rect(0,0,0,0), 18, Color(0,0,0),Color(0xff,0,0),Color(0xff,0x80,0)); | |
1577 btn_set->set_func = &ChangeBtnSet; | |
1578 btn_set->set_pointer = this; | |
1579 btn_set->SetLabelLeft(new Label(btn_set->PicNode(), Rect(0,0)), Rect(0,0,200,0), Rect(0,0)); | |
1580 if (interface.type == Scn2kMenu::MENU_LOAD) { | |
1581 btn_set->Add(" Load "); | |
1582 } else { | |
1583 btn_set->Add(" Save "); | |
1584 } | |
1585 btn_set->Add(" Cancel "); | |
1586 btn_set->pack(); | |
1587 /* | |
1588 surface = parent.Root().NewSurface(btn_set->Pic()->Width(), btn_set->Pic()->Height(), ALPHA_MASK); | |
1589 DSurfaceFill(surface, Rect(*surface), 0, 0, 0xff, 0x80); | |
1590 btn_set->Pic()->SetSurface(surface, 0, 0); | |
1591 btn_set->Pic()->SetSurfaceFreeFlag(); | |
1592 */ | |
1593 menu->item[2] = btn_set; | |
1594 // void btn_set_press(void* pointer, MenuItem* widget); | |
1595 // btn_set->set_func = btn_set_press; | |
1596 // btn_set->set_pointer = this; | |
1597 btn_local = new RadioButton(*pevent, menu->PicNode(), Rect(0, 0, 480, 300), 1, 100, &btn_local_val, | |
1598 Rect(0,0,300,30), 18, Color(0,0,0),Color(0xff,0,0),Color(0xff,0x80,0)); | |
1599 btn_local->set_func = &ChangeBtnLocal; | |
1600 btn_local->set_pointer = this; | |
1601 /* | |
1602 surface = pparent->Root().NewSurface(btn_local->Pic()->Width(), btn_local->Pic()->Height(), ALPHA_MASK); | |
1603 DSurfaceFill(surface, Rect(*surface), 0, 0xff, 0, 0x80); | |
1604 btn_local->Pic()->SetSurface(surface, 0, 0); | |
1605 btn_local->Pic()->SetSurfaceFreeFlag(); | |
1606 */ | |
1607 menu->item[1] = btn_local; | |
1608 int i; | |
1609 for (i=0; i<12; i++) | |
1610 btn_local->Add("",false); | |
1611 btn_local->pack(); | |
1612 btn_local->show_all(); | |
1613 menu->pack(); | |
1614 | |
1615 PicBase* local_pic = btn_local->Pic(); | |
1616 int local_x2 = local_pic->PosX() + local_pic->Width(); | |
1617 int local_y2 = local_pic->PosY() + local_pic->Height(); | |
1618 btn_scale = new Scale(*pevent, menu->PicNode(), Rect(local_x2-16, local_pic->PosY(), local_x2, local_y2), Color(0xff, 0x80, 0), true); | |
1619 btn_scale->SetRange(0, 900); | |
1620 btn_scale->InitCursor(1024/10); | |
1621 btn_scale->SetValue(0); | |
1622 btn_scale->change_func = &ChangeBtnScale; | |
1623 btn_scale->change_pointer = this; | |
1624 | |
1625 menu->PicNode()->show_all(); | |
1626 } | |
1627 | |
1628 void LoadMenu::InitTitle(const SaveTitle& title_op) { | |
1629 title.clear(); | |
1630 int i; | |
1631 for (i=1; i<=100; i++) { | |
1632 char buf[100]; | |
1633 sprintf(buf,"%2d:",i); | |
1634 string t = title_op(i); | |
1635 string s = string(buf) + t; | |
1636 if (t.length() == 0) { | |
1637 string s = string(buf) + "--------"; | |
1638 title_valid.push_back(0); | |
1639 } else { | |
1640 title_valid.push_back(1); | |
1641 } | |
1642 title.push_back(s); | |
1643 } | |
1644 if (btn_local==0) return; | |
1645 for (i=0; i<10; i++) { | |
1646 TextButton* button = dynamic_cast<TextButton*>(btn_local->item[i]); | |
1647 if (button) button->SetText(title[i].c_str()); | |
1648 } | |
1649 } | |
1650 | |
1651 void LoadMenu::SetPage(int new_page) { | |
1652 if (new_page < 0) new_page = 0; | |
1653 if (new_page > 900) new_page = 900; | |
1654 if (select_page == new_page) return; | |
1655 if (in_setpage) return; | |
1656 in_setpage = true; | |
1657 | |
1658 int prev_page = select_page / 10; | |
1659 int cur_page = new_page / 10; | |
1660 int prev_point = select_page%10; | |
1661 int new_point = new_page%10; | |
1662 select_page = new_page; | |
1663 if (prev_page != cur_page) { | |
1664 int i; | |
1665 for (i=0; i<12; i++) { | |
1666 TextButton* button = dynamic_cast<TextButton*>(btn_local->item[i]); | |
1667 if (button) { | |
1668 if (cur_page+i < title.size()) button->SetText(title[cur_page+i].c_str()); | |
1669 else button->SetText("----"); | |
1670 } | |
1671 } | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1672 // ボタンの内容を変更する |
0 | 1673 if (select_value < cur_page || select_value > cur_page+12) |
1674 btn_local->SetValue(-1); | |
1675 else | |
1676 btn_local->SetValue(select_value - cur_page); | |
1677 } | |
1678 if (prev_point != new_point) { | |
1679 int i; | |
1680 for (i=0; i<12; i++) { | |
1681 int old_x = btn_local->item[i]->Pic()->PosX(); | |
1682 btn_local->item[i]->Pic()->Move(old_x, i*30-new_point*3); | |
1683 } | |
1684 } | |
52 | 1685 if (btn_page != NULL) { |
0 | 1686 if (select_page%100 == 0) btn_page->SetValue(select_page/100); |
1687 else btn_page->SetValue(-1); | |
1688 } | |
52 | 1689 if (btn_scale != NULL) { |
0 | 1690 btn_scale->SetValue(select_page); |
1691 } | |
1692 in_setpage = false; | |
1693 } | |
52 | 1694 |
0 | 1695 void LoadMenu::SetValue(int new_value) { |
1696 if (in_setpage) return; | |
1697 in_setpage = true; | |
1698 | |
1699 if (new_value < 0 || new_value > title.size() || | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1700 (interface.type == Scn2kMenu::MENU_LOAD && title_valid[new_value] == 0) ) { // 無効な選択肢 |
0 | 1701 if (select_value < select_page/10 || select_value > select_page/10+12) |
1702 btn_local->SetValue(-1); | |
1703 else | |
1704 btn_local->SetValue(select_value-select_page/10); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1705 } else { // 選択肢を変更する |
0 | 1706 if (select_value == new_value) { |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1707 PressOk(); // ダブルクリック |
0 | 1708 } else { |
1709 select_value = new_value; | |
1710 if (interface.type == Scn2kMenu::MENU_SAVE && title_valid[select_value] == 0) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1711 PressOk(); // 新しいセーブデータなら無条件に選択 |
0 | 1712 } |
1713 } | |
1714 } | |
1715 | |
1716 in_setpage = false; | |
1717 } | |
52 | 1718 |
0 | 1719 void LoadMenu::PressOk(void) { |
1720 if (select_value == -1) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1721 btn_set->SetValue(-1); // なにもしない |
0 | 1722 return; |
1723 } | |
1724 menu->deactivate(); | |
1725 if (interface.type == Scn2kMenu::MENU_LOAD) { | |
1726 interface.cmd.cmd_type = CMD_LOAD; | |
1727 interface.cmd.args.push_back(VarInfo(select_value)); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1728 awk_dialog = new Dialog(*pevent, pparent, "ファイルをロードしますか?", true); |
0 | 1729 awk_dialog->set_pointer = this; |
1730 awk_dialog->set_func = ChangeDialog; | |
1731 } else {// MENU_SAVE | |
1732 interface.cmd.cmd_type = CMD_SAVE; | |
1733 interface.cmd.args.push_back(VarInfo(select_value)); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1734 if (title_valid[select_value] == 0) { // 新しいセーブデータ |
0 | 1735 interface.status = Scn2kMenu::MenuStatus(Scn2kMenu::MENU_CMD | Scn2kMenu::MENU_DELETE); |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1736 } else { // セーブデータを上書き:確認 |
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1737 awk_dialog = new Dialog(*pevent, pparent, "データを上書きしますか?", true); |
0 | 1738 awk_dialog->set_pointer = this; |
1739 awk_dialog->set_func = ChangeDialog; | |
1740 } | |
1741 } | |
1742 } | |
52 | 1743 |
0 | 1744 void LoadMenu::Cancel(void) { |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1745 if (awk_dialog != NULL) { // ダイアログのキャンセル |
0 | 1746 awk_dialog->status = Dialog::CANCEL; |
1747 ChangeDialog(this, awk_dialog); | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1748 } else { // 一般キャンセル |
0 | 1749 btn_set->SetValue(1); |
1750 } | |
1751 } | |
52 | 1752 |
0 | 1753 void LoadMenu::Exec(Cmd& cmd) { |
1754 } | |
52 | 1755 |
0 | 1756 void LoadMenu::ChangeBtnPage(void* pointer, MenuItem* widget) { |
1757 LoadMenu* instance = (LoadMenu*)pointer; | |
1758 if (instance->btn_page_val == -1) return; | |
1759 instance->SetPage(instance->btn_page_val*100); | |
1760 } | |
52 | 1761 |
0 | 1762 void LoadMenu::ChangeBtnScale(void* pointer, Scale* from) { |
1763 LoadMenu* instance = (LoadMenu*)pointer; | |
1764 int value = from->GetValue(); | |
1765 instance->SetPage(value); | |
1766 } | |
52 | 1767 |
0 | 1768 void LoadMenu::ChangeBtnSet(void* pointer, MenuItem* widget) { |
1769 LoadMenu* instance = (LoadMenu*)pointer; | |
1770 if (instance->btn_set_val == 1) { // cancel | |
1771 instance->interface.status = Scn2kMenu::MENU_DELETE; | |
1772 return; | |
1773 } else if (instance->btn_set_val == 0) { // OK | |
1774 instance->PressOk(); | |
1775 } | |
1776 } | |
52 | 1777 |
0 | 1778 void LoadMenu::ChangeDialog(void* pointer, Dialog* widget) { |
1779 LoadMenu* instance = (LoadMenu*)pointer; | |
1780 if (widget->status == Dialog::CANCEL) { | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1781 // ダイアログ消去、OK ボタン復帰 |
0 | 1782 delete instance->awk_dialog; |
52 | 1783 instance->awk_dialog = NULL; |
0 | 1784 instance->menu->activate(); |
1785 instance->btn_set->SetValue(-1); | |
1786 return; | |
1787 } else if (widget->status == Dialog::OK) { | |
1788 instance->interface.status = Scn2kMenu::MenuStatus(Scn2kMenu::MENU_CMD | Scn2kMenu::MENU_DELETE); | |
1789 return; | |
1790 } | |
1791 } | |
52 | 1792 |
0 | 1793 void LoadMenu::ChangeBtnLocal(void* pointer, MenuItem* widget) { |
1794 LoadMenu* instance = (LoadMenu*)pointer; | |
1795 if (instance->btn_local_val == -1) return; | |
1796 instance->SetValue( (instance->select_page/10) + instance->btn_local_val); | |
1797 } | |
1798 | |
1799 struct BacklogMenu : Scn2kMenuImpl { | |
1800 Scn2k& scn_impl; | |
1801 Text& text_exec; | |
1802 bool backlog_update; | |
1803 int backlog_cnt; | |
1804 BacklogMenu(Scn2kMenu& _interface, Scn2k& scn_impl, Text& text_exec); | |
1805 ~BacklogMenu(); | |
1806 void InitPanel(Event::Container& event, PicContainer& parent); | |
1807 void InitTitle(const SaveTitle&); | |
1808 void Cancel(void); | |
1809 void Exec(Cmd& cmd); | |
1810 }; | |
52 | 1811 |
0 | 1812 BacklogMenu::BacklogMenu(Scn2kMenu& _interface, Scn2k& _scn, Text& parent_text_exec) : Scn2kMenuImpl(_interface), scn_impl(_scn), text_exec(parent_text_exec) { |
1813 backlog_cnt = -1; | |
1814 backlog_update = false; | |
1815 } | |
52 | 1816 |
0 | 1817 BacklogMenu::~BacklogMenu() { |
1818 } | |
52 | 1819 |
0 | 1820 void BacklogMenu::InitPanel(Event::Container& event, PicContainer& parent) { |
1821 pevent = &event; | |
1822 } | |
1823 | |
1824 void BacklogMenu::InitTitle(const SaveTitle& title_op) { | |
1825 } | |
52 | 1826 |
0 | 1827 void BacklogMenu::Cancel(void) { |
1828 interface.status = Scn2kMenu::MenuStatus(Scn2kMenu::MENU_DELETE); | |
1829 } | |
52 | 1830 |
0 | 1831 void BacklogMenu::Exec(Cmd& cmd) { |
1832 int command_direction = 0; // forward | |
1833 if (cmd.cmd_type == CMD_NOP) text_exec.Wait(0xffffffffUL, cmd); | |
1834 if (cmd.cmd_type == CMD_BACKLOGREQ || pevent->presscount(MOUSE_UP)) { | |
1835 if (cmd.cmd_type == CMD_BACKLOGREQ) cmd.clear(); | |
1836 backlog_cnt++; | |
1837 backlog_update = false; | |
1838 command_direction = 1; | |
1839 } | |
1840 if (cmd.cmd_type == CMD_BACKLOGREQ_FWD || pevent->presscount(MOUSE_DOWN)) { | |
1841 if (cmd.cmd_type == CMD_BACKLOGREQ_FWD) cmd.clear(); | |
1842 backlog_cnt--; | |
1843 backlog_update = false; | |
1844 if (backlog_cnt == -2 || ( | |
1845 (backlog_cnt == -1 && text_exec.backlog_item.scn == -1 && text_exec.backlog_item.pos == -1)) ){ | |
1846 Cancel(); | |
1847 return; | |
1848 } | |
1849 command_direction = -1; | |
1850 } | |
1851 if (cmd.cmd_type != CMD_NOP) return; | |
1852 if (backlog_update) return; | |
65
4416cfac86ae
Convert EUC-JP files to UTF8
Thibaut Girka <thib@sitedethib.com>
parents:
62
diff
changeset
|
1853 // backlog を最新の状態に更新 |
0 | 1854 cmd.clear(); |
1855 BacklogItem item; | |
1856 | |
1857 retry: | |
1858 if (backlog_cnt < -1) backlog_cnt = -1; | |
1859 if (backlog_cnt >= int(text_exec.backlog.size())) backlog_cnt = text_exec.backlog.size() - 1; | |
1860 | |
1861 if (backlog_cnt == -1) { | |
1862 if (text_exec.backlog_item.scn == -1 && text_exec.backlog_item.pos == -1) { | |
1863 if (text_exec.backlog.size() == 0 || command_direction < 0) { | |
1864 Cancel(); | |
1865 return; | |
1866 } | |
1867 item = text_exec.backlog.back(); | |
1868 backlog_cnt = 0; | |
1869 } else { | |
1870 // item = text_exec.backlog.back(); | |
1871 item = text_exec.backlog_item; | |
1872 } | |
1873 } else { | |
1874 item = text_exec.backlog[text_exec.backlog.size()-1-backlog_cnt]; | |
1875 } | |
1876 if (item.scn == BacklogItem::SaveSelect) { // select marker ; skip this item | |
1877 if (command_direction == 0) command_direction = 1; | |
1878 backlog_cnt += command_direction; | |
1879 goto retry; | |
1880 } | |
1881 if (item.scn == 0 && item.pos == -1) ; // not read cmd | |
1882 else { | |
1883 scn_impl.ReadCmdAt(cmd, item.scn, item.pos); | |
1884 } | |
1885 text_exec.DrawBacklog(item, cmd); | |
1886 cmd.clear(); | |
1887 backlog_update = true; | |
1888 } | |
1889 | |
1890 /******************************************************************************* | |
1891 ** | |
1892 ** | |
1893 */ | |
1894 | |
1895 Scn2kMenu::Scn2kMenu(MenuType _type, Scn2k& scn_impl, const Flags& flags, Text& text_exec, int system_version) : | |
1896 cmd(flags, system_version), type(_type) { | |
52 | 1897 pimpl = NULL; |
0 | 1898 status = MENU_CONTINUE; |
1899 switch(type) { | |
1900 case MENU_LOAD: pimpl = new LoadMenu(*this); break; | |
1901 case MENU_SAVE: pimpl = new LoadMenu(*this); break; | |
1902 case MENU_BACKLOG: pimpl = new BacklogMenu(*this, scn_impl, text_exec); break; | |
1903 } | |
1904 } | |
53
ddbcbd000206
* MuSys, AyuSysConfig, FileSearcher (former FILESEARCHER) and KeyHolder (former KEYHOLDER) are now singletons
thib
parents:
52
diff
changeset
|
1905 |
0 | 1906 Scn2kMenu::~Scn2kMenu() { |
1907 if (pimpl) delete pimpl; | |
52 | 1908 pimpl = NULL; |
0 | 1909 } |
52 | 1910 |
0 | 1911 void Scn2kMenu::InitPanel(Event::Container& event, PicContainer& parent) { |
52 | 1912 if (pimpl != NULL) pimpl->InitPanel(event, parent); |
0 | 1913 } |
52 | 1914 |
0 | 1915 void Scn2kMenu::InitTitle(const SaveTitle& t) { |
52 | 1916 if (pimpl != NULL) pimpl->InitTitle(t); |
0 | 1917 } |
52 | 1918 |
0 | 1919 void Scn2kMenu::Cancel(void) { |
1920 if (pimpl) pimpl->Cancel(); | |
1921 } | |
52 | 1922 |
0 | 1923 void Scn2kMenu::Exec(Cmd& ret_cmd) { |
52 | 1924 if (pimpl == NULL) return; |
0 | 1925 pimpl->Exec(ret_cmd); |
1926 if (pimpl->pevent->presscount(MOUSE_RIGHT)) { | |
1927 Cancel(); | |
1928 } | |
1929 if (status & MENU_CMD && cmd.cmd_type != CMD_NOP) { | |
1930 status = Scn2kMenu::MenuStatus(status & (~Scn2kMenu::MENU_CMD) ); | |
1931 CmdSimplified tmp_cmd; | |
1932 char cmd_str[32768]; | |
1933 char* tmp_cmd_str = cmd_str; | |
1934 cmd.write(tmp_cmd, tmp_cmd_str); | |
1935 ret_cmd.read(tmp_cmd); | |
1936 } | |
1937 } | |
52 | 1938 |
0 | 1939 void Scn2kMenu::activate(void) { |
52 | 1940 if (pimpl != NULL && pimpl->menu) pimpl->menu->activate(); |
0 | 1941 } |
1942 | |
52 | 1943 void Scn2kMenu::deactivate(void) { |
1944 if (pimpl != NULL && pimpl->menu) pimpl->menu->deactivate(); | |
1945 } | |
1946 |