Commit runtime loader and atlas updates
This commit is contained in:
parent
1040a131da
commit
b173c50c1a
19 changed files with 8425 additions and 698 deletions
BIN
RT2.LOG
Normal file
BIN
RT2.LOG
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
artifacts/tmp/BuildingDetail.win.bin
Normal file
BIN
artifacts/tmp/BuildingDetail.win.bin
Normal file
Binary file not shown.
BIN
artifacts/tmp/CompanyDetail.win.bin
Normal file
BIN
artifacts/tmp/CompanyDetail.win.bin
Normal file
Binary file not shown.
2
artifacts/tmp/analysis/analysis-context-functions.csv
Normal file
2
artifacts/tmp/analysis/analysis-context-functions.csv
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
query_address,function_address,name,size,calling_convention,signature,caller_count,callers,callee_count,callees,data_ref_count,data_refs,entry_excerpt
|
||||
0x004ba3d0,0x004ba3d0,fcn.004ba3d0,2380,cdecl,fcn.004ba3d0();,5,0x004baedd@0x004bad20:fcn.004bad20; 0x004bb8dc@0x004baef0:fcn.004baef0; 0x004bbc89; 0x004bbd6a; 0x004bc02b,67,0x004ba53d->0x00517d40:fcn.00517d40; 0x004ba556->0x00518140:fcn.00518140; 0x004ba5b6->0x00518de0:fcn.00518de0; 0x004ba606->0x005193f0:fcn.005193f0; 0x004ba489->0x0051d820:fcn.0051d820; 0x004ba5e6->0x0051d820:fcn.0051d820; 0x004ba611->0x0051d820:fcn.0051d820; 0x004ba78a->0x0051d820:fcn.0051d820; 0x004ba830->0x0051d820:fcn.0051d820; 0x004ba8cb->0x0051d820:fcn.0051d820; 0x004ba997->0x0051d820:fcn.0051d820; 0x004bac73->0x0051d820:fcn.0051d820; 0x004ba493->0x0053b070:fcn.0053b070; 0x004ba61b->0x0053b070:fcn.0053b070; 0x004ba6d9->0x0053b070:fcn.0053b070; 0x004ba794->0x0053b070:fcn.0053b070; 0x004ba83a->0x0053b070:fcn.0053b070; 0x004ba8d5->0x0053b070:fcn.0053b070; 0x004ba9a1->0x0053b070:fcn.0053b070; 0x004baa6d->0x0053b070:fcn.0053b070; 0x004bab24->0x0053b070:fcn.0053b070; 0x004bac8f->0x0053b070:fcn.0053b070; 0x004ba5cd->0x0053c930:fcn.0053c930; 0x004ba40b->0x0053f830:fcn.0053f830; 0x004ba4c9->0x0053f830:fcn.0053f830; 0x004ba661->0x0053f830:fcn.0053f830; 0x004ba9f4->0x0053f830:fcn.0053f830; 0x004baaab->0x0053f830:fcn.0053f830; 0x004bab53->0x0053f830:fcn.0053f830; 0x004ba4b4->0x0053f9c0:fcn.0053f9c0; 0x004ba63c->0x0053f9c0:fcn.0053f9c0; 0x004ba6fd->0x0053f9c0:fcn.0053f9c0; 0x004ba7b6->0x0053f9c0:fcn.0053f9c0; 0x004ba85a->0x0053f9c0:fcn.0053f9c0; 0x004ba8f5->0x0053f9c0:fcn.0053f9c0; 0x004ba9c1->0x0053f9c0:fcn.0053f9c0; 0x004baa90->0x0053f9c0:fcn.0053f9c0; 0x004bab47->0x0053f9c0:fcn.0053f9c0; 0x004bacb2->0x0053f9c0:fcn.0053f9c0; 0x004ba421->0x0053fe00:fcn.0053fe00; 0x004ba4dc->0x0053fe00:fcn.0053fe00; 0x004ba674->0x0053fe00:fcn.0053fe00; 0x004baa0a->0x0053fe00:fcn.0053fe00; 0x004baac1->0x0053fe00:fcn.0053fe00; 0x004bab69->0x0053fe00:fcn.0053fe00; 0x004bacda->0x00540120:fcn.00540120; 0x004bacf4->0x00540120:fcn.00540120; 0x004bad0f->0x00540120:fcn.00540120; 0x004ba4a6->0x0055a040:fcn.0055a040; 0x004ba62e->0x0055a040:fcn.0055a040; 0x004ba7a9->0x0055a040:fcn.0055a040; 0x004ba84d->0x0055a040:fcn.0055a040; 0x004ba8e8->0x0055a040:fcn.0055a040; 0x004ba9b4->0x0055a040:fcn.0055a040; 0x004baca5->0x0055ab50:fcn.0055ab50; 0x004ba6ef->0x00563210:fcn.00563210; 0x004baa83->0x00563210:fcn.00563210; 0x004bab3a->0x00563210:fcn.00563210; 0x004ba4be->0x005a1145:fcn.005a1145; 0x004ba646->0x005a1145:fcn.005a1145; 0x004ba650->0x005a1145:fcn.005a1145; 0x004ba7c0->0x005a1145:fcn.005a1145; 0x004ba864->0x005a1145:fcn.005a1145; 0x004ba8ff->0x005a1145:fcn.005a1145; 0x004ba9cb->0x005a1145:fcn.005a1145; 0x004bacbf->0x005a1145:fcn.005a1145; 0x004ba56c->0x005a19c4:fcn.005a19c4,28,"0x004bacc9->0x004ba270; 0x004ba5e1->0x005d0194; 0x004ba952->0x005d0608; 0x004ba889->0x005d0614:""Caboose.imb""; 0x004ba59a->0x005d0620:""PassMail.imb""; 0x004ba593->0x005d0630:""AnyFreight.imb""; 0x004ba587->0x005d0640:""AnyCargo.imb""; 0x004ba566->0x005d0650:""%s.imb""; 0x004ba44e->0x005d0658:""Cargo.imb""; 0x004ba74e->0x005d0658:""Cargo.imb""; 0x004ba7f4->0x005d0658:""Cargo.imb""; 0x004bac25->0x005d0658:""Cargo.imb""; 0x004ba536->0x0062ba8c; 0x004ba54f->0x0062ba8c; 0x004ba3e2->0x006cfe04; 0x004ba4fa->0x006cfe04; 0x004ba546->0x006cfe04; 0x004ba576->0x006cfe04; 0x004ba711->0x006cfe04; 0x004ba7c5->0x006cfe04; 0x004ba869->0x006cfe04; 0x004ba904->0x006cfe04; 0x004ba9d0->0x006cfe04; 0x004baa95->0x006cfe04; 0x004bab81->0x006cfe04; 0x004bacdf->0x006cfe04; 0x004bacf9->0x006cfe04; 0x004ba5bb->0x006d4020"," 4ba3b0: jl 0x4ba355 <.text+0xb9355> | 4ba3b2: decl %ebx | 4ba3b3: addb %ah, 0x4ba3(%ebp) | 4ba3b9: addl %eax, (%ebx) | 4ba3bb: addl (%ebx), %eax | 4ba3bd: addl (%ebx), %eax | 4ba3bf: addb (%ebx), %al | 4ba3c1: addl (%eax), %eax | 4ba3c3: addl %eax, (%eax) | 4ba3c5: addl %edx, -0x6f6f6f70(%eax) | 4ba3cb: nop | 4ba3cc: nop | 4ba3cd: nop | 4ba3ce: nop | 4ba3cf: nop | 4ba3d0: pushl %ebp | 4ba3d1: movl %esp, %ebp | 4ba3d3: andl $-0x8, %esp | 4ba3d6: subl $0x318, %esp # imm = 0x318 | 4ba3dc: pushl %ebx | 4ba3dd: pushl %ebp | 4ba3de: pushl %esi | 4ba3df: pushl %edi | 4ba3e0: movl %ecx, %ebp | 4ba3e2: movl 0x6cfe04, %eax | 4ba3e7: cmpb $0x0, (%eax) | 4ba3ea: jbe 0x4ba72f <.text+0xb972f>"
|
||||
|
292
artifacts/tmp/analysis/analysis-context.md
Normal file
292
artifacts/tmp/analysis/analysis-context.md
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
# Analysis Context
|
||||
|
||||
- Target binary: `/home/jan/projects/rrt/rt3_wineprefix/drive_c/rt3/RT3.exe`
|
||||
- Function names prefer the curated ledger when a committed mapping exists.
|
||||
|
||||
## Function Targets
|
||||
|
||||
### `0x004ba3d0` -> `0x004ba3d0` `fcn.004ba3d0`
|
||||
|
||||
- Size: `2380`
|
||||
- Calling convention: `cdecl`
|
||||
- Signature: `fcn.004ba3d0();`
|
||||
|
||||
Entry excerpt:
|
||||
|
||||
```asm
|
||||
4ba3b0: jl 0x4ba355 <.text+0xb9355>
|
||||
4ba3b2: decl %ebx
|
||||
4ba3b3: addb %ah, 0x4ba3(%ebp)
|
||||
4ba3b9: addl %eax, (%ebx)
|
||||
4ba3bb: addl (%ebx), %eax
|
||||
4ba3bd: addl (%ebx), %eax
|
||||
4ba3bf: addb (%ebx), %al
|
||||
4ba3c1: addl (%eax), %eax
|
||||
4ba3c3: addl %eax, (%eax)
|
||||
4ba3c5: addl %edx, -0x6f6f6f70(%eax)
|
||||
4ba3cb: nop
|
||||
4ba3cc: nop
|
||||
4ba3cd: nop
|
||||
4ba3ce: nop
|
||||
4ba3cf: nop
|
||||
4ba3d0: pushl %ebp
|
||||
4ba3d1: movl %esp, %ebp
|
||||
4ba3d3: andl $-0x8, %esp
|
||||
4ba3d6: subl $0x318, %esp # imm = 0x318
|
||||
4ba3dc: pushl %ebx
|
||||
4ba3dd: pushl %ebp
|
||||
4ba3de: pushl %esi
|
||||
4ba3df: pushl %edi
|
||||
4ba3e0: movl %ecx, %ebp
|
||||
4ba3e2: movl 0x6cfe04, %eax
|
||||
4ba3e7: cmpb $0x0, (%eax)
|
||||
4ba3ea: jbe 0x4ba72f <.text+0xb972f>
|
||||
```
|
||||
|
||||
Callers:
|
||||
- `0x004baedd` in `0x004bad20` `fcn.004bad20`
|
||||
- `0x004bb8dc` in `0x004baef0` `fcn.004baef0`
|
||||
- `0x004bbc89`
|
||||
- `0x004bbd6a`
|
||||
- `0x004bc02b`
|
||||
|
||||
Caller xref excerpts:
|
||||
|
||||
#### `0x004baedd`
|
||||
|
||||
```asm
|
||||
4baebd: addb %cl, 0x6cfe0415(%ebx)
|
||||
4baec3: addb %cl, (%edi)
|
||||
4baec5: movb $0x42, %dh
|
||||
4baec7: andl %ebp, (%edx)
|
||||
4baeca: pushl $0x0
|
||||
4baecc: pushl %eax
|
||||
4baecd: pushl $0x7d0e # imm = 0x7D0E
|
||||
4baed2: pushl $0x66
|
||||
4baed4: movl %esi, %ecx
|
||||
4baed6: calll 0x540120 <.text+0x13f120>
|
||||
4baedb: movl %esi, %ecx
|
||||
4baedd: calll 0x4ba3d0 <.text+0xb93d0>
|
||||
4baee2: popl %edi
|
||||
4baee3: popl %esi
|
||||
4baee4: popl %ebx
|
||||
4baee5: retl $0x4
|
||||
4baee8: nop
|
||||
4baee9: nop
|
||||
4baeea: nop
|
||||
4baeeb: nop
|
||||
4baeec: nop
|
||||
4baeed: nop
|
||||
4baeee: nop
|
||||
4baeef: nop
|
||||
4baef0: pushl %ebp
|
||||
4baef1: movl %esp, %ebp
|
||||
4baef3: andl $-0x8, %esp
|
||||
4baef6: subl $0x270, %esp # imm = 0x270
|
||||
4baefc: movl 0x6cfe04, %eax
|
||||
```
|
||||
|
||||
#### `0x004bb8dc`
|
||||
|
||||
```asm
|
||||
4bb8bc: incl %ebx
|
||||
4bb8bd: movl %ebx, 0x2c(%esp)
|
||||
4bb8c1: incl %ebp
|
||||
4bb8c2: movl 0x62ba8c, %ecx
|
||||
4bb8c8: incl %edi
|
||||
4bb8c9: movl %edi, 0x18(%esp)
|
||||
4bb8cd: calll 0x517cf0 <.text+0x116cf0>
|
||||
4bb8d2: cmpl %eax, %edi
|
||||
4bb8d4: jl 0x4bb490 <.text+0xba490>
|
||||
4bb8da: movl %esi, %ecx
|
||||
4bb8dc: calll 0x4ba3d0 <.text+0xb93d0>
|
||||
4bb8e1: movl %esi, %ecx
|
||||
4bb8e3: calll 0x4b9a20 <.text+0xb8a20>
|
||||
4bb8e8: pushl $0x7d0b # imm = 0x7D0B
|
||||
4bb8ed: movl %esi, %ecx
|
||||
4bb8ef: calll 0x53f830 <.text+0x13e830>
|
||||
4bb8f4: movl 0x6cec20, %ecx
|
||||
4bb8fa: movl %eax, %edi
|
||||
```
|
||||
|
||||
#### `0x004bbc89`
|
||||
|
||||
```asm
|
||||
4bbc69: pushl $0x7d96 # imm = 0x7D96
|
||||
4bbc6e: movl %ebp, %ecx
|
||||
4bbc70: calll 0x53fe00 <.text+0x13ee00>
|
||||
4bbc75: pushl %edi
|
||||
4bbc76: pushl $0x8051 # imm = 0x8051
|
||||
4bbc7b: pushl $0x8020 # imm = 0x8020
|
||||
4bbc80: movl %ebp, %ecx
|
||||
4bbc82: calll 0x53fe00 <.text+0x13ee00>
|
||||
4bbc87: movl %ebp, %ecx
|
||||
4bbc89: calll 0x4ba3d0 <.text+0xb93d0>
|
||||
4bbc8e: movl 0x6cfe08, %edx
|
||||
4bbc94: movb 0xc(%edx), %al
|
||||
4bbc97: testb %al, %al
|
||||
4bbc99: je 0x4bbca2 <.text+0xbaca2>
|
||||
4bbc9b: movl %ebp, %ecx
|
||||
4bbc9d: calll 0x4b9ec0 <.text+0xb8ec0>
|
||||
4bbca2: popl %edi
|
||||
4bbca3: popl %ebx
|
||||
4bbca4: popl %esi
|
||||
4bbca5: xorl %eax, %eax
|
||||
4bbca7: popl %ebp
|
||||
4bbca8: retl $0x4
|
||||
```
|
||||
|
||||
#### `0x004bbd6a`
|
||||
|
||||
```asm
|
||||
4bbd4a: movzbl (%eax), %ecx
|
||||
4bbd4d: movl %edx, -0x3(%eax,%ecx,4)
|
||||
4bbd51: jmp 0x4bbd68 <.text+0xbad68>
|
||||
4bbd53: leal -0x3(%eax), %ecx
|
||||
4bbd56: calll 0x4b99c0 <.text+0xb89c0>
|
||||
4bbd5b: movl 0x6cfe04, %ecx
|
||||
4bbd61: movzbl (%ecx), %edx
|
||||
4bbd64: movl %eax, -0x3(%ecx,%edx,4)
|
||||
4bbd68: movl %ebp, %ecx
|
||||
4bbd6a: calll 0x4ba3d0 <.text+0xb93d0>
|
||||
4bbd6f: movl 0x6cfe08, %eax
|
||||
4bbd74: movb 0xc(%eax), %cl
|
||||
4bbd77: testb %cl, %cl
|
||||
4bbd79: je 0x4bbca2 <.text+0xbaca2>
|
||||
4bbd7f: movl %ebp, %ecx
|
||||
4bbd81: calll 0x4b9ec0 <.text+0xb8ec0>
|
||||
4bbd86: popl %edi
|
||||
4bbd87: popl %ebx
|
||||
4bbd88: popl %esi
|
||||
4bbd89: xorl %eax, %eax
|
||||
```
|
||||
|
||||
#### `0x004bc02b`
|
||||
|
||||
```asm
|
||||
4bc00b: addb %dl, 0x68(%edi)
|
||||
4bc00e: pushl %ecx
|
||||
4bc00f: addb $0x0, (%eax)
|
||||
4bc012: pushl $0x8020 # imm = 0x8020
|
||||
4bc017: movl %ebp, %ecx
|
||||
4bc019: calll 0x53fe00 <.text+0x13ee00>
|
||||
4bc01e: movl 0x6cfe04, %eax
|
||||
4bc023: testb $0x40, 0x28(%eax)
|
||||
4bc027: movl %ebp, %ecx
|
||||
4bc029: je 0x4bc039 <.text+0xbb039>
|
||||
4bc02b: calll 0x4ba3d0 <.text+0xb93d0>
|
||||
4bc030: popl %edi
|
||||
4bc031: popl %ebx
|
||||
4bc032: popl %esi
|
||||
4bc033: xorl %eax, %eax
|
||||
4bc035: popl %ebp
|
||||
4bc036: retl $0x4
|
||||
4bc039: calll 0x4b9a20 <.text+0xb8a20>
|
||||
4bc03e: popl %edi
|
||||
4bc03f: popl %ebx
|
||||
4bc040: popl %esi
|
||||
4bc041: xorl %eax, %eax
|
||||
4bc043: popl %ebp
|
||||
4bc044: retl $0x4
|
||||
4bc047: cmpl %edi, 0x6cfe10
|
||||
```
|
||||
|
||||
Direct internal callees:
|
||||
- `0x004ba53d` -> `0x00517d40` `fcn.00517d40`
|
||||
- `0x004ba556` -> `0x00518140` `fcn.00518140`
|
||||
- `0x004ba5b6` -> `0x00518de0` `fcn.00518de0`
|
||||
- `0x004ba606` -> `0x005193f0` `fcn.005193f0`
|
||||
- `0x004ba489` -> `0x0051d820` `fcn.0051d820`
|
||||
- `0x004ba5e6` -> `0x0051d820` `fcn.0051d820`
|
||||
- `0x004ba611` -> `0x0051d820` `fcn.0051d820`
|
||||
- `0x004ba78a` -> `0x0051d820` `fcn.0051d820`
|
||||
- `0x004ba830` -> `0x0051d820` `fcn.0051d820`
|
||||
- `0x004ba8cb` -> `0x0051d820` `fcn.0051d820`
|
||||
- `0x004ba997` -> `0x0051d820` `fcn.0051d820`
|
||||
- `0x004bac73` -> `0x0051d820` `fcn.0051d820`
|
||||
- `0x004ba493` -> `0x0053b070` `fcn.0053b070`
|
||||
- `0x004ba61b` -> `0x0053b070` `fcn.0053b070`
|
||||
- `0x004ba6d9` -> `0x0053b070` `fcn.0053b070`
|
||||
- `0x004ba794` -> `0x0053b070` `fcn.0053b070`
|
||||
- `0x004ba83a` -> `0x0053b070` `fcn.0053b070`
|
||||
- `0x004ba8d5` -> `0x0053b070` `fcn.0053b070`
|
||||
- `0x004ba9a1` -> `0x0053b070` `fcn.0053b070`
|
||||
- `0x004baa6d` -> `0x0053b070` `fcn.0053b070`
|
||||
- `0x004bab24` -> `0x0053b070` `fcn.0053b070`
|
||||
- `0x004bac8f` -> `0x0053b070` `fcn.0053b070`
|
||||
- `0x004ba5cd` -> `0x0053c930` `fcn.0053c930`
|
||||
- `0x004ba40b` -> `0x0053f830` `fcn.0053f830`
|
||||
- `0x004ba4c9` -> `0x0053f830` `fcn.0053f830`
|
||||
- `0x004ba661` -> `0x0053f830` `fcn.0053f830`
|
||||
- `0x004ba9f4` -> `0x0053f830` `fcn.0053f830`
|
||||
- `0x004baaab` -> `0x0053f830` `fcn.0053f830`
|
||||
- `0x004bab53` -> `0x0053f830` `fcn.0053f830`
|
||||
- `0x004ba4b4` -> `0x0053f9c0` `fcn.0053f9c0`
|
||||
- `0x004ba63c` -> `0x0053f9c0` `fcn.0053f9c0`
|
||||
- `0x004ba6fd` -> `0x0053f9c0` `fcn.0053f9c0`
|
||||
- `0x004ba7b6` -> `0x0053f9c0` `fcn.0053f9c0`
|
||||
- `0x004ba85a` -> `0x0053f9c0` `fcn.0053f9c0`
|
||||
- `0x004ba8f5` -> `0x0053f9c0` `fcn.0053f9c0`
|
||||
- `0x004ba9c1` -> `0x0053f9c0` `fcn.0053f9c0`
|
||||
- `0x004baa90` -> `0x0053f9c0` `fcn.0053f9c0`
|
||||
- `0x004bab47` -> `0x0053f9c0` `fcn.0053f9c0`
|
||||
- `0x004bacb2` -> `0x0053f9c0` `fcn.0053f9c0`
|
||||
- `0x004ba421` -> `0x0053fe00` `fcn.0053fe00`
|
||||
- `0x004ba4dc` -> `0x0053fe00` `fcn.0053fe00`
|
||||
- `0x004ba674` -> `0x0053fe00` `fcn.0053fe00`
|
||||
- `0x004baa0a` -> `0x0053fe00` `fcn.0053fe00`
|
||||
- `0x004baac1` -> `0x0053fe00` `fcn.0053fe00`
|
||||
- `0x004bab69` -> `0x0053fe00` `fcn.0053fe00`
|
||||
- `0x004bacda` -> `0x00540120` `fcn.00540120`
|
||||
- `0x004bacf4` -> `0x00540120` `fcn.00540120`
|
||||
- `0x004bad0f` -> `0x00540120` `fcn.00540120`
|
||||
- `0x004ba4a6` -> `0x0055a040` `fcn.0055a040`
|
||||
- `0x004ba62e` -> `0x0055a040` `fcn.0055a040`
|
||||
- `0x004ba7a9` -> `0x0055a040` `fcn.0055a040`
|
||||
- `0x004ba84d` -> `0x0055a040` `fcn.0055a040`
|
||||
- `0x004ba8e8` -> `0x0055a040` `fcn.0055a040`
|
||||
- `0x004ba9b4` -> `0x0055a040` `fcn.0055a040`
|
||||
- `0x004baca5` -> `0x0055ab50` `fcn.0055ab50`
|
||||
- `0x004ba6ef` -> `0x00563210` `fcn.00563210`
|
||||
- `0x004baa83` -> `0x00563210` `fcn.00563210`
|
||||
- `0x004bab3a` -> `0x00563210` `fcn.00563210`
|
||||
- `0x004ba4be` -> `0x005a1145` `fcn.005a1145`
|
||||
- `0x004ba646` -> `0x005a1145` `fcn.005a1145`
|
||||
- `0x004ba650` -> `0x005a1145` `fcn.005a1145`
|
||||
- `0x004ba7c0` -> `0x005a1145` `fcn.005a1145`
|
||||
- `0x004ba864` -> `0x005a1145` `fcn.005a1145`
|
||||
- `0x004ba8ff` -> `0x005a1145` `fcn.005a1145`
|
||||
- `0x004ba9cb` -> `0x005a1145` `fcn.005a1145`
|
||||
- `0x004bacbf` -> `0x005a1145` `fcn.005a1145`
|
||||
- `0x004ba56c` -> `0x005a19c4` `fcn.005a19c4`
|
||||
|
||||
Data refs:
|
||||
- `0x004bacc9` -> `0x004ba270`
|
||||
- `0x004ba5e1` -> `0x005d0194`
|
||||
- `0x004ba952` -> `0x005d0608`
|
||||
- `0x004ba889` -> `0x005d0614` "Caboose.imb"
|
||||
- `0x004ba59a` -> `0x005d0620` "PassMail.imb"
|
||||
- `0x004ba593` -> `0x005d0630` "AnyFreight.imb"
|
||||
- `0x004ba587` -> `0x005d0640` "AnyCargo.imb"
|
||||
- `0x004ba566` -> `0x005d0650` "%s.imb"
|
||||
- `0x004ba44e` -> `0x005d0658` "Cargo.imb"
|
||||
- `0x004ba74e` -> `0x005d0658` "Cargo.imb"
|
||||
- `0x004ba7f4` -> `0x005d0658` "Cargo.imb"
|
||||
- `0x004bac25` -> `0x005d0658` "Cargo.imb"
|
||||
- `0x004ba536` -> `0x0062ba8c`
|
||||
- `0x004ba54f` -> `0x0062ba8c`
|
||||
- `0x004ba3e2` -> `0x006cfe04`
|
||||
- `0x004ba4fa` -> `0x006cfe04`
|
||||
- `0x004ba546` -> `0x006cfe04`
|
||||
- `0x004ba576` -> `0x006cfe04`
|
||||
- `0x004ba711` -> `0x006cfe04`
|
||||
- `0x004ba7c5` -> `0x006cfe04`
|
||||
- `0x004ba869` -> `0x006cfe04`
|
||||
- `0x004ba904` -> `0x006cfe04`
|
||||
- `0x004ba9d0` -> `0x006cfe04`
|
||||
- `0x004baa95` -> `0x006cfe04`
|
||||
- `0x004bab81` -> `0x006cfe04`
|
||||
- `0x004bacdf` -> `0x006cfe04`
|
||||
- `0x004bacf9` -> `0x006cfe04`
|
||||
- `0x004ba5bb` -> `0x006d4020`
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -81,8 +81,9 @@ mod tests {
|
|||
use super::*;
|
||||
use crate::FixtureStateOrigin;
|
||||
use rrt_runtime::{
|
||||
CalendarPoint, RuntimeServiceState, RuntimeSnapshotDocument, RuntimeSnapshotSource,
|
||||
RuntimeState, SNAPSHOT_FORMAT_VERSION, save_runtime_snapshot_document,
|
||||
CalendarPoint, RuntimeSaveProfileState, RuntimeServiceState, RuntimeSnapshotDocument,
|
||||
RuntimeSnapshotSource, RuntimeState, RuntimeWorldRestoreState, SNAPSHOT_FORMAT_VERSION,
|
||||
save_runtime_snapshot_document,
|
||||
};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
|
|
@ -111,8 +112,13 @@ mod tests {
|
|||
tick_slot: 5,
|
||||
},
|
||||
world_flags: BTreeMap::new(),
|
||||
save_profile: RuntimeSaveProfileState::default(),
|
||||
world_restore: RuntimeWorldRestoreState::default(),
|
||||
metadata: BTreeMap::new(),
|
||||
companies: Vec::new(),
|
||||
event_runtime_records: Vec::new(),
|
||||
candidate_availability: BTreeMap::new(),
|
||||
special_conditions: BTreeMap::new(),
|
||||
service_state: RuntimeServiceState::default(),
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,12 +16,77 @@ pub struct ExpectedRuntimeSummary {
|
|||
#[serde(default)]
|
||||
pub calendar: Option<rrt_runtime::CalendarPoint>,
|
||||
#[serde(default)]
|
||||
pub calendar_projection_source: Option<String>,
|
||||
#[serde(default)]
|
||||
pub calendar_projection_is_placeholder: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_flag_count: Option<usize>,
|
||||
#[serde(default)]
|
||||
pub world_restore_selected_year_profile_lane: Option<u8>,
|
||||
#[serde(default)]
|
||||
pub world_restore_campaign_scenario_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_sandbox_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_seed_tuple_written_from_raw_lane: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_absolute_counter_requires_shell_context: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_absolute_counter_reconstructible_from_save: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_disable_cargo_economy_special_condition_slot: Option<u8>,
|
||||
#[serde(default)]
|
||||
pub world_restore_disable_cargo_economy_special_condition_reconstructible_from_save:
|
||||
Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_disable_cargo_economy_special_condition_write_side_grounded: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_disable_cargo_economy_special_condition_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_use_bio_accelerator_cars_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_use_wartime_cargos_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_disable_train_crashes_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_disable_train_crashes_and_breakdowns_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_ai_ignore_territories_at_startup_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub world_restore_absolute_counter_restore_kind: Option<String>,
|
||||
#[serde(default)]
|
||||
pub world_restore_absolute_counter_adjustment_context: Option<String>,
|
||||
#[serde(default)]
|
||||
pub metadata_count: Option<usize>,
|
||||
#[serde(default)]
|
||||
pub company_count: Option<usize>,
|
||||
#[serde(default)]
|
||||
pub event_runtime_record_count: Option<usize>,
|
||||
#[serde(default)]
|
||||
pub candidate_availability_count: Option<usize>,
|
||||
#[serde(default)]
|
||||
pub zero_candidate_availability_count: Option<usize>,
|
||||
#[serde(default)]
|
||||
pub special_condition_count: Option<usize>,
|
||||
#[serde(default)]
|
||||
pub enabled_special_condition_count: Option<usize>,
|
||||
#[serde(default)]
|
||||
pub save_profile_kind: Option<String>,
|
||||
#[serde(default)]
|
||||
pub save_profile_family: Option<String>,
|
||||
#[serde(default)]
|
||||
pub save_profile_map_path: Option<String>,
|
||||
#[serde(default)]
|
||||
pub save_profile_display_name: Option<String>,
|
||||
#[serde(default)]
|
||||
pub save_profile_selected_year_profile_lane: Option<u8>,
|
||||
#[serde(default)]
|
||||
pub save_profile_sandbox_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub save_profile_campaign_scenario_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub save_profile_staged_profile_copy_on_restore: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub total_event_record_service_count: Option<u64>,
|
||||
#[serde(default)]
|
||||
pub periodic_boundary_call_count: Option<u64>,
|
||||
|
|
@ -45,6 +110,22 @@ impl ExpectedRuntimeSummary {
|
|||
));
|
||||
}
|
||||
}
|
||||
if let Some(source) = &self.calendar_projection_source {
|
||||
if actual.calendar_projection_source.as_ref() != Some(source) {
|
||||
mismatches.push(format!(
|
||||
"calendar_projection_source mismatch: expected {source:?}, got {:?}",
|
||||
actual.calendar_projection_source
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(is_placeholder) = self.calendar_projection_is_placeholder {
|
||||
if actual.calendar_projection_is_placeholder != is_placeholder {
|
||||
mismatches.push(format!(
|
||||
"calendar_projection_is_placeholder mismatch: expected {is_placeholder}, got {}",
|
||||
actual.calendar_projection_is_placeholder
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(count) = self.world_flag_count {
|
||||
if actual.world_flag_count != count {
|
||||
mismatches.push(format!(
|
||||
|
|
@ -53,6 +134,164 @@ impl ExpectedRuntimeSummary {
|
|||
));
|
||||
}
|
||||
}
|
||||
if let Some(lane) = self.world_restore_selected_year_profile_lane {
|
||||
if actual.world_restore_selected_year_profile_lane != Some(lane) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_selected_year_profile_lane mismatch: expected {lane}, got {:?}",
|
||||
actual.world_restore_selected_year_profile_lane
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.world_restore_campaign_scenario_enabled {
|
||||
if actual.world_restore_campaign_scenario_enabled != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_campaign_scenario_enabled mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_campaign_scenario_enabled
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.world_restore_sandbox_enabled {
|
||||
if actual.world_restore_sandbox_enabled != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_sandbox_enabled mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_sandbox_enabled
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.world_restore_seed_tuple_written_from_raw_lane {
|
||||
if actual.world_restore_seed_tuple_written_from_raw_lane != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_seed_tuple_written_from_raw_lane mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_seed_tuple_written_from_raw_lane
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.world_restore_absolute_counter_requires_shell_context {
|
||||
if actual.world_restore_absolute_counter_requires_shell_context != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_absolute_counter_requires_shell_context mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_absolute_counter_requires_shell_context
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.world_restore_absolute_counter_reconstructible_from_save {
|
||||
if actual.world_restore_absolute_counter_reconstructible_from_save != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_absolute_counter_reconstructible_from_save mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_absolute_counter_reconstructible_from_save
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(slot) = self.world_restore_disable_cargo_economy_special_condition_slot {
|
||||
if actual.world_restore_disable_cargo_economy_special_condition_slot != Some(slot) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_disable_cargo_economy_special_condition_slot mismatch: expected {slot}, got {:?}",
|
||||
actual.world_restore_disable_cargo_economy_special_condition_slot
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) =
|
||||
self.world_restore_disable_cargo_economy_special_condition_reconstructible_from_save
|
||||
{
|
||||
if actual
|
||||
.world_restore_disable_cargo_economy_special_condition_reconstructible_from_save
|
||||
!= Some(enabled)
|
||||
{
|
||||
mismatches.push(format!(
|
||||
"world_restore_disable_cargo_economy_special_condition_reconstructible_from_save mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_disable_cargo_economy_special_condition_reconstructible_from_save
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) =
|
||||
self.world_restore_disable_cargo_economy_special_condition_write_side_grounded
|
||||
{
|
||||
if actual.world_restore_disable_cargo_economy_special_condition_write_side_grounded
|
||||
!= Some(enabled)
|
||||
{
|
||||
mismatches.push(format!(
|
||||
"world_restore_disable_cargo_economy_special_condition_write_side_grounded mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_disable_cargo_economy_special_condition_write_side_grounded
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.world_restore_disable_cargo_economy_special_condition_enabled {
|
||||
if actual.world_restore_disable_cargo_economy_special_condition_enabled != Some(enabled)
|
||||
{
|
||||
mismatches.push(format!(
|
||||
"world_restore_disable_cargo_economy_special_condition_enabled mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_disable_cargo_economy_special_condition_enabled
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.world_restore_use_bio_accelerator_cars_enabled {
|
||||
if actual.world_restore_use_bio_accelerator_cars_enabled != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_use_bio_accelerator_cars_enabled mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_use_bio_accelerator_cars_enabled
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.world_restore_use_wartime_cargos_enabled {
|
||||
if actual.world_restore_use_wartime_cargos_enabled != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_use_wartime_cargos_enabled mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_use_wartime_cargos_enabled
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.world_restore_disable_train_crashes_enabled {
|
||||
if actual.world_restore_disable_train_crashes_enabled != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_disable_train_crashes_enabled mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_disable_train_crashes_enabled
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.world_restore_disable_train_crashes_and_breakdowns_enabled {
|
||||
if actual.world_restore_disable_train_crashes_and_breakdowns_enabled != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_disable_train_crashes_and_breakdowns_enabled mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_disable_train_crashes_and_breakdowns_enabled
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.world_restore_ai_ignore_territories_at_startup_enabled {
|
||||
if actual.world_restore_ai_ignore_territories_at_startup_enabled != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_ai_ignore_territories_at_startup_enabled mismatch: expected {enabled}, got {:?}",
|
||||
actual.world_restore_ai_ignore_territories_at_startup_enabled
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(kind) = &self.world_restore_absolute_counter_restore_kind {
|
||||
if actual.world_restore_absolute_counter_restore_kind.as_ref() != Some(kind) {
|
||||
mismatches.push(format!(
|
||||
"world_restore_absolute_counter_restore_kind mismatch: expected {kind:?}, got {:?}",
|
||||
actual.world_restore_absolute_counter_restore_kind
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(context) = &self.world_restore_absolute_counter_adjustment_context {
|
||||
if actual
|
||||
.world_restore_absolute_counter_adjustment_context
|
||||
.as_ref()
|
||||
!= Some(context)
|
||||
{
|
||||
mismatches.push(format!(
|
||||
"world_restore_absolute_counter_adjustment_context mismatch: expected {context:?}, got {:?}",
|
||||
actual.world_restore_absolute_counter_adjustment_context
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(count) = self.metadata_count {
|
||||
if actual.metadata_count != count {
|
||||
mismatches.push(format!(
|
||||
"metadata_count mismatch: expected {count}, got {}",
|
||||
actual.metadata_count
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(count) = self.company_count {
|
||||
if actual.company_count != count {
|
||||
mismatches.push(format!(
|
||||
|
|
@ -69,6 +308,102 @@ impl ExpectedRuntimeSummary {
|
|||
));
|
||||
}
|
||||
}
|
||||
if let Some(count) = self.candidate_availability_count {
|
||||
if actual.candidate_availability_count != count {
|
||||
mismatches.push(format!(
|
||||
"candidate_availability_count mismatch: expected {count}, got {}",
|
||||
actual.candidate_availability_count
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(count) = self.zero_candidate_availability_count {
|
||||
if actual.zero_candidate_availability_count != count {
|
||||
mismatches.push(format!(
|
||||
"zero_candidate_availability_count mismatch: expected {count}, got {}",
|
||||
actual.zero_candidate_availability_count
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(count) = self.special_condition_count {
|
||||
if actual.special_condition_count != count {
|
||||
mismatches.push(format!(
|
||||
"special_condition_count mismatch: expected {count}, got {}",
|
||||
actual.special_condition_count
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(count) = self.enabled_special_condition_count {
|
||||
if actual.enabled_special_condition_count != count {
|
||||
mismatches.push(format!(
|
||||
"enabled_special_condition_count mismatch: expected {count}, got {}",
|
||||
actual.enabled_special_condition_count
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(kind) = &self.save_profile_kind {
|
||||
if actual.save_profile_kind.as_ref() != Some(kind) {
|
||||
mismatches.push(format!(
|
||||
"save_profile_kind mismatch: expected {kind:?}, got {:?}",
|
||||
actual.save_profile_kind
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(family) = &self.save_profile_family {
|
||||
if actual.save_profile_family.as_ref() != Some(family) {
|
||||
mismatches.push(format!(
|
||||
"save_profile_family mismatch: expected {family:?}, got {:?}",
|
||||
actual.save_profile_family
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(map_path) = &self.save_profile_map_path {
|
||||
if actual.save_profile_map_path.as_ref() != Some(map_path) {
|
||||
mismatches.push(format!(
|
||||
"save_profile_map_path mismatch: expected {map_path:?}, got {:?}",
|
||||
actual.save_profile_map_path
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(display_name) = &self.save_profile_display_name {
|
||||
if actual.save_profile_display_name.as_ref() != Some(display_name) {
|
||||
mismatches.push(format!(
|
||||
"save_profile_display_name mismatch: expected {display_name:?}, got {:?}",
|
||||
actual.save_profile_display_name
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(lane) = self.save_profile_selected_year_profile_lane {
|
||||
if actual.save_profile_selected_year_profile_lane != Some(lane) {
|
||||
mismatches.push(format!(
|
||||
"save_profile_selected_year_profile_lane mismatch: expected {lane}, got {:?}",
|
||||
actual.save_profile_selected_year_profile_lane
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.save_profile_sandbox_enabled {
|
||||
if actual.save_profile_sandbox_enabled != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"save_profile_sandbox_enabled mismatch: expected {enabled}, got {:?}",
|
||||
actual.save_profile_sandbox_enabled
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.save_profile_campaign_scenario_enabled {
|
||||
if actual.save_profile_campaign_scenario_enabled != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"save_profile_campaign_scenario_enabled mismatch: expected {enabled}, got {:?}",
|
||||
actual.save_profile_campaign_scenario_enabled
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(enabled) = self.save_profile_staged_profile_copy_on_restore {
|
||||
if actual.save_profile_staged_profile_copy_on_restore != Some(enabled) {
|
||||
mismatches.push(format!(
|
||||
"save_profile_staged_profile_copy_on_restore mismatch: expected {enabled}, got {:?}",
|
||||
actual.save_profile_staged_profile_copy_on_restore
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(count) = self.total_event_record_service_count {
|
||||
if actual.total_event_record_service_count != count {
|
||||
mismatches.push(format!(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::path::Path;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::RuntimeState;
|
||||
use crate::{
|
||||
CalendarPoint, RuntimeSaveProfileState, RuntimeServiceState, RuntimeState,
|
||||
RuntimeWorldRestoreState, SmpLoadedSaveSlice,
|
||||
};
|
||||
|
||||
pub const STATE_DUMP_FORMAT_VERSION: u32 = 1;
|
||||
|
||||
|
|
@ -30,6 +34,282 @@ pub struct RuntimeStateImport {
|
|||
pub state: RuntimeState,
|
||||
}
|
||||
|
||||
pub fn project_save_slice_to_runtime_state_import(
|
||||
save_slice: &SmpLoadedSaveSlice,
|
||||
import_id: &str,
|
||||
description: Option<String>,
|
||||
) -> Result<RuntimeStateImport, String> {
|
||||
if import_id.trim().is_empty() {
|
||||
return Err("import_id must not be empty".to_string());
|
||||
}
|
||||
|
||||
let mut world_flags = BTreeMap::new();
|
||||
world_flags.insert(
|
||||
"save_slice.profile_present".to_string(),
|
||||
save_slice.profile.is_some(),
|
||||
);
|
||||
world_flags.insert(
|
||||
"save_slice.candidate_availability_present".to_string(),
|
||||
save_slice.candidate_availability_table.is_some(),
|
||||
);
|
||||
world_flags.insert(
|
||||
"save_slice.special_conditions_present".to_string(),
|
||||
save_slice.special_conditions_table.is_some(),
|
||||
);
|
||||
world_flags.insert(
|
||||
"save_slice.mechanism_confidence_grounded".to_string(),
|
||||
save_slice.mechanism_confidence == "grounded",
|
||||
);
|
||||
if let Some(profile) = &save_slice.profile {
|
||||
world_flags.insert(
|
||||
"save_slice.profile_byte_0x82_nonzero".to_string(),
|
||||
profile.profile_byte_0x82 != 0,
|
||||
);
|
||||
world_flags.insert(
|
||||
"save_slice.profile_byte_0x97_nonzero".to_string(),
|
||||
profile.profile_byte_0x97 != 0,
|
||||
);
|
||||
world_flags.insert(
|
||||
"save_slice.profile_byte_0xc5_nonzero".to_string(),
|
||||
profile.profile_byte_0xc5 != 0,
|
||||
);
|
||||
}
|
||||
|
||||
let mut metadata = BTreeMap::new();
|
||||
metadata.insert(
|
||||
"save_slice.import_projection".to_string(),
|
||||
"partial-runtime-restore-v1".to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.calendar_source".to_string(),
|
||||
"default-1830-placeholder".to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.selected_year_seed_tuple_source".to_string(),
|
||||
"raw-lane-via-0x51d3f0".to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.selected_year_absolute_counter_source".to_string(),
|
||||
"mode-adjusted-lane-via-0x51d390-0x409e80".to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.selected_year_absolute_counter_reconstructible_from_save".to_string(),
|
||||
"false".to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.disable_cargo_economy_special_condition_slot".to_string(),
|
||||
"30".to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.disable_cargo_economy_special_condition_reconstructible_from_save".to_string(),
|
||||
"true".to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.disable_cargo_economy_special_condition_write_side_grounded".to_string(),
|
||||
"true".to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.selected_year_absolute_counter_adjustment_context".to_string(),
|
||||
"editor-map-mode,shell-selected-year-adjust-policy-0x9d26-0x9d28,save-special-condition-disable-cargo-economy-slot-30"
|
||||
.to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.mechanism_family".to_string(),
|
||||
save_slice.mechanism_family.clone(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.mechanism_confidence".to_string(),
|
||||
save_slice.mechanism_confidence.clone(),
|
||||
);
|
||||
if let Some(family) = &save_slice.container_profile_family {
|
||||
metadata.insert(
|
||||
"save_slice.container_profile_family".to_string(),
|
||||
family.clone(),
|
||||
);
|
||||
}
|
||||
if let Some(family) = &save_slice.trailer_family {
|
||||
metadata.insert("save_slice.trailer_family".to_string(), family.clone());
|
||||
}
|
||||
if let Some(family) = &save_slice.bridge_family {
|
||||
metadata.insert("save_slice.bridge_family".to_string(), family.clone());
|
||||
}
|
||||
let save_profile = if let Some(profile) = &save_slice.profile {
|
||||
metadata.insert(
|
||||
"save_slice.profile_kind".to_string(),
|
||||
profile.profile_kind.clone(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.profile_family".to_string(),
|
||||
profile.profile_family.clone(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.packed_profile_offset".to_string(),
|
||||
profile.packed_profile_offset.to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.packed_profile_len".to_string(),
|
||||
profile.packed_profile_len.to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.leading_word_0_hex".to_string(),
|
||||
profile.leading_word_0_hex.clone(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.profile_byte_0x77_hex".to_string(),
|
||||
profile.profile_byte_0x77_hex.clone(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.profile_byte_0x82_hex".to_string(),
|
||||
profile.profile_byte_0x82_hex.clone(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.profile_byte_0x97_hex".to_string(),
|
||||
profile.profile_byte_0x97_hex.clone(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.profile_byte_0xc5_hex".to_string(),
|
||||
profile.profile_byte_0xc5_hex.clone(),
|
||||
);
|
||||
if let Some(header_flag_word_3_hex) = &profile.header_flag_word_3_hex {
|
||||
metadata.insert(
|
||||
"save_slice.header_flag_word_3_hex".to_string(),
|
||||
header_flag_word_3_hex.clone(),
|
||||
);
|
||||
}
|
||||
if let Some(map_path) = &profile.map_path {
|
||||
metadata.insert("save_slice.map_path".to_string(), map_path.clone());
|
||||
}
|
||||
if let Some(display_name) = &profile.display_name {
|
||||
metadata.insert("save_slice.display_name".to_string(), display_name.clone());
|
||||
}
|
||||
RuntimeSaveProfileState {
|
||||
profile_kind: Some(profile.profile_kind.clone()),
|
||||
profile_family: Some(profile.profile_family.clone()),
|
||||
map_path: profile.map_path.clone(),
|
||||
display_name: profile.display_name.clone(),
|
||||
selected_year_profile_lane: Some(profile.profile_byte_0x77),
|
||||
sandbox_enabled: Some(profile.profile_byte_0x82 != 0),
|
||||
campaign_scenario_enabled: Some(profile.profile_byte_0xc5 != 0),
|
||||
staged_profile_copy_on_restore: Some(profile.profile_byte_0x97 != 0),
|
||||
}
|
||||
} else {
|
||||
RuntimeSaveProfileState::default()
|
||||
};
|
||||
|
||||
let special_condition_enabled = |slot_index: u8| {
|
||||
save_slice.special_conditions_table.as_ref().map(|table| {
|
||||
table
|
||||
.entries
|
||||
.iter()
|
||||
.find(|entry| entry.slot_index == slot_index)
|
||||
.map(|entry| entry.value != 0)
|
||||
.unwrap_or(false)
|
||||
})
|
||||
};
|
||||
|
||||
let world_restore = if let Some(profile) = &save_slice.profile {
|
||||
let disable_cargo_economy_special_condition_enabled = special_condition_enabled(30);
|
||||
RuntimeWorldRestoreState {
|
||||
selected_year_profile_lane: Some(profile.profile_byte_0x77),
|
||||
campaign_scenario_enabled: Some(profile.profile_byte_0xc5 != 0),
|
||||
sandbox_enabled: Some(profile.profile_byte_0x82 != 0),
|
||||
seed_tuple_written_from_raw_lane: Some(true),
|
||||
absolute_counter_requires_shell_context: Some(true),
|
||||
absolute_counter_reconstructible_from_save: Some(false),
|
||||
disable_cargo_economy_special_condition_slot: Some(30),
|
||||
disable_cargo_economy_special_condition_reconstructible_from_save: Some(true),
|
||||
disable_cargo_economy_special_condition_write_side_grounded: Some(true),
|
||||
disable_cargo_economy_special_condition_enabled,
|
||||
use_bio_accelerator_cars_enabled: special_condition_enabled(29),
|
||||
use_wartime_cargos_enabled: special_condition_enabled(31),
|
||||
disable_train_crashes_enabled: special_condition_enabled(32),
|
||||
disable_train_crashes_and_breakdowns_enabled: special_condition_enabled(33),
|
||||
ai_ignore_territories_at_startup_enabled: special_condition_enabled(34),
|
||||
absolute_counter_restore_kind: Some(
|
||||
"mode-adjusted-selected-year-lane".to_string(),
|
||||
),
|
||||
absolute_counter_adjustment_context: Some(
|
||||
"editor-map-mode,shell-selected-year-adjust-policy-0x9d26-0x9d28,save-special-condition-disable-cargo-economy-slot-30"
|
||||
.to_string(),
|
||||
),
|
||||
}
|
||||
} else {
|
||||
RuntimeWorldRestoreState::default()
|
||||
};
|
||||
|
||||
let mut candidate_availability = BTreeMap::new();
|
||||
if let Some(table) = &save_slice.candidate_availability_table {
|
||||
metadata.insert(
|
||||
"save_slice.candidate_table_source_kind".to_string(),
|
||||
table.source_kind.clone(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.candidate_table_semantic_family".to_string(),
|
||||
table.semantic_family.clone(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.candidate_table_entry_count".to_string(),
|
||||
table.observed_entry_count.to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.candidate_table_zero_count".to_string(),
|
||||
table.zero_availability_count.to_string(),
|
||||
);
|
||||
for entry in &table.entries {
|
||||
candidate_availability.insert(entry.text.clone(), entry.availability_dword);
|
||||
}
|
||||
}
|
||||
let mut special_conditions = BTreeMap::new();
|
||||
if let Some(table) = &save_slice.special_conditions_table {
|
||||
metadata.insert(
|
||||
"save_slice.special_conditions_source_kind".to_string(),
|
||||
table.source_kind.clone(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.special_conditions_table_offset".to_string(),
|
||||
table.table_offset.to_string(),
|
||||
);
|
||||
metadata.insert(
|
||||
"save_slice.special_conditions_enabled_visible_count".to_string(),
|
||||
table.enabled_visible_count.to_string(),
|
||||
);
|
||||
for entry in &table.entries {
|
||||
if !entry.hidden {
|
||||
special_conditions.insert(entry.label.clone(), entry.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (index, note) in save_slice.notes.iter().enumerate() {
|
||||
metadata.insert(format!("save_slice.note.{index}"), note.clone());
|
||||
}
|
||||
|
||||
let state = RuntimeState {
|
||||
calendar: CalendarPoint {
|
||||
year: 1830,
|
||||
month_slot: 0,
|
||||
phase_slot: 0,
|
||||
tick_slot: 0,
|
||||
},
|
||||
world_flags,
|
||||
save_profile,
|
||||
world_restore,
|
||||
metadata,
|
||||
companies: Vec::new(),
|
||||
event_runtime_records: Vec::new(),
|
||||
candidate_availability,
|
||||
special_conditions,
|
||||
service_state: RuntimeServiceState::default(),
|
||||
};
|
||||
state.validate()?;
|
||||
|
||||
Ok(RuntimeStateImport {
|
||||
import_id: import_id.to_string(),
|
||||
description,
|
||||
state,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn validate_runtime_state_dump_document(
|
||||
document: &RuntimeStateDumpDocument,
|
||||
) -> Result<(), String> {
|
||||
|
|
@ -85,8 +365,6 @@ pub fn load_runtime_state_import_from_str(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{CalendarPoint, RuntimeServiceState};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
fn state() -> RuntimeState {
|
||||
RuntimeState {
|
||||
|
|
@ -97,8 +375,13 @@ mod tests {
|
|||
tick_slot: 0,
|
||||
},
|
||||
world_flags: BTreeMap::new(),
|
||||
save_profile: RuntimeSaveProfileState::default(),
|
||||
world_restore: RuntimeWorldRestoreState::default(),
|
||||
metadata: BTreeMap::new(),
|
||||
companies: Vec::new(),
|
||||
event_runtime_records: Vec::new(),
|
||||
candidate_availability: BTreeMap::new(),
|
||||
special_conditions: BTreeMap::new(),
|
||||
service_state: RuntimeServiceState::default(),
|
||||
}
|
||||
}
|
||||
|
|
@ -130,4 +413,236 @@ mod tests {
|
|||
assert_eq!(import.import_id, "fallback");
|
||||
assert!(import.description.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn projects_save_slice_into_runtime_state_import() {
|
||||
let save_slice = SmpLoadedSaveSlice {
|
||||
file_extension_hint: Some("gms".to_string()),
|
||||
container_profile_family: Some("rt3-105-save-container-v1".to_string()),
|
||||
mechanism_family: "rt3-105-save-post-span-bridge-v1".to_string(),
|
||||
mechanism_confidence: "mixed".to_string(),
|
||||
trailer_family: Some("rt3-105-save-trailer-v1".to_string()),
|
||||
bridge_family: Some("rt3-105-save-post-span-bridge-v1".to_string()),
|
||||
profile: Some(crate::SmpLoadedProfile {
|
||||
profile_kind: "rt3-105-packed-profile".to_string(),
|
||||
profile_family: "rt3-105-save-container-v1".to_string(),
|
||||
packed_profile_offset: 0x73c0,
|
||||
packed_profile_len: 0x108,
|
||||
packed_profile_len_hex: "0x108".to_string(),
|
||||
leading_word_0: 3,
|
||||
leading_word_0_hex: "0x00000003".to_string(),
|
||||
header_flag_word_3: Some(0x01000000),
|
||||
header_flag_word_3_hex: Some("0x01000000".to_string()),
|
||||
map_path: Some("Alternate USA.gmp".to_string()),
|
||||
display_name: Some("Alternate USA".to_string()),
|
||||
profile_byte_0x77: 0x07,
|
||||
profile_byte_0x77_hex: "0x07".to_string(),
|
||||
profile_byte_0x82: 0x4d,
|
||||
profile_byte_0x82_hex: "0x4d".to_string(),
|
||||
profile_byte_0x97: 0x00,
|
||||
profile_byte_0x97_hex: "0x00".to_string(),
|
||||
profile_byte_0xc5: 0x00,
|
||||
profile_byte_0xc5_hex: "0x00".to_string(),
|
||||
}),
|
||||
candidate_availability_table: Some(crate::SmpLoadedCandidateAvailabilityTable {
|
||||
source_kind: "save-bridge-secondary-block".to_string(),
|
||||
semantic_family: "scenario-named-candidate-availability-table".to_string(),
|
||||
header_offset: 0x6a70,
|
||||
entries_offset: 0x6ad1,
|
||||
entries_end_offset: 0x73b7,
|
||||
observed_entry_count: 2,
|
||||
zero_availability_count: 1,
|
||||
zero_availability_names: vec!["Uranium Mine".to_string()],
|
||||
footer_progress_hex_words: vec!["0x000032dc".to_string(), "0x00003714".to_string()],
|
||||
entries: vec![
|
||||
crate::SmpRt3105SaveNameTableEntry {
|
||||
index: 0,
|
||||
offset: 0x6ad1,
|
||||
text: "AutoPlant".to_string(),
|
||||
availability_dword: 1,
|
||||
availability_dword_hex: "0x00000001".to_string(),
|
||||
trailer_word: 1,
|
||||
trailer_word_hex: "0x00000001".to_string(),
|
||||
},
|
||||
crate::SmpRt3105SaveNameTableEntry {
|
||||
index: 1,
|
||||
offset: 0x6af3,
|
||||
text: "Uranium Mine".to_string(),
|
||||
availability_dword: 0,
|
||||
availability_dword_hex: "0x00000000".to_string(),
|
||||
trailer_word: 0,
|
||||
trailer_word_hex: "0x00000000".to_string(),
|
||||
},
|
||||
],
|
||||
}),
|
||||
special_conditions_table: Some(crate::SmpLoadedSpecialConditionsTable {
|
||||
source_kind: "save-fixed-special-conditions-range".to_string(),
|
||||
table_offset: 0x0d64,
|
||||
table_len: 36 * 4,
|
||||
enabled_visible_count: 0,
|
||||
enabled_visible_labels: vec![],
|
||||
entries: vec![
|
||||
crate::SmpSpecialConditionEntry {
|
||||
slot_index: 30,
|
||||
hidden: false,
|
||||
label_id: 3722,
|
||||
help_id: 3723,
|
||||
label: "Disable Cargo Economy".to_string(),
|
||||
value: 0,
|
||||
value_hex: "0x00000000".to_string(),
|
||||
},
|
||||
crate::SmpSpecialConditionEntry {
|
||||
slot_index: 35,
|
||||
hidden: true,
|
||||
label_id: 3,
|
||||
help_id: 3,
|
||||
label: "Hidden sentinel".to_string(),
|
||||
value: 1,
|
||||
value_hex: "0x00000001".to_string(),
|
||||
},
|
||||
],
|
||||
}),
|
||||
notes: vec!["packed profile recovered".to_string()],
|
||||
};
|
||||
|
||||
let import = project_save_slice_to_runtime_state_import(
|
||||
&save_slice,
|
||||
"save-import-smoke",
|
||||
Some("test save import".to_string()),
|
||||
)
|
||||
.expect("save slice should project");
|
||||
|
||||
assert_eq!(import.import_id, "save-import-smoke");
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.metadata
|
||||
.get("save_slice.map_path")
|
||||
.map(String::as_str),
|
||||
Some("Alternate USA.gmp")
|
||||
);
|
||||
assert_eq!(
|
||||
import.state.save_profile.selected_year_profile_lane,
|
||||
Some(0x07)
|
||||
);
|
||||
assert_eq!(import.state.save_profile.sandbox_enabled, Some(true));
|
||||
assert_eq!(
|
||||
import.state.world_restore.selected_year_profile_lane,
|
||||
Some(0x07)
|
||||
);
|
||||
assert_eq!(import.state.world_restore.sandbox_enabled, Some(true));
|
||||
assert_eq!(
|
||||
import.state.world_restore.campaign_scenario_enabled,
|
||||
Some(false)
|
||||
);
|
||||
assert_eq!(
|
||||
import.state.world_restore.seed_tuple_written_from_raw_lane,
|
||||
Some(true)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_restore
|
||||
.absolute_counter_requires_shell_context,
|
||||
Some(true)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_restore
|
||||
.absolute_counter_reconstructible_from_save,
|
||||
Some(false)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_restore
|
||||
.disable_cargo_economy_special_condition_slot,
|
||||
Some(30)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_restore
|
||||
.disable_cargo_economy_special_condition_reconstructible_from_save,
|
||||
Some(true)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_restore
|
||||
.disable_cargo_economy_special_condition_write_side_grounded,
|
||||
Some(true)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_restore
|
||||
.disable_cargo_economy_special_condition_enabled,
|
||||
Some(false)
|
||||
);
|
||||
assert_eq!(
|
||||
import.state.world_restore.use_bio_accelerator_cars_enabled,
|
||||
Some(false)
|
||||
);
|
||||
assert_eq!(
|
||||
import.state.world_restore.use_wartime_cargos_enabled,
|
||||
Some(false)
|
||||
);
|
||||
assert_eq!(
|
||||
import.state.world_restore.disable_train_crashes_enabled,
|
||||
Some(false)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_restore
|
||||
.disable_train_crashes_and_breakdowns_enabled,
|
||||
Some(false)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_restore
|
||||
.ai_ignore_territories_at_startup_enabled,
|
||||
Some(false)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_restore
|
||||
.absolute_counter_restore_kind
|
||||
.as_deref(),
|
||||
Some("mode-adjusted-selected-year-lane")
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_restore
|
||||
.absolute_counter_adjustment_context
|
||||
.as_deref(),
|
||||
Some(
|
||||
"editor-map-mode,shell-selected-year-adjust-policy-0x9d26-0x9d28,save-special-condition-disable-cargo-economy-slot-30"
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
import.state.save_profile.map_path.as_deref(),
|
||||
Some("Alternate USA.gmp")
|
||||
);
|
||||
assert_eq!(
|
||||
import.state.candidate_availability.get("Uranium Mine"),
|
||||
Some(&0)
|
||||
);
|
||||
assert_eq!(
|
||||
import.state.special_conditions.get("Disable Cargo Economy"),
|
||||
Some(&0)
|
||||
);
|
||||
assert_eq!(
|
||||
import
|
||||
.state
|
||||
.world_flags
|
||||
.get("save_slice.profile_byte_0x82_nonzero"),
|
||||
Some(&true)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ pub use campaign_exe::{
|
|||
};
|
||||
pub use import::{
|
||||
RuntimeStateDumpDocument, RuntimeStateDumpSource, RuntimeStateImport,
|
||||
STATE_DUMP_FORMAT_VERSION, load_runtime_state_import, validate_runtime_state_dump_document,
|
||||
STATE_DUMP_FORMAT_VERSION, load_runtime_state_import,
|
||||
project_save_slice_to_runtime_state_import, validate_runtime_state_dump_document,
|
||||
};
|
||||
pub use persistence::{
|
||||
RuntimeSnapshotDocument, RuntimeSnapshotSource, SNAPSHOT_FORMAT_VERSION,
|
||||
|
|
@ -27,16 +28,30 @@ pub use pk4::{
|
|||
PK4_DIRECTORY_ENTRY_STRIDE, PK4_MAGIC, Pk4Entry, Pk4ExtractionReport, Pk4InspectionReport,
|
||||
extract_pk4_entry_bytes, extract_pk4_entry_file, inspect_pk4_bytes, inspect_pk4_file,
|
||||
};
|
||||
pub use runtime::{RuntimeCompany, RuntimeEventRecord, RuntimeServiceState, RuntimeState};
|
||||
pub use runtime::{
|
||||
RuntimeCompany, RuntimeEventRecord, RuntimeSaveProfileState, RuntimeServiceState, RuntimeState,
|
||||
RuntimeWorldRestoreState,
|
||||
};
|
||||
pub use smp::{
|
||||
SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAsciiPreview, SmpClassicPackedProfileBlock,
|
||||
SMP_FOUR_SIDECAR_BYTE_PLANES_MIN_BUNDLE_VERSION, SmpAlignedRuntimeRuleBandLane,
|
||||
SmpAlignedRuntimeRuleBandProbe, SmpAsciiPreview, SmpClassicPackedProfileBlock,
|
||||
SmpClassicRehydrateProfileProbe, SmpContainerProfile, SmpEarlyContentProbe,
|
||||
SmpHeaderVariantProbe, SmpInspectionReport, SmpKnownTagHit, SmpPackedProfileWordLane,
|
||||
SmpPreamble, SmpPreambleWord, SmpRt3105PackedProfileBlock, SmpRt3105PackedProfileProbe,
|
||||
SmpRt3105PostSpanBridgeProbe, SmpRt3105SaveBridgePayloadProbe, SmpRt3105SaveNameTableEntry,
|
||||
SmpRt3105SaveNameTableProbe, SmpRuntimeAnchorCycleBlock, SmpRuntimePostSpanHeaderCandidate,
|
||||
SmpRuntimePostSpanProbe, SmpRuntimeTrailerBlock, SmpSaveAnchorRunBlock, SmpSaveBootstrapBlock,
|
||||
SmpSecondaryVariantProbe, SmpSharedHeader, inspect_smp_bytes, inspect_smp_file,
|
||||
SmpHeaderVariantProbe, SmpInspectionReport, SmpKnownTagHit,
|
||||
SmpLoadedCandidateAvailabilityTable, SmpLoadedProfile, SmpLoadedSaveSlice,
|
||||
SmpLoadedSpecialConditionsTable, SmpLocomotivePolicyFieldObservation,
|
||||
SmpLocomotivePolicyFloatAlignmentCandidate, SmpLocomotivePolicyNeighborhoodProbe,
|
||||
SmpPackedProfileWordLane, SmpPostSpecialConditionsScalarLane,
|
||||
SmpPostSpecialConditionsScalarProbe, SmpPostTextFieldNeighborhoodProbe,
|
||||
SmpPostTextFloatAlignmentCandidate, SmpPostTextGroundedFieldObservation,
|
||||
SmpPreRecipeScalarPlateauLane, SmpPreRecipeScalarPlateauProbe, SmpPreamble, SmpPreambleWord,
|
||||
SmpRecipeBookLineSummary, SmpRecipeBookSummaryBook, SmpRecipeBookSummaryProbe,
|
||||
SmpRt3105PackedProfileBlock, SmpRt3105PackedProfileProbe, SmpRt3105PostSpanBridgeProbe,
|
||||
SmpRt3105SaveBridgePayloadProbe, SmpRt3105SaveNameTableEntry, SmpRt3105SaveNameTableProbe,
|
||||
SmpRuntimeAnchorCycleBlock, SmpRuntimePostSpanHeaderCandidate, SmpRuntimePostSpanProbe,
|
||||
SmpRuntimeTrailerBlock, SmpSaveAnchorRunBlock, SmpSaveBootstrapBlock,
|
||||
SmpSaveLoadCandidateTableSummary, SmpSaveLoadSummary, SmpSecondaryVariantProbe,
|
||||
SmpSharedHeader, SmpSpecialConditionEntry, SmpSpecialConditionsProbe, inspect_smp_bytes,
|
||||
inspect_smp_file, load_save_slice_file, load_save_slice_from_report,
|
||||
};
|
||||
pub use step::{BoundaryEvent, ServiceEvent, StepCommand, StepResult, execute_step_command};
|
||||
pub use summary::RuntimeSummary;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,9 @@ pub fn save_runtime_snapshot_document(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{CalendarPoint, RuntimeServiceState};
|
||||
use crate::{
|
||||
CalendarPoint, RuntimeSaveProfileState, RuntimeServiceState, RuntimeWorldRestoreState,
|
||||
};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
fn snapshot() -> RuntimeSnapshotDocument {
|
||||
|
|
@ -87,8 +89,13 @@ mod tests {
|
|||
tick_slot: 0,
|
||||
},
|
||||
world_flags: BTreeMap::new(),
|
||||
save_profile: RuntimeSaveProfileState::default(),
|
||||
world_restore: RuntimeWorldRestoreState::default(),
|
||||
metadata: BTreeMap::new(),
|
||||
companies: Vec::new(),
|
||||
event_runtime_records: Vec::new(),
|
||||
candidate_availability: BTreeMap::new(),
|
||||
special_conditions: BTreeMap::new(),
|
||||
service_state: RuntimeServiceState::default(),
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,16 +34,84 @@ pub struct RuntimeServiceState {
|
|||
pub dirty_rerun_count: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
|
||||
pub struct RuntimeSaveProfileState {
|
||||
#[serde(default)]
|
||||
pub profile_kind: Option<String>,
|
||||
#[serde(default)]
|
||||
pub profile_family: Option<String>,
|
||||
#[serde(default)]
|
||||
pub map_path: Option<String>,
|
||||
#[serde(default)]
|
||||
pub display_name: Option<String>,
|
||||
#[serde(default)]
|
||||
pub selected_year_profile_lane: Option<u8>,
|
||||
#[serde(default)]
|
||||
pub sandbox_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub campaign_scenario_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub staged_profile_copy_on_restore: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
|
||||
pub struct RuntimeWorldRestoreState {
|
||||
#[serde(default)]
|
||||
pub selected_year_profile_lane: Option<u8>,
|
||||
#[serde(default)]
|
||||
pub campaign_scenario_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub sandbox_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub seed_tuple_written_from_raw_lane: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub absolute_counter_requires_shell_context: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub absolute_counter_reconstructible_from_save: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub disable_cargo_economy_special_condition_slot: Option<u8>,
|
||||
#[serde(default)]
|
||||
pub disable_cargo_economy_special_condition_reconstructible_from_save: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub disable_cargo_economy_special_condition_write_side_grounded: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub disable_cargo_economy_special_condition_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub use_bio_accelerator_cars_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub use_wartime_cargos_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub disable_train_crashes_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub disable_train_crashes_and_breakdowns_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub ai_ignore_territories_at_startup_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub absolute_counter_restore_kind: Option<String>,
|
||||
#[serde(default)]
|
||||
pub absolute_counter_adjustment_context: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct RuntimeState {
|
||||
pub calendar: CalendarPoint,
|
||||
#[serde(default)]
|
||||
pub world_flags: BTreeMap<String, bool>,
|
||||
#[serde(default)]
|
||||
pub save_profile: RuntimeSaveProfileState,
|
||||
#[serde(default)]
|
||||
pub world_restore: RuntimeWorldRestoreState,
|
||||
#[serde(default)]
|
||||
pub metadata: BTreeMap<String, String>,
|
||||
#[serde(default)]
|
||||
pub companies: Vec<RuntimeCompany>,
|
||||
#[serde(default)]
|
||||
pub event_runtime_records: Vec<RuntimeEventRecord>,
|
||||
#[serde(default)]
|
||||
pub candidate_availability: BTreeMap<String, u32>,
|
||||
#[serde(default)]
|
||||
pub special_conditions: BTreeMap<String, u32>,
|
||||
#[serde(default)]
|
||||
pub service_state: RuntimeServiceState,
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +139,79 @@ impl RuntimeState {
|
|||
}
|
||||
}
|
||||
|
||||
for (label, value) in [
|
||||
(
|
||||
"save_profile.profile_kind",
|
||||
self.save_profile.profile_kind.as_deref(),
|
||||
),
|
||||
(
|
||||
"save_profile.profile_family",
|
||||
self.save_profile.profile_family.as_deref(),
|
||||
),
|
||||
(
|
||||
"save_profile.map_path",
|
||||
self.save_profile.map_path.as_deref(),
|
||||
),
|
||||
(
|
||||
"save_profile.display_name",
|
||||
self.save_profile.display_name.as_deref(),
|
||||
),
|
||||
] {
|
||||
if value.is_some_and(|text| text.trim().is_empty()) {
|
||||
return Err(format!("{label} must not be empty"));
|
||||
}
|
||||
}
|
||||
|
||||
if self.world_restore.selected_year_profile_lane.is_none()
|
||||
&& (self.world_restore.campaign_scenario_enabled.is_some()
|
||||
|| self.world_restore.sandbox_enabled.is_some())
|
||||
{
|
||||
return Err(
|
||||
"world_restore.selected_year_profile_lane must be present when world restore flags are populated"
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
if self
|
||||
.world_restore
|
||||
.absolute_counter_restore_kind
|
||||
.as_deref()
|
||||
.is_some_and(|text| text.trim().is_empty())
|
||||
{
|
||||
return Err(
|
||||
"world_restore.absolute_counter_restore_kind must not be empty".to_string(),
|
||||
);
|
||||
}
|
||||
if self
|
||||
.world_restore
|
||||
.absolute_counter_adjustment_context
|
||||
.as_deref()
|
||||
.is_some_and(|text| text.trim().is_empty())
|
||||
{
|
||||
return Err(
|
||||
"world_restore.absolute_counter_adjustment_context must not be empty".to_string(),
|
||||
);
|
||||
}
|
||||
for (key, value) in &self.metadata {
|
||||
if key.trim().is_empty() {
|
||||
return Err("metadata contains an empty key".to_string());
|
||||
}
|
||||
if value.trim().is_empty() {
|
||||
return Err(format!("metadata[{key}] must not be empty"));
|
||||
}
|
||||
}
|
||||
|
||||
for key in self.candidate_availability.keys() {
|
||||
if key.trim().is_empty() {
|
||||
return Err("candidate_availability contains an empty key".to_string());
|
||||
}
|
||||
}
|
||||
for key in self.special_conditions.keys() {
|
||||
if key.trim().is_empty() {
|
||||
return Err("special_conditions contains an empty key".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -89,6 +230,9 @@ mod tests {
|
|||
tick_slot: 0,
|
||||
},
|
||||
world_flags: BTreeMap::new(),
|
||||
save_profile: RuntimeSaveProfileState::default(),
|
||||
world_restore: RuntimeWorldRestoreState::default(),
|
||||
metadata: BTreeMap::new(),
|
||||
companies: vec![
|
||||
RuntimeCompany {
|
||||
company_id: 1,
|
||||
|
|
@ -102,6 +246,53 @@ mod tests {
|
|||
},
|
||||
],
|
||||
event_runtime_records: Vec::new(),
|
||||
candidate_availability: BTreeMap::new(),
|
||||
special_conditions: BTreeMap::new(),
|
||||
service_state: RuntimeServiceState::default(),
|
||||
};
|
||||
|
||||
assert!(state.validate().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_partial_world_restore_without_year_lane() {
|
||||
let state = RuntimeState {
|
||||
calendar: CalendarPoint {
|
||||
year: 1830,
|
||||
month_slot: 0,
|
||||
phase_slot: 0,
|
||||
tick_slot: 0,
|
||||
},
|
||||
world_flags: BTreeMap::new(),
|
||||
save_profile: RuntimeSaveProfileState::default(),
|
||||
world_restore: RuntimeWorldRestoreState {
|
||||
selected_year_profile_lane: None,
|
||||
campaign_scenario_enabled: Some(false),
|
||||
sandbox_enabled: Some(true),
|
||||
seed_tuple_written_from_raw_lane: Some(true),
|
||||
absolute_counter_requires_shell_context: Some(true),
|
||||
absolute_counter_reconstructible_from_save: Some(false),
|
||||
disable_cargo_economy_special_condition_slot: Some(30),
|
||||
disable_cargo_economy_special_condition_reconstructible_from_save: Some(true),
|
||||
disable_cargo_economy_special_condition_write_side_grounded: Some(true),
|
||||
disable_cargo_economy_special_condition_enabled: Some(false),
|
||||
use_bio_accelerator_cars_enabled: Some(false),
|
||||
use_wartime_cargos_enabled: Some(false),
|
||||
disable_train_crashes_enabled: Some(false),
|
||||
disable_train_crashes_and_breakdowns_enabled: Some(false),
|
||||
ai_ignore_territories_at_startup_enabled: Some(false),
|
||||
absolute_counter_restore_kind: Some(
|
||||
"mode-adjusted-selected-year-lane".to_string(),
|
||||
),
|
||||
absolute_counter_adjustment_context: Some(
|
||||
"editor-map-mode,shell-selected-year-adjust-policy-0x9d26-0x9d28,save-special-condition-disable-cargo-economy-slot-30".to_string(),
|
||||
),
|
||||
},
|
||||
metadata: BTreeMap::new(),
|
||||
companies: Vec::new(),
|
||||
event_runtime_records: Vec::new(),
|
||||
candidate_availability: BTreeMap::new(),
|
||||
special_conditions: BTreeMap::new(),
|
||||
service_state: RuntimeServiceState::default(),
|
||||
};
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -188,7 +188,10 @@ mod tests {
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use super::*;
|
||||
use crate::{CalendarPoint, RuntimeCompany, RuntimeEventRecord, RuntimeServiceState};
|
||||
use crate::{
|
||||
CalendarPoint, RuntimeCompany, RuntimeEventRecord, RuntimeSaveProfileState,
|
||||
RuntimeServiceState, RuntimeWorldRestoreState,
|
||||
};
|
||||
|
||||
fn state() -> RuntimeState {
|
||||
RuntimeState {
|
||||
|
|
@ -199,12 +202,17 @@ mod tests {
|
|||
tick_slot: 0,
|
||||
},
|
||||
world_flags: BTreeMap::new(),
|
||||
save_profile: RuntimeSaveProfileState::default(),
|
||||
world_restore: RuntimeWorldRestoreState::default(),
|
||||
metadata: BTreeMap::new(),
|
||||
companies: vec![RuntimeCompany {
|
||||
company_id: 1,
|
||||
current_cash: 10,
|
||||
debt: 0,
|
||||
}],
|
||||
event_runtime_records: Vec::new(),
|
||||
candidate_availability: BTreeMap::new(),
|
||||
special_conditions: BTreeMap::new(),
|
||||
service_state: RuntimeServiceState::default(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,42 @@ use crate::{CalendarPoint, RuntimeState};
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct RuntimeSummary {
|
||||
pub calendar: CalendarPoint,
|
||||
pub calendar_projection_source: Option<String>,
|
||||
pub calendar_projection_is_placeholder: bool,
|
||||
pub world_flag_count: usize,
|
||||
pub world_restore_selected_year_profile_lane: Option<u8>,
|
||||
pub world_restore_campaign_scenario_enabled: Option<bool>,
|
||||
pub world_restore_sandbox_enabled: Option<bool>,
|
||||
pub world_restore_seed_tuple_written_from_raw_lane: Option<bool>,
|
||||
pub world_restore_absolute_counter_requires_shell_context: Option<bool>,
|
||||
pub world_restore_absolute_counter_reconstructible_from_save: Option<bool>,
|
||||
pub world_restore_disable_cargo_economy_special_condition_slot: Option<u8>,
|
||||
pub world_restore_disable_cargo_economy_special_condition_reconstructible_from_save:
|
||||
Option<bool>,
|
||||
pub world_restore_disable_cargo_economy_special_condition_write_side_grounded: Option<bool>,
|
||||
pub world_restore_disable_cargo_economy_special_condition_enabled: Option<bool>,
|
||||
pub world_restore_use_bio_accelerator_cars_enabled: Option<bool>,
|
||||
pub world_restore_use_wartime_cargos_enabled: Option<bool>,
|
||||
pub world_restore_disable_train_crashes_enabled: Option<bool>,
|
||||
pub world_restore_disable_train_crashes_and_breakdowns_enabled: Option<bool>,
|
||||
pub world_restore_ai_ignore_territories_at_startup_enabled: Option<bool>,
|
||||
pub world_restore_absolute_counter_restore_kind: Option<String>,
|
||||
pub world_restore_absolute_counter_adjustment_context: Option<String>,
|
||||
pub metadata_count: usize,
|
||||
pub company_count: usize,
|
||||
pub event_runtime_record_count: usize,
|
||||
pub candidate_availability_count: usize,
|
||||
pub zero_candidate_availability_count: usize,
|
||||
pub special_condition_count: usize,
|
||||
pub enabled_special_condition_count: usize,
|
||||
pub save_profile_kind: Option<String>,
|
||||
pub save_profile_family: Option<String>,
|
||||
pub save_profile_map_path: Option<String>,
|
||||
pub save_profile_display_name: Option<String>,
|
||||
pub save_profile_selected_year_profile_lane: Option<u8>,
|
||||
pub save_profile_sandbox_enabled: Option<bool>,
|
||||
pub save_profile_campaign_scenario_enabled: Option<bool>,
|
||||
pub save_profile_staged_profile_copy_on_restore: Option<bool>,
|
||||
pub total_event_record_service_count: u64,
|
||||
pub periodic_boundary_call_count: u64,
|
||||
pub total_trigger_dispatch_count: u64,
|
||||
|
|
@ -19,9 +52,86 @@ impl RuntimeSummary {
|
|||
pub fn from_state(state: &RuntimeState) -> Self {
|
||||
Self {
|
||||
calendar: state.calendar,
|
||||
calendar_projection_source: state.metadata.get("save_slice.calendar_source").cloned(),
|
||||
calendar_projection_is_placeholder: state
|
||||
.metadata
|
||||
.get("save_slice.calendar_source")
|
||||
.is_some_and(|value| value == "default-1830-placeholder"),
|
||||
world_flag_count: state.world_flags.len(),
|
||||
world_restore_selected_year_profile_lane: state
|
||||
.world_restore
|
||||
.selected_year_profile_lane,
|
||||
world_restore_campaign_scenario_enabled: state.world_restore.campaign_scenario_enabled,
|
||||
world_restore_sandbox_enabled: state.world_restore.sandbox_enabled,
|
||||
world_restore_seed_tuple_written_from_raw_lane: state
|
||||
.world_restore
|
||||
.seed_tuple_written_from_raw_lane,
|
||||
world_restore_absolute_counter_requires_shell_context: state
|
||||
.world_restore
|
||||
.absolute_counter_requires_shell_context,
|
||||
world_restore_absolute_counter_reconstructible_from_save: state
|
||||
.world_restore
|
||||
.absolute_counter_reconstructible_from_save,
|
||||
world_restore_disable_cargo_economy_special_condition_slot: state
|
||||
.world_restore
|
||||
.disable_cargo_economy_special_condition_slot,
|
||||
world_restore_disable_cargo_economy_special_condition_reconstructible_from_save: state
|
||||
.world_restore
|
||||
.disable_cargo_economy_special_condition_reconstructible_from_save,
|
||||
world_restore_disable_cargo_economy_special_condition_write_side_grounded: state
|
||||
.world_restore
|
||||
.disable_cargo_economy_special_condition_write_side_grounded,
|
||||
world_restore_disable_cargo_economy_special_condition_enabled: state
|
||||
.world_restore
|
||||
.disable_cargo_economy_special_condition_enabled,
|
||||
world_restore_use_bio_accelerator_cars_enabled: state
|
||||
.world_restore
|
||||
.use_bio_accelerator_cars_enabled,
|
||||
world_restore_use_wartime_cargos_enabled: state
|
||||
.world_restore
|
||||
.use_wartime_cargos_enabled,
|
||||
world_restore_disable_train_crashes_enabled: state
|
||||
.world_restore
|
||||
.disable_train_crashes_enabled,
|
||||
world_restore_disable_train_crashes_and_breakdowns_enabled: state
|
||||
.world_restore
|
||||
.disable_train_crashes_and_breakdowns_enabled,
|
||||
world_restore_ai_ignore_territories_at_startup_enabled: state
|
||||
.world_restore
|
||||
.ai_ignore_territories_at_startup_enabled,
|
||||
world_restore_absolute_counter_restore_kind: state
|
||||
.world_restore
|
||||
.absolute_counter_restore_kind
|
||||
.clone(),
|
||||
world_restore_absolute_counter_adjustment_context: state
|
||||
.world_restore
|
||||
.absolute_counter_adjustment_context
|
||||
.clone(),
|
||||
metadata_count: state.metadata.len(),
|
||||
company_count: state.companies.len(),
|
||||
event_runtime_record_count: state.event_runtime_records.len(),
|
||||
candidate_availability_count: state.candidate_availability.len(),
|
||||
zero_candidate_availability_count: state
|
||||
.candidate_availability
|
||||
.values()
|
||||
.filter(|value| **value == 0)
|
||||
.count(),
|
||||
special_condition_count: state.special_conditions.len(),
|
||||
enabled_special_condition_count: state
|
||||
.special_conditions
|
||||
.values()
|
||||
.filter(|value| **value != 0)
|
||||
.count(),
|
||||
save_profile_kind: state.save_profile.profile_kind.clone(),
|
||||
save_profile_family: state.save_profile.profile_family.clone(),
|
||||
save_profile_map_path: state.save_profile.map_path.clone(),
|
||||
save_profile_display_name: state.save_profile.display_name.clone(),
|
||||
save_profile_selected_year_profile_lane: state.save_profile.selected_year_profile_lane,
|
||||
save_profile_sandbox_enabled: state.save_profile.sandbox_enabled,
|
||||
save_profile_campaign_scenario_enabled: state.save_profile.campaign_scenario_enabled,
|
||||
save_profile_staged_profile_copy_on_restore: state
|
||||
.save_profile
|
||||
.staged_profile_copy_on_restore,
|
||||
total_event_record_service_count: state.service_state.total_event_record_services,
|
||||
periodic_boundary_call_count: state.service_state.periodic_boundary_calls,
|
||||
total_trigger_dispatch_count: state
|
||||
|
|
|
|||
|
|
@ -382,20 +382,24 @@ fn collect_anonymous_selector_records(
|
|||
|
||||
let mut records = Vec::new();
|
||||
let mut start = 0usize;
|
||||
while let Some(relative) = bytes
|
||||
.get(start..)
|
||||
.and_then(|slice| slice.windows(PRELUDE.len()).position(|window| window == PRELUDE))
|
||||
{
|
||||
while let Some(relative) = bytes.get(start..).and_then(|slice| {
|
||||
slice
|
||||
.windows(PRELUDE.len())
|
||||
.position(|window| window == PRELUDE)
|
||||
}) {
|
||||
let record_offset = start + relative;
|
||||
let name_len = read_u32_le(bytes, record_offset + PRELUDE.len()).unwrap_or(0);
|
||||
if name_len == 0 {
|
||||
let selector_word_0 = read_u32_le(bytes, record_offset + 0x10).unwrap_or(0);
|
||||
let selector_word_0_low_u16 = (selector_word_0 & 0xffff) as u16;
|
||||
if (0xc352..=0xc39b).contains(&selector_word_0_low_u16) {
|
||||
let preceding_named_record =
|
||||
references.iter().rev().find(|reference| reference.offset < record_offset);
|
||||
let following_named_record =
|
||||
references.iter().find(|reference| reference.offset > record_offset);
|
||||
let preceding_named_record = references
|
||||
.iter()
|
||||
.rev()
|
||||
.find(|reference| reference.offset < record_offset);
|
||||
let following_named_record = references
|
||||
.iter()
|
||||
.find(|reference| reference.offset > record_offset);
|
||||
let selector_word_1 = read_u32_le(bytes, record_offset + 0x14).unwrap_or(0);
|
||||
let selector_word_0_high_u16 = ((selector_word_0 >> 16) & 0xffff) as u16;
|
||||
let selector_word_1_middle_u16 = ((selector_word_1 >> 8) & 0xffff) as u16;
|
||||
|
|
|
|||
87
rt3_auto_load_winedbg.log
Normal file
87
rt3_auto_load_winedbg.log
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
Script started on 2026-04-08 18:28:14-07:00 [COMMAND="/opt/wine-stable/bin/winedbg --file /home/jan/projects/rrt/tools/winedbg_auto_load_compare.cmd RT3.exe" TERM="xterm-256color" TTY="/dev/pts/4" COLUMNS="116" LINES="70"]
|
||||
]0;Wine Debugger[?25lWineDbg starting on pid 00f0
|
||||
[?25h00ec:fixme:dbghelp:elf_search_auxv can't find symbol in module
|
||||
00ec:fixme:dbghelp:elf_search_auxv can't find symbol in module
|
||||
[?25lprocess_breakpoint () at /usr/src/packages/BUILD/dlls/ntdll/signal_i386.c:557
|
||||
[?25h[?25l0x0000007bd237b6 process_breakpoint+0x36 [/usr/src/packages/BUILD/dlls/ntdll/signal_i386.c:557] in ntdll: movl -0x58
|
||||
(%ebp), %eax[K
|
||||
[?25h[?25lUnable to access file '/usr/src/packages/BUILD/dlls/ntdll/signal_i386.c'
|
||||
[?25h[?25lBreakpoint 1 at 0x00000000438890 rt3+0x38890
|
||||
[?25h[?25lBreakpoint 2 at 0x000000004390cb rt3+0x390cb
|
||||
[?25h[?25lBreakpoint 3 at 0x00000000445ac0 rt3+0x45ac0
|
||||
[?25h00f4:fixme:ntdll:NtQuerySystemInformation info_class SYSTEM_PERFORMANCE_INFORMATION
|
||||
libEGL warning: DRI3 error: Could not get DRI3 device
|
||||
libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering
|
||||
00f4:fixme:d3d:wined3d_guess_card No card selector available for card vendor 0000 (using GL_RENDERER "llvmpipe (LLVM 19.1.7, 256 bits)").
|
||||
00f4:fixme:d3d:wined3d_guess_card No card selector available for card vendor 0000 (using GL_RENDERER "llvmpipe (LLVM 19.1.7, 256 bits)").
|
||||
[?25lThread ID=0160 not in our list of threads -> can't rename
|
||||
[?25h[?25lThread ID=0184 not in our list of threads -> can't rename
|
||||
[?25h0140:fixme:d3d:state_linepattern_w Setting line patterns is not supported in OpenGL core contexts.
|
||||
X Error of failed request: XF86VidModeClientNotLocal
|
||||
Major opcode of failed request: 150 (XFree86-VidModeExtension)
|
||||
Minor opcode of failed request: 15 (XF86VidModeSetGamma)
|
||||
Serial number of failed request: 3081
|
||||
Current serial number in output stream: 3098
|
||||
[?25lInvalid address (0x00000000438890 rt3+0x38890) for breakpoint 1, disabling it
|
||||
[?25h[?25lInvalid address (0x000000004390cb rt3+0x390cb) for breakpoint 2, disabling it
|
||||
[?25h[?25lInvalid address (0x00000000445ac0 rt3+0x45ac0) for breakpoint 3, disabling it
|
||||
[?25h[?25lProcess of pid=00f0 has terminated
|
||||
[?25h
|
||||
[?25lException c0000005
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp)'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+4)'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+8)'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+12)'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec74'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec7c'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec78'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9b8'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9bc'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9c0'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9c4'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1270'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1274'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1278'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d127c'
|
||||
[?25h[?25lYou must be attached to a process to run this command.
|
||||
[?25h[?25lNo process loaded, cannot execute 'cont'
|
||||
[?25h[?25lNo process loaded, cannot execute 'cont'
|
||||
[?25h
|
||||
[?25lException c0000005
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp)'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+4)'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+8)'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+12)'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec74'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec7c'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec78'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9b8'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9bc'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9c0'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9c4'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1270'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1274'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1278'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d127c'
|
||||
[?25h[?25lYou must be attached to a process to run this command.
|
||||
[?25h[?25lNo process loaded, cannot execute 'cont'
|
||||
[?25h
|
||||
[?25lException c0000005
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp)'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+4)'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+8)'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)($esp+12)'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec74'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec7c'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006cec78'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9b8'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9bc'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9c0'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006ce9c4'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1270'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1274'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d1278'
|
||||
[?25h[?25lNo process loaded, cannot execute 'print/x *(unsigned int*)0x006d127c'
|
||||
[?25h[?25lYou must be attached to a process to run this command.
|
||||
[?25h
|
||||
Script done on 2026-04-08 18:33:15-07:00 [COMMAND_EXIT_CODE="0"]
|
||||
44
rt3_manual_load_winedbg.log
Normal file
44
rt3_manual_load_winedbg.log
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
Script started on 2026-04-07 18:35:01-07:00 [COMMAND="/opt/wine-stable/bin/winedbg --file /home/jan/projects/rrt/tools/winedbg_manual_load_445ac0.cmd RT3.exe" TERM="xterm-256color" TTY="/dev/pts/4" COLUMNS="116" LINES="30"]
|
||||
]0;Wine Debugger[?25lWineDbg starting on pid 00f0
|
||||
[?25h00ec:fixme:dbghelp:elf_search_auxv can't find symbol in module
|
||||
00ec:fixme:dbghelp:elf_search_auxv can't find symbol in module
|
||||
[?25lprocess_breakpoint () at /usr/src/packages/BUILD/dlls/ntdll/signal_i386.c:557
|
||||
[?25h[?25l0x0000007bd237b6 process_breakpoint+0x36 [/usr/src/packages/BUILD/dlls/ntdll/signal_i386.c:557] in ntdll: movl -0x58
|
||||
(%ebp), %eax[K
|
||||
[?25h[?25lUnable to access file '/usr/src/packages/BUILD/dlls/ntdll/signal_i386.c'
|
||||
[?25h[?25lBreakpoint 1 at 0x000000004390cb rt3+0x390cb
|
||||
[?25h[?25lBreakpoint 2 at 0x00000000445ac0 rt3+0x45ac0
|
||||
[?25h00f4:fixme:ntdll:NtQuerySystemInformation info_class SYSTEM_PERFORMANCE_INFORMATION
|
||||
libEGL warning: DRI3 error: Could not get DRI3 device
|
||||
libEGL warning: Ensure your X server supports DRI3 to get accelerated rendering
|
||||
00f4:fixme:d3d:wined3d_guess_card No card selector available for card vendor 0000 (using GL_RENDERER "llvmpipe (LLVM 19.1.7, 256 bits)").
|
||||
00f4:fixme:d3d:wined3d_guess_card No card selector available for card vendor 0000 (using GL_RENDERER "llvmpipe (LLVM 19.1.7, 256 bits)").
|
||||
[?25lThread ID=0164 not in our list of threads -> can't rename
|
||||
[?25h[?25lThread ID=0188 not in our list of threads -> can't rename
|
||||
[?25h0144:fixme:d3d:state_linepattern_w Setting line patterns is not supported in OpenGL core contexts.
|
||||
00ec:fixme:dbghelp:elf_search_auxv can't find symbol in module
|
||||
[?25lStopped on breakpoint 1 at 0x000000004390cb rt3+0x390cb
|
||||
[?25h[?25lRegister dump:
|
||||
[?25h[?25l CS:0023 SS:002b DS:002b ES:002b FS:0000 GS:002b
|
||||
EIP:004390cb ESP:0022fb30 EBP:02af5840 EFLAGS:00000206( - -- I - -P- )
|
||||
[?25h[?25l EAX:00000002 EBX:00000000 ECX:02af5840 EDX:01db4739
|
||||
[?25h[?25l ESI:00000000 EDI:00000001
|
||||
[?25h[?25l0x1db4739
|
||||
[?25h[?25l0x4
|
||||
[?25h[?25l0x22fb50
|
||||
[?25h[?25l0x26d7b88
|
||||
[?25h[?25l0x1d81230
|
||||
[?25h[?25l0x2af5840
|
||||
[?25h[?25l0
|
||||
[?25h[?25l0
|
||||
[?25h[?25l0
|
||||
[?25h[?25l0
|
||||
[?25h[?25l0
|
||||
[?25h[?25l0
|
||||
[?25h[?25l0
|
||||
[?25h[?25l0
|
||||
[?25h[?25lBacktrace:
|
||||
[?25h[?25l=>0 0x000000004390cb in rt3 (+0x390cb) (0x00000002af5840)
|
||||
[?25h[?25l 1 0x00000001072558 (0000000000000000)
|
||||
[?25h
|
||||
Script done on 2026-04-07 18:35:28-07:00 [COMMAND_EXIT_CODE="0"]
|
||||
Loading…
Add table
Add a link
Reference in a new issue