Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/CSaveFile.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations) (download) (as text)
Sun Sep 9 04:21:31 2012 UTC (11 years, 8 months ago) by okadu
File MIME type: text/x-c++src
File size: 28711 byte(s)
[okadu] Version 2.14a バグ修正いろいろ

1 #include "stdafx.h"
2 #include "md5.h"
3 #include "RailMap.h"
4 #include "Network.h"
5 #include "CJobTimer.h"
6 #include "CListView.h"
7 #include "CSimpleDialog.h"
8 #include "CRailWay.h"
9 #include "CTrainGroup.h"
10 #include "CScene.h"
11 #include "CSaveFile.h"
12 #include "CDiaInst.h"
13 #include "CModelInst.h"
14 #include "CSurfacePlugin.h"
15 #include "CEnvPlugin.h"
16 #include "CSkinPlugin.h"
17 #include "CSimulationMode.h"
18 #include "CConfigMode.h"
19 #include "CNeutralMode.h"
20 #include "CRailPlugin.h"
21 #include "CTiePlugin.h"
22 #include "CGirderPlugin.h"
23 #include "CPierPlugin.h"
24 #include "CLinePlugin.h"
25
26 // 関数宣言
27 bool IsLeapYear(int);
28 int GetDaysPerMonth(int, int);
29
30 // 外部定数
31 extern const char *LAYOUT_DIRNAME;
32
33 // 内部定数
34 const float WIND_MAX = 0.5f; // 最大風速
35
36 // 外部グローバル
37 extern CTrain *g_CabinViewTrain;
38 extern char *YESNO[];
39
40 // 内部グローバル
41 char *g_DayOfWeek[7]; // 曜日
42 char *g_TrainSetString[2] = {lang(NotSet), lang(Set)}; // 編成設置状態
43 CScene *g_Scene; // カレントシーン
44 CTrainGroup *g_TrainGroup; // カレント編成
45 map<void *, void *> g_AddressMap; // アドレス変換
46 set<string> g_LackPlugin; // 不足プラグイン
47 //int g_GroupEndCount = 0; // debug
48
49 /*
50 * コンストラクタ
51 */
52 CSaveFile::CSaveFile(
53 bool preset // プリセット編成・シーン準備
54 ){
55 m_NetworkSyncCount = 0;
56 m_Year = m_Month = m_Day = m_Hour = m_Minute
57 = m_Second = m_Frame = m_DayOfWeek = m_SumDays = 0;
58 for(; m_Month<3; m_Month++) m_SumDays += GetDaysPerMonth(0, m_Month);
59 m_Hour = 12;
60 m_GroupNum = m_SceneNum = 1;
61 m_WarpList = NULL;
62 if(preset){
63 g_TrainGroup = m_GroupList = new CTrainGroup(lang(InitialConsist));
64 g_Scene = m_SceneList = new CScene(g_DefaultSurface, g_DefaultEnv, lang(InitialScene));
65 }else{
66 g_TrainGroup = m_GroupList = NULL;
67 g_Scene = m_SceneList = NULL;
68 }
69 ClearRailBlockUser(NULL);
70 NumberGroup();
71 NumberScene();
72 UpdateWind();
73 UpdateWind();
74 CParticle::InitRenderList();
75 if(g_Scene) g_Scene->Enter(false);
76 }
77
78 /*
79 * デストラクタ
80 */
81 CSaveFile::~CSaveFile(){
82 g_Scene = NULL;
83 if(g_ConfigMode) g_ConfigMode->FreeWindowDiv();
84 DELETE_V(m_WarpList);
85 DELETE_V(m_GroupList);
86 DELETE_V(m_SceneList);
87 }
88
89 /*
90 * 風方向の更新
91 */
92 void CSaveFile::UpdateWind(){
93 float theta = FRand(2.0f*D3DX_PI);
94 float speed = FRand(WIND_MAX)*FRand(WIND_MAX)/WIND_MAX;
95 m_WindDir1 = m_WindDir2;
96 m_WindDir2 = speed*VEC3(sinf(theta), 0.0f, cosf(theta));
97 m_WindCount = 0;
98 m_WindTime = Rand2(12*60*60*MAXFPS, 48*60*60*MAXFPS);
99 }
100
101 /*
102 * ワープリストルート設定
103 */
104 void CSaveFile::SetWarpRoot(){
105 CRailWay::SetRoot(&m_WarpList);
106 }
107
108 /*
109 * 閉塞区間設定
110 */
111 /*bool CSaveFile::SetRailBlock(char *rb){
112 bool changed = false;
113 CScene *ptr = m_SceneList;
114 while(ptr){
115 changed |= ptr->SetRailBlock(rb);
116 ptr = ptr->Next();
117 }
118 return changed;
119 }*/
120
121 /*
122 * ワープ削除
123 */
124 bool CSaveFile::DeleteWarp(){
125 bool deleted = false;
126 CRailWay *ptr, **adr = &m_WarpList;
127 while(ptr = *adr){
128 *adr = ptr->Delete();
129 if(ptr==*adr) adr = ptr->NextAdr();
130 else deleted = true;
131 }
132 return deleted;
133 }
134
135 /*
136 * 編成追加
137 */
138 void CSaveFile::AddGroup(){
139 m_GroupNum++;
140 CTrainGroup **adr = &m_GroupList;
141 while(*adr) adr = (*adr)->NextAdr();
142 *adr = new CTrainGroup(lang(NewConsist));
143 NumberGroup();
144 }
145
146 /*
147 * 編成削除
148 */
149 void CSaveFile::DeleteGroup(
150 CTrainGroup *gr // 編成
151 ){
152 CTrainGroup **adr = &m_GroupList;
153 g_TrainGroup = NULL;
154 while(*adr){
155 if(*adr==gr){
156 CScene *scene = m_SceneList;
157 while(scene){
158 scene->DeleteGroup(gr);
159 scene = scene->Next();
160 }
161 CTrainGroup *tmp = *adr;
162 *adr = tmp->Next();
163 *tmp->NextAdr() = NULL;
164 delete tmp;
165 if(!g_TrainGroup) g_TrainGroup = *adr;
166 m_GroupNum--;
167 break;
168 }
169 g_TrainGroup = *adr;
170 adr = (*adr)->NextAdr();
171 }
172 NumberGroup();
173 }
174
175 /*
176 * 編成リスト作成
177 */
178 void CSaveFile::ListGroup(
179 CListView *lv // リストビュー
180 ){
181 char *train_set_string[2] = {lang(NotSet), lang(Set)}; // 編成設置状態
182 CTrainGroup *ptr = m_GroupList;
183 lv->DeleteAllItems();
184 int i = 0;
185 while(ptr){
186 CListElement *le = lv->InsertItem(-1, ptr->GetName());
187 le->SetString(1, FlashIn("%d", ptr->GetTrainNum()));
188 le->SetString(2, train_set_string[ptr->IsSet()]);
189 le->SetData((DWORD)ptr);
190 ptr->SetListElement(le);
191 if(ptr==g_TrainGroup) lv->SetSelectionMark(i, 0);
192 i++;
193 ptr = ptr->Next();
194 }
195 lv->EnsureVisible(lv->GetSelectionMark());
196 }
197
198 /*
199 * 編成リスト作成 (ダイヤ設定用)
200 */
201 void CSaveFile::ListGroupDia(
202 CListView *lv, // リストビュー
203 CDiaInstBase *dinst // ダイヤ
204 ){
205 CTrainGroup *ptr = m_GroupList;
206 lv->DeleteAllItems();
207 int i = 0;
208 while(ptr){
209 CListElement *le = lv->InsertItem(-1, ptr->GetName());
210 le->SetString(1, FlashIn("%d", ptr->GetTrainNum()));
211 le->SetString(2, g_DiaDefaultString[dinst->IsDefault(ptr)]);
212 le->SetData((DWORD)ptr);
213 ptr->SetListElement(le);
214 if(ptr==g_TrainGroup) lv->SetSelectionMark(i, 0);
215 i++;
216 ptr = ptr->Next();
217 }
218 }
219
220 /*
221 * プラットフォーム削除
222 */
223 void CSaveFile::DeletePlatform(
224 CPlatformInst *pf // プラットフォーム
225 ){
226 CTrainGroup *ptr = m_GroupList;
227 while(ptr){
228 ptr->DeletePlatform(pf);
229 ptr = ptr->Next();
230 }
231 }
232
233 /*
234 * 編成番号を付ける
235 */
236 void CSaveFile::NumberGroup(){
237 int i = 0;
238 m_GroupNum = 0;
239 CTrainGroup *ptr = m_GroupList;
240 while(ptr){
241 m_GroupNum++;
242 ptr->SetSerial(i++);
243 ptr = ptr->Next();
244 }
245 }
246
247 /*
248 * 次の編成を選択
249 */
250 void CSaveFile::NextGroup(
251 bool prev // 逆方向
252 ){
253 if(prev){
254 CTrainGroup *ptr = m_GroupList;
255 while(ptr){
256 if(!ptr->Next() || ptr->Next()==g_TrainGroup){
257 g_TrainGroup = ptr;
258 break;
259 }
260 ptr = ptr->Next();
261 }
262 }else{
263 g_TrainGroup = g_TrainGroup && g_TrainGroup->Next()
264 ? g_TrainGroup->Next() : m_GroupList;
265 }
266 }
267
268 /*
269 * 順序取得
270 */
271 vector<CTrainGroup *> CSaveFile::GetTrainGroupByVector(){
272 vector<CTrainGroup *> group_list;
273 CTrainGroup *ptr = m_GroupList;
274 while(ptr){
275 group_list.push_back(ptr);
276 ptr = ptr->Next();
277 }
278 return group_list;
279 }
280
281 /*
282 * 編成順序変更
283 */
284 void CSaveFile::SetTrainGroupByVector(vector<CTrainGroup *> group_list){
285 int i;
286 m_GroupList = group_list.size() ? group_list[0] : NULL;
287 for(i = 0; i<group_list.size(); ++i)
288 *group_list[i]->NextAdr() = i<group_list.size()-1 ? group_list[i+1] : NULL;
289 NumberGroup();
290 }
291
292 /*
293 * ワープ入力チェック
294 */
295 void CSaveFile::ScanInputWarp(
296 int mode, // モード
297 VEC3 rect1, // 領域始点
298 VEC3 rect2 // 領域終点
299 ){
300 CRailWay::ResetDetect();
301 CRailWay *warp = m_WarpList;
302 while(warp){
303 warp->ScanInputWarp(mode, rect1, rect2);
304 warp = warp->Next();
305 }
306 }
307
308 /*
309 * インスタンス入力チェック
310 */
311 void CSaveFile::ScanInputInst(
312 int mode, // モード
313 VEC3 rect1, // 領域始点
314 VEC3 rect2 // 領域終点
315 ){
316 CModelInst::ResetDetect(mode, rect1, rect2);
317 CTrainGroup *group = m_GroupList;
318 while(group){
319 group->ScanInput(mode, rect1, rect2);
320 group = group->Next();
321 }
322 g_Scene->ScanInputStation(mode, rect1, rect2);
323 g_Scene->ScanInputStruct(mode, rect1, rect2);
324 }
325
326 /*
327 * シーン追加
328 */
329 void CSaveFile::AddScene(
330 CSurfacePlugin *spi // 地形プラグイン
331 ){
332 m_SceneNum++;
333 CScene **adr = &m_SceneList;
334 while(*adr) adr = (*adr)->NextAdr();
335 (*adr = new CScene(spi, g_DefaultEnv, lang(NewScene)))->Enter(false);
336 NumberScene();
337 }
338
339 /*
340 * シーン削除
341 */
342 void CSaveFile::DeleteScene(
343 CScene *sc // シーン
344 ){
345 sc->Delete();
346 CRailWay *warp = m_WarpList;
347 while(warp){
348 warp->CheckWarpEndScene(sc);
349 warp = warp->Next();
350 }
351 DeleteWarp();
352 CScene **adr = &m_SceneList;
353 g_Scene = sc;
354 g_RailPluginList->ClearDumpAll();
355 g_TiePluginList->ClearDumpAll();
356 g_GirderPluginList->ClearDumpAll();
357 g_PierPluginList->ClearDumpAll();
358 g_LinePluginList->ClearDumpAll();
359 g_Scene = NULL;
360 while(*adr){
361 if(*adr==sc){
362 CScene *tmp = *adr;
363 *adr = tmp->Next();
364 *tmp->NextAdr() = NULL;
365 delete tmp;
366 if(!g_Scene) g_Scene = *adr;
367 m_SceneNum--;
368 break;
369 }
370 g_Scene = *adr;
371 adr = (*adr)->NextAdr();
372 }
373 if(!m_SceneList){
374 g_Scene = m_SceneList = new CScene(g_DefaultSurface, g_DefaultEnv, lang(InitialScene));
375 m_SceneNum = 1;
376 }
377 CScene *ptr = m_SceneList;
378 while(ptr){
379 ptr->SetDumpReady(false);
380 ptr = ptr->Next();
381 }
382 NumberScene();
383 g_Scene->Enter(false);
384 g_ConfigMode->GetRootWindow()->OnDeleteScene(sc);
385 }
386
387 /*
388 * シーンリスト作成
389 */
390 void CSaveFile::ListScene(
391 CListView *lv // リストビュー
392 ){
393 CScene *ptr = m_SceneList;
394 lv->DeleteAllItems();
395 int i = 0;
396 while(ptr){
397 CListElement *le = lv->InsertItem(-1, ptr->GetName());
398 le->SetString(1, ptr->GetSurface()->GetName());
399 le->SetData((DWORD)ptr);
400 ptr->SetListElement(le);
401 if(ptr==g_Scene) lv->SetSelectionMark(i, 0);
402 i++;
403 ptr = ptr->Next();
404 }
405 }
406
407 /*
408 * シーン番号を付ける
409 */
410 void CSaveFile::NumberScene(){
411 int i = 0;
412 m_SceneNum = 0;
413 CScene *ptr = m_SceneList;
414 while(ptr){
415 m_SceneNum++;
416 ptr->SetSerial(i++);
417 ptr = ptr->Next();
418 }
419 }
420
421 /*
422 * 次のシーンを選択
423 */
424 void CSaveFile::NextScene(
425 bool prev // 逆方向
426 ){
427 CWindowInfo* active_wnd = g_ConfigMode->GetActiveWindow();
428 CScene *origscene = g_Scene;
429 if(active_wnd && active_wnd->GetScene()) g_Scene = active_wnd->GetScene();
430 CScene *oldscene = g_Scene;
431 if(prev){
432 CScene *ptr = m_SceneList;
433 while(ptr){
434 if(!ptr->Next() || ptr->Next()==g_Scene){
435 g_Scene = ptr;
436 break;
437 }
438 ptr = ptr->Next();
439 }
440 }else{
441 g_Scene = g_Scene && g_Scene->Next() ? g_Scene->Next() : m_SceneList;
442 }
443 if(g_Scene!=oldscene) g_Scene->Enter(true);
444 if(active_wnd){
445 active_wnd->SetScene(g_Scene);
446 g_Scene = origscene;
447 }
448 }
449
450 /*
451 * 順序取得
452 */
453 vector<CScene *> CSaveFile::GetSceneByVector(){
454 vector<CScene *> scene_list;
455 CScene *ptr = m_SceneList;
456 while(ptr){
457 scene_list.push_back(ptr);
458 ptr = ptr->Next();
459 }
460 return scene_list;
461 }
462
463 /*
464 * 編成順序変更
465 */
466 void CSaveFile::SetSceneByVector(vector<CScene *> scene_list){
467 int i;
468 m_SceneList = scene_list.size() ? scene_list[0] : NULL;
469 for(i = 0; i<scene_list.size(); ++i)
470 *scene_list[i]->NextAdr() = i<scene_list.size()-1 ? scene_list[i+1] : NULL;
471 NumberScene();
472 }
473
474 /*
475 * レンダリング
476 */
477 void CSaveFile::RenderScene(
478 int option // 1: renderwarp
479 ){
480 TIMER_RAII("CSaveFile::RenderScene()");
481 InitShadow();
482 InitRailMap();
483 CNamedObject::InitAfterRenderList();
484 CHeadlight::InitRenderList();
485 ResetSwitch();
486 g_Scene->RenderScene();
487 devSetState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
488 devSetState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
489 {
490 TIMER_RAII("train group");
491 CTrainGroup *group = m_GroupList;
492 while(group){
493 group->Render();
494 group = group->Next();
495 }
496 }
497 devSetState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
498 devSetState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1);
499 RenderShadow();
500 devSetState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
501 devSetState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
502 CNamedObject::AfterRenderAll();
503 devSetState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
504 devSetState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1);
505 {
506 TIMER_RAII("effect");
507 CParticle::RenderAll();
508 CHeadlight::RenderAll();
509 }
510 g_Scene->RenderAfter();
511 devResetMatrix();
512 devSetTexture(0, NULL);
513 devSetZRead(FALSE);
514 devSetZWrite(FALSE);
515 devSetLighting(FALSE);
516 if(option&1){
517 CRailWay *warp = m_WarpList;
518 while(warp){
519 warp->RenderWarp();
520 warp = warp->Next();
521 }
522 }
523 devSetZRead(TRUE);
524 devSetZWrite(TRUE);
525 devSetLighting(TRUE);
526
527 //SetWindowText(svw.hWnd, FlashIn("g_GroupEndCount = %d", g_GroupEndCount));
528 //g_GroupEndCount = 0;
529 }
530
531 /*
532 * シミュレーション進行
533 */
534 void CSaveFile::Simulate(
535 int num // 回数
536 ){
537 TIMER_RAII("CSaveFile::Simulate()");
538 int scale = g_SimulationMode->GetTimeScale();
539 int speed = num<0 ? g_SimulationMode->GetSimSpeed() : num;
540 int i;
541 bool exceed = true;
542 void UpdateSyncLimit();
543 UpdateSyncLimit();
544 if(!speed && g_NetworkInitialized
545 && m_NetworkSyncCount<g_NetworkSyncLimitReceived
546 && m_NetworkSyncCount<g_NetworkSyncLimitSent){
547 exceed = false;
548 speed = g_SimulationMode->GetOldSpeed();
549 }
550 for(i = 0; i<speed; i++){
551 TIMER_RAII("single simulation");
552 if(g_NetworkInitialized){
553 if(exceed) ExceedNetworkSyncLimit(m_NetworkSyncCount);
554 if(m_NetworkSyncCount){
555 if(m_NetworkSyncCount>=g_NetworkSyncLimitReceived
556 || m_NetworkSyncCount>=g_NetworkSyncLimitSent) return;
557 }
558 void SyncTrainControls(int);
559 SyncTrainControls(m_NetworkSyncCount);
560 }
561 m_NetworkSyncCount++;
562 //SetWindowText(svw.hWnd, FlashIn("net sync = %d", m_NetworkSyncCount));
563
564 int dpm = GetDaysPerMonth(m_Year, m_Month);
565 m_Frame += scale;
566 m_Second += m_Frame/30;
567 m_Frame %= 30;
568 m_Minute += m_Second/60;
569 m_Second %= 60;
570 m_Hour += m_Minute/60;
571 m_Minute %= 60;
572 m_Day += m_Hour/24;
573 m_SumDays += m_Hour/24;
574 m_DayOfWeek += m_Hour/24;
575 m_Hour %= 24;
576 m_Month += m_Day/dpm;
577 m_Day %= dpm;
578 m_DayOfWeek %= 7;
579 m_Year += m_Month/12;
580 m_Month %= 12;
581
582 float wtmp = (float)m_WindCount/m_WindTime;
583 g_WindDir = (1.0f-wtmp)*m_WindDir1+wtmp*m_WindDir2;
584 if(V3Len(&g_WindDir)) V3Norm(&g_WindDirNorm, &g_WindDir);
585 if((m_WindCount += scale)>=m_WindTime) UpdateWind();
586
587 ResetSwitch();
588
589 CParticle::SimulateAll();
590 CScene *scene = m_SceneList;
591 while(scene){
592 scene->SimulateScene();
593 scene = scene->Next();
594 }
595 CTrainGroup *group = m_GroupList;
596 while(group){
597 group->Simulate();
598 group = group->Next();
599 }
600 g_CabinViewTrain = NULL;
601 }
602 }
603
604 /*
605 * スイッチリセット
606 */
607 void CSaveFile::ResetSwitch(){
608 g_SystemSwitch[SYS_SW_FRONT].SetValue(0);
609 g_SystemSwitch[SYS_SW_CONNECT1].SetValue(0);
610 g_SystemSwitch[SYS_SW_CONNECT2].SetValue(0);
611 g_SystemSwitch[SYS_SW_DOOR1].SetValue(0);
612 g_SystemSwitch[SYS_SW_DOOR2].SetValue(0);
613 g_SystemSwitch[SYS_SW_SERIAL].SetValue(0);
614 g_SystemSwitch[SYS_SW_CAMDIST].SetValue(0);
615 g_SystemSwitch[SYS_SW_VELOCITY].SetValue(0);
616 g_SystemSwitch[SYS_SW_ACCEL].SetValue(0);
617 g_SystemSwitch[SYS_SW_CABINVIEW].SetValue(0);
618 g_SystemSwitch[SYS_SW_APPROACH1].SetValue(0);
619 g_SystemSwitch[SYS_SW_APPROACH2].SetValue(0);
620 g_SystemSwitch[SYS_SW_STOPPING].SetValue(0);
621 if(g_RSPV){
622 g_SystemSwitch[SYS_SW_YEAR].SetValue(1);
623 g_SystemSwitch[SYS_SW_MONTH].SetValue(1);
624 g_SystemSwitch[SYS_SW_DAY].SetValue(1);
625 g_SystemSwitch[SYS_SW_DAYOFWEEK].SetValue(0);
626 g_SystemSwitch[SYS_SW_HOUR].SetValue(0);
627 g_SystemSwitch[SYS_SW_MINUTE].SetValue(0);
628 g_SystemSwitch[SYS_SW_SECOND].SetValue(0);
629 }else{
630 g_SystemSwitch[SYS_SW_YEAR].SetValue(m_Year+1);
631 g_SystemSwitch[SYS_SW_MONTH].SetValue(m_Month+1);
632 g_SystemSwitch[SYS_SW_DAY].SetValue(m_Day+1);
633 g_SystemSwitch[SYS_SW_DAYOFWEEK].SetValue(m_DayOfWeek);
634 g_SystemSwitch[SYS_SW_HOUR].SetValue(m_Hour);
635 g_SystemSwitch[SYS_SW_MINUTE].SetValue(m_Minute);
636 g_SystemSwitch[SYS_SW_SECOND].SetValue(m_Second);
637 }
638 }
639
640 /*
641 * 日時文字列の取得
642 */
643 char *CSaveFile::GetTimeText(){
644 return FlashIn("%02d/%02d/%02d (%s) %02d:%02d",
645 m_Year+1, m_Month+1, m_Day+1, g_DayOfWeek[m_DayOfWeek], m_Hour, m_Minute);
646 }
647
648 /*
649 * 読込
650 */
651 bool CSaveFile::Load(
652 const char *fname, // ファイル名
653 const char *dirname, // ディレクトリ名
654 bool warn, // 開けない場合警告
655 bool upname, // ファイル名更新
656 char **copy, // データコピー先
657 int *copysize, // コピーサイズ
658 bool checkhash, // ハッシュチェック要求
659 char *auxdata // 外部入力
660 ){
661 FILE *df;
662 if(!auxdata){
663 if(chdir(g_BaseDir) || chdir(dirname) || !(df = fopen(fname, "rb"))){
664 if(warn){
665 EnqueueCommonDialog(new CSimpleDialog(lang(CannotOpenFile), (char *)fname));
666 g_Skin->Error();
667 }
668 return false;
669 }
670 }
671 void ClearStaticSwitchTable();
672 ClearStaticSwitchTable();
673 g_Scene = NULL;
674 g_ConfigMode->FreeWindowDiv();
675 g_TrainGroup = NULL;
676 g_AddressMap.clear();
677 g_AddressMap[NULL] = NULL;
678 g_LackPlugin.clear();
679 if(upname) m_FileName = fname;
680 CScene *currentscene;
681 char *buf;
682 if(auxdata){
683 int copysize = strlen(auxdata);
684 buf = new char[copysize+1];
685 memcpy(buf, auxdata, copysize);
686 buf[copysize] = 0;
687 }else{
688 buf = LoadBinaryText(df);
689 }
690 char *str = buf, *eee, *tmp;
691 if(copy){
692 int tmp = strlen(buf);
693 *copy = new char[tmp+1];
694 *copysize = tmp;
695 memcpy(*copy, buf, tmp);
696 (*copy)[tmp] = 0;
697 }
698 if(checkhash){
699 MD5 hash;
700 int tmp = strlen(buf);
701 hash.update((unsigned char *)buf, tmp);
702 hash.finalize();
703 CheckLayoutDigest(hash.raw_digest());
704 }
705 try{
706 if(!(str = Space(eee = str))) throw CSynErr(eee);
707 if(!(str = BeginBlock(eee = str, "DatafileHeader"))) throw CSynErr(eee);
708 if(!(str = AsgnFloat(eee = str, "RailSimVersion", &m_Version))) throw CSynErr(eee);
709 if(m_Version<2.00f) throw CSynErr(eee, "%s: %.2f", lang(InvalidVersion), m_Version);
710 if(RAILSIM_VERSION<m_Version) throw CSynErr(eee, "%s: %.2f", lang(UnsupportedVersion), m_Version);
711 string datafiletype;
712 if(!(str = AsgnIdentifier(eee = str, "DatafileType", &datafiletype))) throw CSynErr(eee);
713 if(datafiletype!=LAYOUT_DIRNAME) throw CSynErr(eee, lang(InvalidDatafileType));
714 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
715
716 if(!(str = BeginBlock(eee = str, "LayoutInfo"))) throw CSynErr(eee);
717 if(!(str = AsgnString(eee = str, "Date", &m_FileDate))) throw CSynErr(eee);
718 if(!(str = AsgnString(eee = str, "Note", &m_FileNote))) throw CSynErr(eee);
719 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
720
721 if(!(str = BeginBlock(eee = str, "Time"))) throw CSynErr(eee);
722 if(!(str = Assignment(eee = str, "Date"))) throw CSynErr(eee);
723 if(!(str = ConstInteger(eee = str, &m_Year))) throw CSynErr(eee);
724 if(!(str = Character2(eee = str, ','))) throw CSynErr(eee);
725 if(!(str = ConstInteger(eee = str, &m_Month))) throw CSynErr(eee);
726 if(!(str = Character2(eee = str, ','))) throw CSynErr(eee);
727 if(!(str = ConstInteger(eee = str, &m_Day))) throw CSynErr(eee);
728 if(!(str = Character2(eee = str, ','))) throw CSynErr(eee);
729 if(!(str = ConstInteger(eee = str, &m_DayOfWeek))) throw CSynErr(eee);
730 if(!(str = Character2(eee = str, ';'))) throw CSynErr(eee);
731 if(!(str = Assignment(eee = str, "Time"))) throw CSynErr(eee);
732 if(!(str = ConstInteger(eee = str, &m_Hour))) throw CSynErr(eee);
733 if(!(str = Character2(eee = str, ','))) throw CSynErr(eee);
734 if(!(str = ConstInteger(eee = str, &m_Minute))) throw CSynErr(eee);
735 if(!(str = Character2(eee = str, ','))) throw CSynErr(eee);
736 if(!(str = ConstInteger(eee = str, &m_Second))) throw CSynErr(eee);
737 if(!(str = Character2(eee = str, ','))) throw CSynErr(eee);
738 if(!(str = ConstInteger(eee = str, &m_Frame))) throw CSynErr(eee);
739 if(!(str = Character2(eee = str, ';'))) throw CSynErr(eee);
740 if(!(str = AsgnInteger(eee = str, "SumDays", &m_SumDays))) throw CSynErr(eee);
741 int tsc, ssp, ert, erv;
742 if(!(str = AsgnInteger(eee = str, "TimeScale", &tsc))) throw CSynErr(eee);
743 if(!(str = AsgnInteger(eee = str, "SimulationSpeed", &ssp))) throw CSynErr(eee);
744 if(!(str = AsgnInteger(eee = str, "EarthRotation", &ert))) throw CSynErr(eee);
745 if(!(str = AsgnInteger(eee = str, "EarthRevolution", &erv))) throw CSynErr(eee);
746 g_SimulationMode->m_TimeScale[tsc].SetCheck();
747 g_SimulationMode->m_SimSpeed[ssp].SetCheck();
748 g_SimulationMode->m_EarthRotation[ert].SetCheck();
749 g_SimulationMode->m_EarthRevolution[erv].SetCheck();
750 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
751
752 bool man_ctrl = 0, ign_acc = 0;
753 if(m_Version>=2.11f){
754 if(!(str = BeginBlock(eee = str, "Simulation"))) throw CSynErr(eee);
755 if(!(str = AsgnYesNo(eee = str, "ManualControl", &man_ctrl))) throw CSynErr(eee);
756 if(!(str = AsgnYesNo(eee = str, "IgnoreAcceleration", &ign_acc))) throw CSynErr(eee);
757 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
758 }
759 g_SimulationMode->m_ManualControl.SetCheck(man_ctrl);
760 g_SimulationMode->m_IgnoreAcceleration.SetCheck(ign_acc);
761
762 if(!(str = BeginBlock(eee = str, "Wind"))) throw CSynErr(eee);
763 if(!(str = AsgnVector3D(eee = str, "Dir1", &m_WindDir1))) throw CSynErr(eee);
764 if(!(str = AsgnVector3D(eee = str, "Dir2", &m_WindDir1))) throw CSynErr(eee);
765 if(!(str = AsgnInteger(eee = str, "Count", &m_WindCount))) throw CSynErr(eee);
766 if(!(str = AsgnInteger(eee = str, "Time", &m_WindTime))) throw CSynErr(eee);
767 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
768
769 if(!(str = BeginBlock(eee = str, "WarpList"))) throw CSynErr(eee);
770 CRailWay::SetRoot(&m_WarpList);
771 while(true){
772 if(tmp = (new CRailWay)->ReadWarp(str)) str = tmp;
773 else break;
774 }
775 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
776
777 ClearRailBlockUser(NULL);
778 if(tmp = BeginBlock(str, "RailBlockList")){
779 str = tmp;
780 while(tmp = Assignment(str, "RailBlock")){
781 str = tmp;
782 std::string rb_name;
783 CTrainGroup *rb_group = NULL;
784 if(!(str = StringLiteral(str, &rb_name))) throw CSynErr(eee);
785 if(!(str = Character2(str, ','))) throw CSynErr(eee);
786 if(!(str = HexPointer(str, (void **)&rb_group))) throw CSynErr(eee);
787 g_RailBlockMap[RestoreDoubleQuote(rb_name)] = rb_group;
788 if(!(str = Character2(str, ';'))) throw CSynErr(eee);
789 }
790 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
791 }
792
793 if(!(str = BeginBlock(eee = str, "TrainGroupList"))) throw CSynErr(eee);
794 CTrainGroup **gadr = &m_GroupList;
795 while(true){
796 if(tmp = (new CTrainGroup(""))->Read(str, &gadr)) str = tmp;
797 else break;
798 }
799 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
800
801 if(!(str = BeginBlock(eee = str, "SceneList"))) throw CSynErr(eee);
802 if(!(str = AsgnPointer(eee = str, "CurrentScene", (void **)&currentscene))) throw CSynErr(eee);
803 CScene **sadr = &m_SceneList;
804 while(true){
805 g_Scene = new CScene();
806 if(tmp = g_Scene->Read(str, &sadr)) str = tmp;
807 else break;
808 }
809 g_Scene = NULL;
810 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
811
812 if(m_Version>=2.14f){
813 if(!(str = BeginBlock(eee = str, "Window"))) throw CSynErr(eee);
814 str = g_ConfigMode->GetRootWindow()->Read(str);
815 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
816 }
817 }
818 catch(CSynErr err){
819 err.Handle(FlashIn("%s <%s>", m_FileName.c_str(), "Layout"), buf);
820 return false;
821 }
822 DELETE_A(buf);
823 CRailWay *warp = m_WarpList;
824 while(warp){
825 warp->RestoreAddress();
826 warp = warp->Next();
827 }
828 map<std::string, CTrainGroup *>::iterator railblock;
829 for(railblock = g_RailBlockMap.begin(); railblock!=g_RailBlockMap.end(); ++railblock){
830 railblock->second = (CTrainGroup *)ReplaceAdr(railblock->second);;
831 }
832 CTrainGroup *group = m_GroupList;
833 while(group){
834 group->RestoreAddress();
835 group = group->Next();
836 }
837 CScene *scene = m_SceneList;
838 while(scene){
839 scene->RestoreAddress();
840 scene = scene->Next();
841 }
842 if(g_LackPlugin.size()){
843 chdir(g_BaseDir);
844 FILE *lacklog = fopen("LackPlugin.txt", "wt");
845 if(lacklog){
846 set<string>::iterator is = g_LackPlugin.begin();
847 for(; is!=g_LackPlugin.end(); is++) fprintf(lacklog, "%s\n", is->c_str());
848 fclose(lacklog);
849 ErrorDialog("%s\n%s", lang(LackedPluginMessage), lang(LackedPluginListSaved));
850 }else{
851 ErrorDialog("%s\n%s", lang(LackedPluginMessage), lang(LackedPluginListFailed));
852 }
853 }
854 g_TrainGroup = m_GroupList;
855 g_Scene = (CScene *)ReplaceAdr(currentscene);
856 g_Scene->Enter(true);
857 //g_AddressMap.clear();
858 NumberGroup();
859 NumberScene();
860 group = m_GroupList;
861 while(group){
862 group->RestoreSet();
863 group = group->Next();
864 }
865 scene = m_SceneList;
866 while(scene){
867 scene->ScanInputRailWay(4, V3ZERO, V3ZERO, true);
868 scene->ScanInputPier(4, V3ZERO, V3ZERO);
869 scene->ScanInputLine(4, V3ZERO, V3ZERO);
870 scene->ScanInputPole(4, V3ZERO, V3ZERO);
871 scene = scene->Next();
872 }
873 m_NetworkSyncCount = 0;
874 Simulate(1); // 1 回だけシミュレート
875 return true;
876 }
877
878 /*
879 * 保存
880 *
881 * 戻り値: 0: succeeded, 1: error, 2: file already exist
882 */
883 int CSaveFile::Save(
884 const char *fname, // ファイル名
885 const char *dirname, // ディレクトリ名
886 bool overwrite, // 上書き
887 bool upname // ファイル名更新
888 ){
889 FILE *df;
890 if(CheckSlash(fname) || chdir(g_BaseDir) || chdir(dirname)){
891 EnqueueCommonDialog(new CSimpleDialog(lang(CannotOpenFile), (char *)fname));
892 g_Skin->Error();
893 return 1;
894 }
895 if(!overwrite && (df = fopen(fname, "rb"))){
896 fclose(df);
897 return 2;
898 }
899 if(!(df = fopen(fname, "wt"))){
900 EnqueueCommonDialog(new CSimpleDialog(lang(CannotOpenFile), (char *)fname));
901 g_Skin->Error();
902 return 1;
903 }
904 if(upname) m_FileName = fname;
905 m_Version = RAILSIM_VERSION;
906
907 fprintf(df, "DatafileHeader{\n");
908 fprintf(df, "\tRailSimVersion = %.2f;\n", RAILSIM_VERSION);
909 fprintf(df, "\tDatafileType = %s;\n", LAYOUT_DIRNAME);
910 fprintf(df, "}\n\n");
911
912 SYSTEMTIME systime;
913 GetLocalTime(&systime);
914 fprintf(df, "LayoutInfo{\n");
915 fprintf(df, "\tDate = \"%04d/%02d/%02d (%s) %02d:%02d:%02d\";\n",
916 systime.wYear, systime.wMonth, systime.wDay, g_DayOfWeek[systime.wDayOfWeek],
917 systime.wHour, systime.wMinute, systime.wSecond);
918 fprintf(df, "\tNote = \"%s\";\n", ExpandDoubleQuote(m_FileNote).c_str());
919 fprintf(df, "}\n\n");
920
921 fprintf(df, "Time{\n");
922 fprintf(df, "\tDate = %d, %d, %d, %d;\n", m_Year, m_Month, m_Day, m_DayOfWeek);
923 fprintf(df, "\tTime = %d, %d, %d, %d;\n", m_Hour, m_Minute, m_Second, m_Frame);
924 fprintf(df, "\tSumDays = %d;\n", m_SumDays);
925 fprintf(df, "\tTimeScale = %d;\n", g_SimulationMode->m_TimeScale->GetNumber());
926 fprintf(df, "\tSimulationSpeed = %d;\n", g_SimulationMode->m_SimSpeed->GetNumber());
927 fprintf(df, "\tEarthRotation = %d;\n", g_SimulationMode->m_EarthRotation->GetNumber());
928 fprintf(df, "\tEarthRevolution = %d;\n", g_SimulationMode->m_EarthRevolution->GetNumber());
929 fprintf(df, "}\n\n");
930
931 fprintf(df, "Simulation{\n");
932 fprintf(df, "\tManualControl = %s;\n", YESNO[g_SimulationMode->GetManualControl()]);
933 fprintf(df, "\tIgnoreAcceleration = %s;\n", YESNO[g_SimulationMode->GetIgnoreAcceleration()]);
934 fprintf(df, "}\n\n");
935
936 fprintf(df, "Wind{\n");
937 fprintf(df, "\tDir1 = "); V3Save(df, m_WindDir1, ";\n");
938 fprintf(df, "\tDir2 = "); V3Save(df, m_WindDir2, ";\n");
939 fprintf(df, "\tCount = %d;\n", m_WindCount);
940 fprintf(df, "\tTime = %d;\n", m_WindTime);
941 fprintf(df, "}\n\n");
942
943 fprintf(df, "WarpList{\n");
944 CRailWay *warp = m_WarpList;
945 while(warp){
946 warp->SaveWarp(df);
947 warp = warp->Next();
948 }
949 fprintf(df, "}\n\n");
950
951 fprintf(df, "RailBlockList{\n");
952 map<std::string, CTrainGroup *>::iterator railblock;
953 for(railblock = g_RailBlockMap.begin(); railblock!=g_RailBlockMap.end(); ++railblock){
954 if(railblock->second) fprintf(df, "\tRailBlock = \"%s\", %p;\n",
955 ExpandDoubleQuote(railblock->first).c_str(), railblock->second);
956 }
957 fprintf(df, "}\n\n");
958
959 fprintf(df, "TrainGroupList{\n");
960 CTrainGroup *group = m_GroupList;
961 while(group){
962 group->Save(df);
963 group = group->Next();
964 }
965 fprintf(df, "}\n\n");
966
967 fprintf(df, "SceneList{\n");
968 fprintf(df, "\tCurrentScene = %p;\n", g_Scene);
969 CScene *scene = m_SceneList;
970 while(scene){
971 scene->Save(df);
972 scene = scene->Next();
973 }
974 fprintf(df, "}\n\n");
975
976 fprintf(df, "Window{\n");
977 g_ConfigMode->GetRootWindow()->Save(df, "\t");
978 fprintf(df, "}\n\n");
979
980 fclose(df);
981 return 0;
982 }
983
984 ////////////////////////////////////////////////////////////////////////////////
985 ////////////////////////////////////////////////////////////////////////////////
986
987 /*
988 * 閏年かどうか調べる
989 */
990 bool IsLeapYear(
991 int year // 年 (A.D.1 = 0)
992 ){
993 year++;
994 if(year%4) return false;
995 if(year%100) return true;
996 if(year%400) return false;
997 return true;
998 }
999
1000 /*
1001 * 月当たりの日数を調べる
1002 */
1003 int GetDaysPerMonth(
1004 int year, // 年
1005 int month // 月
1006 ){
1007 static int sdpm[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
1008 int ret = sdpm[month];
1009 if(month==1 && IsLeapYear(year)) ret++;
1010 return ret;
1011 }
1012
1013 /*
1014 * 変換後アドレス取得
1015 */
1016 void *ReplaceAdr(
1017 void *oldadr // 旧アドレス
1018 ){
1019 if(oldadr){
1020 if(!g_AddressMap.count(oldadr)){
1021 // Dialog("Address not found: %p", oldadr);
1022 return NULL;
1023 }
1024 return g_AddressMap[oldadr];
1025 }else{
1026 return NULL;
1027 }
1028 }
1029
1030 /*
1031 * マップにアドレスを登録 (ネットワーク同期用)
1032 */
1033 void *RegisterNewMapAddress(void *new_adr){
1034 extern int g_NetworkDummyMapAddress;
1035 while(g_AddressMap.count((void *)g_NetworkDummyMapAddress)) g_NetworkDummyMapAddress++;
1036 g_AddressMap[(void *)g_NetworkDummyMapAddress] = new_adr;
1037 return (void *)g_NetworkDummyMapAddress;
1038 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26