More investigation into animation
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"code.ur.gs/lupine/ordoor/internal/data"
|
||||
"code.ur.gs/lupine/ordoor/internal/fonts"
|
||||
"code.ur.gs/lupine/ordoor/internal/idx"
|
||||
"code.ur.gs/lupine/ordoor/internal/maps"
|
||||
"code.ur.gs/lupine/ordoor/internal/menus"
|
||||
"code.ur.gs/lupine/ordoor/internal/sets"
|
||||
@@ -33,13 +34,15 @@ func main() {
|
||||
loadSets()
|
||||
loadMenus()
|
||||
loadFonts()
|
||||
loadIdx()
|
||||
}
|
||||
|
||||
func loadData() {
|
||||
dataPath := filepath.Join(*gamePath, "Data")
|
||||
accountingPath := filepath.Join(dataPath, "Accounting.dat")
|
||||
genericDataPath := filepath.Join(dataPath, "GenericData.dat")
|
||||
aniObDefPath := filepath.Join(dataPath, "AniObDef.dat")
|
||||
genericDataPath := filepath.Join(dataPath, "GenericData.dat")
|
||||
hasActionPath := filepath.Join(dataPath, "HasAction.dat")
|
||||
i18nPath := filepath.Join(dataPath, data.I18nFile)
|
||||
|
||||
log.Printf("Loading %s...", accountingPath)
|
||||
@@ -73,6 +76,12 @@ func loadData() {
|
||||
}
|
||||
|
||||
log.Printf("%s: len=%v", i18nPath, i18n.Len())
|
||||
|
||||
ha, err := data.LoadHasAction(hasActionPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse %s: %v", hasActionPath, err)
|
||||
}
|
||||
ha.Print()
|
||||
}
|
||||
|
||||
func loadObj() {
|
||||
@@ -189,3 +198,11 @@ func loadFonts() {
|
||||
fmt.Printf(" * `%s`: obj=%v entries=%v\n", font.Name, font.ObjectFile, font.Entries())
|
||||
}
|
||||
}
|
||||
|
||||
func loadIdx() {
|
||||
idxPath := filepath.Join(*gamePath, "Idx", "WarHammer.idx")
|
||||
_, err := idx.Load(idxPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse %s as idx: %v", idxPath, err)
|
||||
}
|
||||
}
|
||||
|
@@ -162,6 +162,7 @@ how many type 2 records there are.
|
||||
| 0 | 2? | `02 06` - ??? |
|
||||
| 2 | 2? | `n xx` - ??? `n` counts from 1 to 8 |
|
||||
| 4 | 4 | Position of type 3 record |
|
||||
| 8 | 4 | ??? |
|
||||
|
||||
The two type 3a and 3b records are identical to each other, it's hard to know
|
||||
what's what.
|
||||
@@ -169,137 +170,219 @@ what's what.
|
||||
None of the unknown numbers, however sliced, seem to be sprite indices for
|
||||
`Anim/WarHammer.ani`.
|
||||
|
||||
Here's a trace of both `idx` (fd 34) and `ani` (fd 14) files when placing a
|
||||
single librarian for me to dig into in more detail.
|
||||
Here's a trace of both `idx` and `ani` files when placing a single librarian for
|
||||
me to dig into in more detail. No other files are touched when doing this.
|
||||
|
||||
<details>
|
||||
|
||||
```
|
||||
read(14, "~\337\2\0 \0\0\0\360\373\26\0\20\374\26\0\245J\303\30\0\0\0\0\0\0\0\0(\222R\0", 32) = 32
|
||||
_llseek(<WarHammer.idx>, 132, [132], SEEK_SET) = 0
|
||||
read(<WarHammer.idx>, "\x30\x7c\x09\x00\x98\x00\x00\x00\x88\xf8\x00\x00", 12) = 12
|
||||
|
||||
_llseek(34, 132, [132], SEEK_SET) = 0
|
||||
read(34, "0|\t\0\230\0\0\0\210\370\0\0", 12) = 12
|
||||
_llseek(<WarHammer.idx>, 132, [132], SEEK_SET) = 0
|
||||
read(<WarHammer.idx>, "\x30\x7c\x09\x00\x98\x00\x00\x00\x88\xf8\x00\x00", 12) = 12
|
||||
|
||||
_llseek(34, 132, [132], SEEK_SET) = 0
|
||||
read(34, "0|\t\0\230\0\0\0\210\370\0\0", 12) = 12
|
||||
_llseek(<WarHammer.idx>, 621616, [621616], SEEK_SET) = 0
|
||||
read(<WarHammer.idx>, "\x02\x01\x01\x33\x50\x83\x09\x00\x0d\x00\x00\x00", 12) = 12
|
||||
|
||||
_llseek(34, 621616, [621616], SEEK_SET) = 0
|
||||
read(34, "\2\1\0013P\203\t\0\r\0\0\0", 12) = 12
|
||||
_llseek(34, 621628, [621628], SEEK_SET) = 0
|
||||
read(34, "\2\1\0023\262\203\t\0\r\0\0\0", 12) = 12
|
||||
_llseek(34, 621640, [621640], SEEK_SET) = 0
|
||||
read(34, "\2\1\0033\24\204\t\0\r\0\0\0", 12) = 12
|
||||
_llseek(34, 621652, [621652], SEEK_SET) = 0
|
||||
read(34, "\2\1\0043v\204\t\0\r\0\0\0", 12) = 12
|
||||
_llseek(34, 621664, [621664], SEEK_SET) = 0
|
||||
read(34, "\2\1\0053\330\204\t\0\r\0\0\0", 12) = 12
|
||||
_llseek(<WarHammer.idx>, 621628, [621628], SEEK_SET) = 0
|
||||
read(<WarHammer.idx>, "\x02\x01\x02\x33\xb2\x83\x09\x00\x0d\x00\x00\x00", 12) = 12
|
||||
|
||||
_llseek(34, 623832, [623832], SEEK_SET) = 0
|
||||
read(34, "4\0@\0@\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0", 20) = 20
|
||||
_llseek(<WarHammer.idx>, 621640, [621640], SEEK_SET) = 0
|
||||
read(<WarHammer.idx>, "\x02\x01\x03\x33\x14\x84\x09\x00\x0d\x00\x00\x00", 12) = 12
|
||||
|
||||
_llseek(14, 509440, [509440], SEEK_SET) = 0
|
||||
read(14, "\fM\266\th\16\0\0", 8) = 8
|
||||
_llseek(14, 509448, [509448], SEEK_SET) = 0
|
||||
read(14, "t[\266\t\376\16\0\0", 8) = 8
|
||||
_llseek(14, 509456, [509456], SEEK_SET) = 0
|
||||
read(14, "rj\266\tg\17\0\0", 8) = 8
|
||||
_llseek(14, 509464, [509464], SEEK_SET) = 0
|
||||
read(14, "\331y\266\t\251\17\0\0", 8) = 8
|
||||
_llseek(14, 509472, [509472], SEEK_SET) = 0
|
||||
read(14, "\202\211\266\t\273\17\0\0", 8) = 8
|
||||
_llseek(14, 509480, [509480], SEEK_SET) = 0
|
||||
read(14, "=\231\266\t\10\20\0\0", 8) = 8
|
||||
_llseek(14, 509488, [509488], SEEK_SET) = 0
|
||||
read(14, "E\251\266\t\321\17\0\0", 8) = 8
|
||||
_llseek(14, 509496, [509496], SEEK_SET) = 0
|
||||
read(14, "\26\271\266\t\1\17\0\0", 8) = 8
|
||||
_llseek(14, 509504, [509504], SEEK_SET) = 0
|
||||
read(14, "\27\310\266\t\304\16\0\0", 8) = 8
|
||||
_llseek(14, 509512, [509512], SEEK_SET) = 0
|
||||
read(14, "\333\326\266\t\343\16\0\0", 8) = 8
|
||||
_llseek(14, 509520, [509520], SEEK_SET) = 0
|
||||
read(14, "\276\345\266\t\f\17\0\0", 8) = 8
|
||||
_llseek(14, 509528, [509528], SEEK_SET) = 0
|
||||
read(14, "\312\364\266\tA\17\0\0", 8) = 8
|
||||
_llseek(14, 509536, [509536], SEEK_SET) = 0
|
||||
read(14, "\v\4\267\t\246\17\0\0", 8) = 8
|
||||
_llseek(14, 509440, [509440], SEEK_SET) = 0
|
||||
read(14, "\fM\266\th\16\0\0", 8) = 8
|
||||
_llseek(<WarHammer.idx>, 621652, [621652], SEEK_SET) = 0
|
||||
read(<WarHammer.idx>, "\x02\x01\x04\x33\x76\x84\x09\x00\x0d\x00\x00\x00", 12) = 12
|
||||
|
||||
_llseek(14, 164448540, [164448540], SEEK_SET) = 0
|
||||
read(14, "\367\0\n\0015\0T\0\0\0\0\0P\16\0\0\324q;\1\0\0\0\0\200\23\207**+*+"..., 3688) = 3688
|
||||
_llseek(14, 509448, [509448], SEEK_SET) = 0
|
||||
read(14, "t[\266\t\376\16\0\0", 8) = 8
|
||||
_llseek(14, 164452228, [164452228], SEEK_SET) = 0
|
||||
read(14, "\365\0\10\0017\0W\0\0\0\0\0\346\16\0\0\324q;\1\0\0\0\0\200\25\3*\212+*,"..., 3838) = 3838
|
||||
_llseek(14, 509456, [509456], SEEK_SET) = 0
|
||||
read(14, "rj\266\tg\17\0\0", 8) = 8
|
||||
_llseek(14, 164456066, [164456066], SEEK_SET) = 0
|
||||
read(14, "\364\0\10\19\0Z\0\0\0\0\0O\17\0\0\324q;\1\0\0\0\0\200\30\201*\5+\200\33"..., 3943) = 3943
|
||||
_llseek(14, 509464, [509464], SEEK_SET) = 0
|
||||
read(14, "\331y\266\t\251\17\0\0", 8) = 8
|
||||
_llseek(14, 164460009, [164460009], SEEK_SET) = 0
|
||||
read(14, "\356\0\7\1B\0[\0\0\0\0\0\221\17\0\0\324q;\1\0\0\0\0\200\"\201*\200\37\0\200"..., 4009) = 4009
|
||||
_llseek(14, 509472, [509472], SEEK_SET) = 0
|
||||
read(14, "\202\211\266\t\273\17\0\0", 8) = 8
|
||||
_llseek(14, 164464018, [164464018], SEEK_SET) = 0
|
||||
read(14, "\356\0\n\1C\0\\\0\0\0\0\0\243\17\0\0\324q;\1\0\0\0\0\200#\3)\3+\200\32"..., 4027) = 4027
|
||||
_llseek(14, 509480, [509480], SEEK_SET) = 0
|
||||
read(14, "=\231\266\t\10\20\0\0", 8) = 8
|
||||
_llseek(14, 164468045, [164468045], SEEK_SET) = 0
|
||||
read(14, "\354\0\t\1C\0Z\0\0\0\0\0\360\17\0\0\324q;\1\0\0\0\0\200$\201*\200\36\0\200"..., 4104) = 4104
|
||||
_llseek(14, 509488, [509488], SEEK_SET) = 0
|
||||
read(14, "E\251\266\t\321\17\0\0", 8) = 8
|
||||
_llseek(14, 164472149, [164472149], SEEK_SET) = 0
|
||||
read(14, "\356\0\t\1?\0V\0\0\0\0\0\271\17\0\0\324q;\1\0\0\0\0\200\35\212&&H)*"..., 4049) = 4049
|
||||
_llseek(14, 509496, [509496], SEEK_SET) = 0
|
||||
read(14, "\26\271\266\t\1\17\0\0", 8) = 8
|
||||
_llseek(14, 164476198, [164476198], SEEK_SET) = 0
|
||||
read(14, "\366\0\10\0015\0[\0\0\0\0\0\351\16\0\0\324q;\1\0\0\0\0\200\20\201*\4+\206*"..., 3841) = 3841
|
||||
_llseek(14, 509504, [509504], SEEK_SET) = 0
|
||||
read(14, "\27\310\266\t\304\16\0\0", 8) = 8
|
||||
_llseek(14, 164480039, [164480039], SEEK_SET) = 0
|
||||
read(14, "\367\0\7\0013\0[\0\0\0\0\0\254\16\0\0\324q;\1\0\0\0\0\200\33\210+,+,,"..., 3780) = 3780
|
||||
_llseek(14, 509512, [509512], SEEK_SET) = 0
|
||||
read(14, "\333\326\266\t\343\16\0\0", 8) = 8
|
||||
_llseek(14, 164483819, [164483819], SEEK_SET) = 0
|
||||
read(14, "\370\0\7\1A\0_\0\0\0\0\0\313\16\0\0\324q;\1\0\0\0\0\200\34\203,,*\200\""..., 3811) = 3811
|
||||
_llseek(14, 509520, [509520], SEEK_SET) = 0
|
||||
read(14, "\276\345\266\t\f\17\0\0", 8) = 8
|
||||
_llseek(14, 164487630, [164487630], SEEK_SET) = 0
|
||||
read(14, "\370\0\7\1H\0`\0\0\0\0\0\364\16\0\0\324q;\1\0\0\0\0\200\35\201,\200*\0\200"..., 3852) = 3852
|
||||
_llseek(14, 509528, [509528], SEEK_SET) = 0
|
||||
read(14, "\312\364\266\tA\17\0\0", 8) = 8
|
||||
_llseek(14, 164491482, [164491482], SEEK_SET) = 0
|
||||
read(14, "\373\0\10\1;\0Z\0\0\0\0\0)\17\0\0\324q;\1\0\0\0\0\200\36\202+,\200\33\0"..., 3905) = 3905
|
||||
_llseek(14, 509536, [509536], SEEK_SET) = 0
|
||||
read(14, "\v\4\267\t\246\17\0\0", 8) = 8
|
||||
_llseek(14, 164495387, [164495387], SEEK_SET) = 0
|
||||
read(14, "\366\0\n\18\0Y\0\0\0\0\0\216\17\0\0\324q;\1\0\0\0\0\200\32\t+\205*\4,"..., 4006) = 4006
|
||||
_llseek(<WarHammer.idx>, 621664, [621664], SEEK_SET) = 0
|
||||
read(<WarHammer.idx>, "\x02\x01\x05\x33\xd8\x84\x09\x00\x0d\x00\x00\x00", 12) = 12
|
||||
|
||||
_llseek(34, 623832, [623832], SEEK_SET) = 0
|
||||
read(34, "4\0@\0@\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0", 20) = 20
|
||||
read(34, "\0\0\6\0\4\0\0\0\6\0\4\0\0\0\6\0\4\0\0\0\5\0\4\0\0\0\5\0\4\0\0\0"..., 78) = 78
|
||||
_llseek(<WarHammer.idx>, 623832, [623832], SEEK_SET) = 0
|
||||
read(<WarHammer.idx>, "\x34\x00\x40\x00\x40\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 20) = 20
|
||||
|
||||
_llseek(34, 132, [132], SEEK_SET) = 0
|
||||
read(34, "0|\t\0\230\0\0\0\210\370\0\0", 12) = 12
|
||||
_llseek(<WarHammer.idx>, 0, [623852], SEEK_CUR) = 0
|
||||
_llseek(<WarHammer.idx>, 623852, [623852], SEEK_SET) = 0
|
||||
_llseek(<WarHammer.idx>, 623930, [623930], SEEK_SET) = 0
|
||||
|
||||
_llseek(34, 621616, [621616], SEEK_SET) = 0
|
||||
read(34, "\2\1\0013P\203\t\0\r\0\0\0", 12) = 12
|
||||
_llseek(34, 621628, [621628], SEEK_SET) = 0
|
||||
read(34, "\2\1\0023\262\203\t\0\r\0\0\0", 12) = 12
|
||||
_llseek(34, 621640, [621640], SEEK_SET) = 0
|
||||
read(34, "\2\1\0033\24\204\t\0\r\0\0\0", 12) = 12
|
||||
_llseek(34, 621652, [621652], SEEK_SET) = 0
|
||||
read(34, "\2\1\0043v\204\t\0\r\0\0\0", 12) = 12
|
||||
_llseek(34, 621664, [621664], SEEK_SET) = 0
|
||||
read(34, "\2\1\0053\330\204\t\0\r\0\0\0", 12) = 12
|
||||
_llseek(<WarHammer.ani>, 509440, [509440], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x0c\x4d\xb6\x09\x68\x0e\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509448, [509448], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x74\x5b\xb6\x09\xfe\x0e\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509456, [509456], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x72\x6a\xb6\x09\x67\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509464, [509464], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xd9\x79\xb6\x09\xa9\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509472, [509472], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x82\x89\xb6\x09\xbb\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509480, [509480], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x3d\x99\xb6\x09\x08\x10\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509488, [509488], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x45\xa9\xb6\x09\xd1\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509496, [509496], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x16\xb9\xb6\x09\x01\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509504, [509504], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x17\xc8\xb6\x09\xc4\x0e\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509512, [509512], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xdb\xd6\xb6\x09\xe3\x0e\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509520, [509520], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xbe\xe5\xb6\x09\x0c\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509528, [509528], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xca\xf4\xb6\x09\x41\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509536, [509536], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x0b\x04\xb7\x09\xa6\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 509440, [509440], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x0c\x4d\xb6\x09\x68\x0e\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 164448540, [164448540], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xf7\x00\x0a\x01\x35\x00\x54\x00\x00\x00\x00\x00\x50\x0e\x00\x00\xd4\x71\x3b\x01\x00\x00\x00\x00\x80\x13\x87\x2a\x2a\x2b\x2a\x2b"..., 3688) = 3688
|
||||
|
||||
_llseek(<WarHammer.ani>, 509448, [509448], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x74\x5b\xb6\x09\xfe\x0e\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 164452228, [164452228], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xf5\x00\x08\x01\x37\x00\x57\x00\x00\x00\x00\x00\xe6\x0e\x00\x00\xd4\x71\x3b\x01\x00\x00\x00\x00\x80\x15\x03\x2a\x8a\x2b\x2a\x2c"..., 3838) = 3838
|
||||
|
||||
_llseek(<WarHammer.ani>, 509456, [509456], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x72\x6a\xb6\x09\x67\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 164456066, [164456066], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xf4\x00\x08\x01\x39\x00\x5a\x00\x00\x00\x00\x00\x4f\x0f\x00\x00\xd4\x71\x3b\x01\x00\x00\x00\x00\x80\x18\x81\x2a\x05\x2b\x80\x1b"..., 3943) = 3943
|
||||
|
||||
_llseek(<WarHammer.ani>, 509464, [509464], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xd9\x79\xb6\x09\xa9\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 164460009, [164460009], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xee\x00\x07\x01\x42\x00\x5b\x00\x00\x00\x00\x00\x91\x0f\x00\x00\xd4\x71\x3b\x01\x00\x00\x00\x00\x80\x22\x81\x2a\x80\x1f\x00\x80"..., 4009) = 4009
|
||||
|
||||
_llseek(<WarHammer.ani>, 509472, [509472], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x82\x89\xb6\x09\xbb\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 164464018, [164464018], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xee\x00\x0a\x01\x43\x00\x5c\x00\x00\x00\x00\x00\xa3\x0f\x00\x00\xd4\x71\x3b\x01\x00\x00\x00\x00\x80\x23\x03\x29\x03\x2b\x80\x1a"..., 4027) = 4027
|
||||
|
||||
_llseek(<WarHammer.ani>, 509480, [509480], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x3d\x99\xb6\x09\x08\x10\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 164468045, [164468045], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xec\x00\x09\x01\x43\x00\x5a\x00\x00\x00\x00\x00\xf0\x0f\x00\x00\xd4\x71\x3b\x01\x00\x00\x00\x00\x80\x24\x81\x2a\x80\x1e\x00\x80"..., 4104) = 4104
|
||||
|
||||
_llseek(<WarHammer.ani>, 509488, [509488], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x45\xa9\xb6\x09\xd1\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 164472149, [164472149], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xee\x00\x09\x01\x3f\x00\x56\x00\x00\x00\x00\x00\xb9\x0f\x00\x00\xd4\x71\x3b\x01\x00\x00\x00\x00\x80\x1d\x8a\x26\x26\x48\x29\x2a"..., 4049) = 4049
|
||||
|
||||
_llseek(<WarHammer.ani>, 509496, [509496], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x16\xb9\xb6\x09\x01\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 164476198, [164476198], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xf6\x00\x08\x01\x35\x00\x5b\x00\x00\x00\x00\x00\xe9\x0e\x00\x00\xd4\x71\x3b\x01\x00\x00\x00\x00\x80\x10\x81\x2a\x04\x2b\x86\x2a"..., 3841) = 3841
|
||||
|
||||
_llseek(<WarHammer.ani>, 509504, [509504], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\x17\xc8\xb6\x09\xc4\x0e\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 164480039, [164480039], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xf7\x00\x07\x01\x33\x00\x5b\x00\x00\x00\x00\x00\xac\x0e\x00\x00\xd4\x71\x3b\x01\x00\x00\x00\x00\x80\x1b\x88\x2b\x2c\x2b\x2c\x2c"..., 3780) = 3780
|
||||
|
||||
_llseek(<WarHammer.ani>, 509512, [509512], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xdb\xd6\xb6\x09\xe3\x0e\x00\x00", 8) = 8
|
||||
|
||||
_llseek(<WarHammer.ani>, 164483819, [164483819], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xf8\x00\x07\x01\x41\x00\x5f\x00\x00\x00\x00\x00\xcb\x0e\x00\x00\xd4\x71\x3b\x01\x00\x00\x00\x00\x80\x1c\x83\x2c\x2c\x2a\x80\x22"..., 3811) = 3811
|
||||
|
||||
_llseek(<WarHammer.ani>, 509520, [509520], SEEK_SET) = 0
|
||||
read(<WarHammer.ani>, "\xbe\xe5\xb6\x09\x0c\x0f\x00\x00", 8) = 8
|
||||
|
||||
_llseek(34, 623832, [623832], SEEK_SET) = 0
|
||||
read(34, "4\0@\0@\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0", 20) = 20
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Notable is that we still load 5 type 2 records, even though there's just a
|
||||
single librarian, and 8 compass points. Why 5?
|
||||
Notable is that we still load 5 type 2 records, even though there's just a
|
||||
single librarian, and 8 compass points. Why 5?
|
||||
|
||||
Also notable is that we read from `idx` **before** we read from `ani`.
|
||||
|
||||
Other data may be loaded at program start, of course. What other files seem
|
||||
relevant?
|
||||
|
||||
* `Data/AniObDef.dat`
|
||||
* `Data/HasAction.dat`
|
||||
* `Data/VehicDef.dat`
|
||||
* `Data/WeapDef.dat`
|
||||
|
||||
These all reference animations in one way or another.
|
||||
|
||||
## `HasAction.dat`
|
||||
|
||||
This file seems relevant as it says whether or not particular animations exist
|
||||
for the different types of character, which maps directly to what is stored in
|
||||
the .ani file - and so must affect lookups thereof.
|
||||
|
||||
Fortunately, it's commented extensively. For each "Character Type", there are
|
||||
36 different possible animations.
|
||||
|
||||
Here's a table representation of the data:
|
||||
|
||||
```
|
||||
Tac Ass Dev Term Apo Tech Chp Lib Cpt CMar CLrd CChp CSrc CTrm Kbz BTh BL FHnd LoC Flm PHr BHr Cult
|
||||
00 x x x x x x x x x x x x x x x x x x x x x x x
|
||||
01 x x x x x x x x x x x x x x x x x x x x x x x
|
||||
02 x x x x x x x x x x x x x x x x x x x x x x x
|
||||
03
|
||||
04
|
||||
05
|
||||
06 x x x x x x x x x x x x x x x x x x x x
|
||||
07 x x x x x x x x x x x x x x x x x x x x x x x
|
||||
08 x x x x x x x x x x x x x x x x
|
||||
09
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14 x x x x x x x x x x x x x
|
||||
15 x x x x x x x x x x x x x
|
||||
16 x x x x x x x x x x x x x
|
||||
17 x x x x x x x x x x x x x
|
||||
18 x x x x x x x x x x x x x
|
||||
19 x x x x x x x x x x x x x
|
||||
20 x x x x x x x x x x x x x
|
||||
21 x x x x x x x x x x x x x
|
||||
22 x x x x x x x x x x x x x x
|
||||
23 x x x x x x x x x x x x x
|
||||
24 x x x x x x x x x x x x x x x x
|
||||
25 x x x x x x x x x x x x x x x x x x x x x x
|
||||
26 x x x x x x x x x x x x x x x x x
|
||||
27 x x x x x x x x x x x x x x x x x x x x x
|
||||
28 x x x x x x x x x x x x x x
|
||||
29 x x x
|
||||
30 x
|
||||
31 x
|
||||
32 x x x
|
||||
33 x x x x x x x x x x x x x x x x x x x x x
|
||||
34 x x x x x x x x x x x x x x x x x x x x x x x
|
||||
35 x x x x x x x
|
||||
```
|
||||
|
||||
`WarHammer.ani` doesn't have blank sprites for the unchecked cells, so this must
|
||||
surely be used to map between set-of-sprites and `AnimAction`.
|
||||
|
||||
I think we still need the data in `.idx` for a full picture, though. Things we
|
||||
still need:
|
||||
|
||||
* Mapping of character type to sprite directory index in `WarHammer.ani`
|
||||
* Number of frames in each AnimAction
|
||||
|
||||
Either of these could be hardcoded, or dynamic.
|
||||
|
@@ -17,14 +17,15 @@ remake.
|
||||
* `*.dat` # plaintext files defining properties of objects. No single format
|
||||
* **PARSED**
|
||||
* `Accounting.dat` # key = value => internal/data/accounting.go
|
||||
* [`AniObjDef.dat`](ani.mnu) # animated object definitions
|
||||
* `AniObjDef.dat` # animated object definitions
|
||||
* `GenericData.dat` # Generic Game Settings
|
||||
* [`HasAction.dat`](ani.md) # "Are there animation for each of the character" - list of booleans
|
||||
* **TODO**
|
||||
* `ChaNames.dat` # list of character names
|
||||
* `Coordinates.dat` # Weapon Firing Coordinates
|
||||
* `Defs.dat` # defines properties for objects and tiles, each of which seems to have an id
|
||||
* `GDestroy.dat` # table of what destroys what?
|
||||
* `HasAction.dat` # "Are there animation for each of the character" - list of booleans
|
||||
|
||||
* `MiniMap.dat` # lots of seemingly random numbers. IDs?
|
||||
* `MissionBriefing.dat` # Contains all Campaign Mission Briefing Text. Sections: "CAMPAIGN MISSION X ... END CAMPAIGN MISSION X"
|
||||
* `PWeight.dat` # Personality weights for the individual character types
|
||||
@@ -75,8 +76,9 @@ remake.
|
||||
* [`MultiMaps/`](maps.md#multimaps)
|
||||
* [`*.MAP`](maps.md)
|
||||
* [`*.TXT`](maps.md)
|
||||
* [✓] [`Obj/`](obj.md)
|
||||
* [`*.obj`](obj.md)
|
||||
* [`Obj/`](obj.md)
|
||||
* [ ] `cpiece.rec` # "Rects for various cursor piece types..."
|
||||
* [✓] [`*.obj`](obj.md)
|
||||
* [✓] `Pic/`
|
||||
* `*.pcx` # Standard .pcx format
|
||||
* `RandomMaps/`
|
||||
|
1
go.mod
1
go.mod
@@ -4,6 +4,7 @@ go 1.12
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/emef/bitfield v0.0.0-20170503144143-7d3f8f823065
|
||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.2.0.20200101150127-38815ba801a5
|
||||
github.com/jfreymuth/oggvorbis v1.0.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
|
2
go.sum
2
go.sum
@@ -3,6 +3,8 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/emef/bitfield v0.0.0-20170503144143-7d3f8f823065 h1:7QVNyw2v9R1qOvbe9vfeVJWWKCSnd2Ap+8l8/CtG9LM=
|
||||
github.com/emef/bitfield v0.0.0-20170503144143-7d3f8f823065/go.mod h1:uN4GbWHfit2ByfOKQ4K6fuLy1/Os2eLynsIrDvjiDgM=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72 h1:b+9H1GAsx5RsjvDFLoS5zkNBzIQMuVKUYQDmxU3N5XE=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I=
|
||||
|
178
internal/data/has_action.go
Normal file
178
internal/data/has_action.go
Normal file
@@ -0,0 +1,178 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/emef/bitfield"
|
||||
|
||||
"code.ur.gs/lupine/ordoor/internal/util/asciiscan"
|
||||
)
|
||||
|
||||
// AnimAction represents an animation that is stored in WarHammer.ani
|
||||
type AnimAction int
|
||||
|
||||
// CharacterType represents one of the different types of character in the game.
|
||||
//
|
||||
// TODO: can we load the list of character types anywhere or is it hardcoded in
|
||||
// the original too?
|
||||
type CharacterType int
|
||||
|
||||
const (
|
||||
AnimActionNone AnimAction = 0
|
||||
AnimActionAnim AnimAction = 1
|
||||
AnimActionWalk AnimAction = 2
|
||||
AnimActionExplosion AnimAction = 3
|
||||
AnimActionProjectile AnimAction = 4
|
||||
AnimActionSmoke AnimAction = 5
|
||||
AnimActionStandingShoot AnimAction = 6
|
||||
AnimActionStandingDeath AnimAction = 7
|
||||
AnimActionPain AnimAction = 8
|
||||
AnimActionSpellFx1 AnimAction = 9
|
||||
AnimActionSpellFx2 AnimAction = 10
|
||||
AnimActionSpellFx3 AnimAction = 11
|
||||
AnimActionSpellFx4 AnimAction = 12
|
||||
AnimActionSpellFx5 AnimAction = 13
|
||||
AnimActionRun AnimAction = 14
|
||||
AnimActionCrouch AnimAction = 15
|
||||
AnimActionStand AnimAction = 16
|
||||
AnimActionStandingRead AnimAction = 17
|
||||
AnimActionStandingUnready AnimAction = 18
|
||||
AnimActionCrouchingReady AnimAction = 19
|
||||
AnimActionCrouchingUnready AnimAction = 20
|
||||
AnimActionCrouchingShoot AnimAction = 21
|
||||
AnimActionStandingGrenade AnimAction = 22
|
||||
AnimActionCrouchingGrenade AnimAction = 23
|
||||
AnimActionDrawMelee AnimAction = 24
|
||||
AnimActionSlash AnimAction = 25
|
||||
AnimActionStab AnimAction = 26
|
||||
AnimActionBlown AnimAction = 27
|
||||
AnimActionCrouchingDeath AnimAction = 28
|
||||
AnimActionJump AnimAction = 29
|
||||
AnimActionHeal AnimAction = 30
|
||||
AnimActionTechWork AnimAction = 31
|
||||
AnimActionCast AnimAction = 32
|
||||
AnimActionShoot AnimAction = 33
|
||||
AnimActionDeath AnimAction = 34
|
||||
AnimActionFromWarp AnimAction = 35
|
||||
|
||||
AnimActionStart = AnimActionNone
|
||||
AnimActionEnd = AnimActionFromWarp
|
||||
AnimActionCount = AnimActionEnd - AnimActionStart + 1
|
||||
|
||||
// FIXME: indexed from 1, very annoying
|
||||
CharacterTypeTactical CharacterType = 1
|
||||
CharacterTypeAssault CharacterType = 2
|
||||
CharacterTypeDevastator CharacterType = 3
|
||||
CharacterTypeTerminator CharacterType = 4
|
||||
CharacterTypeApothecary CharacterType = 5
|
||||
CharacterTypeTechmarine CharacterType = 6
|
||||
CharacterTypeChaplain CharacterType = 7
|
||||
CharacterTypeLibrarian CharacterType = 8
|
||||
CharacterTypeCaptain CharacterType = 9
|
||||
CharacterTypeChaosMarine CharacterType = 10
|
||||
CharacterTypeChaosLord CharacterType = 11
|
||||
CharacterTypeChaosChaplain CharacterType = 12
|
||||
CharacterTypeChaosSorcerer CharacterType = 13
|
||||
CharacterTypeChaosTerminator CharacterType = 14
|
||||
CharacterTypeKhorneBerserker CharacterType = 15
|
||||
CharacterTypeBloodThirster CharacterType = 16
|
||||
CharacterTypeBloodLetter CharacterType = 17
|
||||
CharacterTypeFleshHound CharacterType = 18
|
||||
CharacterTypeLordOfChange CharacterType = 19
|
||||
CharacterTypeFlamer CharacterType = 20
|
||||
CharacterTypePinkHorror CharacterType = 21
|
||||
CharacterTypeBlueHorror CharacterType = 22
|
||||
CharacterTypeChaosCultist CharacterType = 23
|
||||
|
||||
CharacterTypeStart = CharacterTypeTactical
|
||||
CharacterTypeEnd = CharacterTypeChaosCultist
|
||||
CharacterTypeCount = CharacterTypeEnd - CharacterTypeStart + 1
|
||||
)
|
||||
|
||||
// HasAction tells us whether a character has an animation or not.
|
||||
type HasAction struct {
|
||||
bits bitfield.BitField
|
||||
}
|
||||
|
||||
func LoadHasAction(filename string) (*HasAction, error) {
|
||||
scanner, err := asciiscan.New(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer scanner.Close()
|
||||
|
||||
out := &HasAction{
|
||||
bits: bitfield.New(int(CharacterTypeCount) * int(AnimActionCount)),
|
||||
}
|
||||
|
||||
// Reuse this for every loop
|
||||
var actions [AnimActionCount]bool
|
||||
ptrs := make([]*bool, len(actions))
|
||||
for i, _ := range actions {
|
||||
ptrs[i] = &actions[i]
|
||||
}
|
||||
|
||||
for c := CharacterTypeStart; c <= CharacterTypeEnd; c++ {
|
||||
if err := scanner.ConsumeBoolPtrs(ptrs...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for j, value := range actions {
|
||||
a := AnimActionStart + AnimAction(j)
|
||||
|
||||
out.set(c, a, value)
|
||||
}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (h *HasAction) Check(c CharacterType, a AnimAction) bool {
|
||||
return h.bits.Test(h.offset(c, a))
|
||||
}
|
||||
|
||||
func (h *HasAction) offset(c CharacterType, a AnimAction) uint32 {
|
||||
// Best to view this as a 2D array with CharacterTypeCount * AnimActionCount elements
|
||||
i := uint32(c - CharacterTypeStart)
|
||||
j := uint32(a - AnimActionStart)
|
||||
|
||||
return (i * uint32(AnimActionCount)) + j
|
||||
}
|
||||
|
||||
func (h *HasAction) set(c CharacterType, a AnimAction, value bool) {
|
||||
if value {
|
||||
h.bits.Set(h.offset(c, a))
|
||||
} else {
|
||||
h.bits.Clear(h.offset(c, a))
|
||||
}
|
||||
}
|
||||
|
||||
// Actions returns the list of animations that a character type has
|
||||
func (h *HasAction) Actions(c CharacterType) []AnimAction {
|
||||
var out []AnimAction
|
||||
|
||||
for j := AnimActionStart; j < AnimActionCount; j++ {
|
||||
if h.Check(c, j) {
|
||||
out = append(out, j)
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (h *HasAction) Print() {
|
||||
fmt.Println(" Tac Ass Dev Term Apo Tech Chp Lib Cpt CMar CLrd CChp CSrc CTrm Kbz BTh BL FHnd LoC Flm PHr BHr Cult")
|
||||
for a := AnimActionStart; a <= AnimActionEnd; a++ {
|
||||
fmt.Printf("%.2d", int(a))
|
||||
for c := CharacterTypeStart; c <= CharacterTypeEnd; c++ {
|
||||
if h.Check(c, a) {
|
||||
fmt.Print(" x ")
|
||||
} else {
|
||||
fmt.Print(" ")
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("")
|
||||
}
|
||||
}
|
73
internal/idx/idx.go
Normal file
73
internal/idx/idx.go
Normal file
@@ -0,0 +1,73 @@
|
||||
// package idx parses the Idx/WarHammer.idx file.
|
||||
//
|
||||
// No, I don't know what it's for yet.
|
||||
package idx
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
//"fmt"
|
||||
"log"
|
||||
"os"
|
||||
//"strings"
|
||||
)
|
||||
|
||||
type Type1Record struct {
|
||||
Offset1 uint32 // Where the type2 for this type1 is to be found
|
||||
Unknown1 uint32 // ???
|
||||
Offset2 uint32 // Another offset? But what to?
|
||||
}
|
||||
|
||||
type Type2Record struct {
|
||||
Unknown1 [4]byte // ???
|
||||
Offset uint32 // Where the type3 for this type2 is to be found
|
||||
Unknown2 [4]byte // ??
|
||||
}
|
||||
|
||||
type Type3Record struct {
|
||||
First20 [20]byte
|
||||
Last78 [78]byte
|
||||
}
|
||||
|
||||
type Idx struct {
|
||||
Filename string
|
||||
|
||||
Type1Records [512]Type1Record // Experimentally, there seem to be 512 of these
|
||||
Type2Records []Type2Record
|
||||
Type3Records []Type3Record
|
||||
}
|
||||
|
||||
func Load(filename string) (*Idx, error) {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
out := &Idx{Filename: filename}
|
||||
|
||||
if err := binary.Read(f, binary.LittleEndian, &out.Type1Records); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, rec := range out.Type1Records {
|
||||
var off1diff uint32
|
||||
var off2diff uint32
|
||||
|
||||
if i > 0 && rec.Offset1 > 0 {
|
||||
lastRec := out.Type1Records[i-1]
|
||||
off1diff = rec.Offset1 - lastRec.Offset1
|
||||
off2diff = rec.Offset2 - lastRec.Offset2
|
||||
}
|
||||
|
||||
log.Printf(
|
||||
"%.3d: 0x%.6x diff=%.6d %.4d 0x%.6x diff=%.6d",
|
||||
i, rec.Offset1, off1diff, rec.Unknown1, rec.Offset2, off2diff,
|
||||
// i,
|
||||
// rec.Unknown1[0], rec.Unknown1[1], rec.Unknown1[2], rec.Unknown1[3],
|
||||
// rec.Unknown1[4], rec.Unknown1[5], rec.Unknown1[6], rec.Unknown1[7],
|
||||
)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
@@ -201,12 +201,18 @@ func loadProperties(menu *Menu, scanner *asciiscan.Scanner) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// DeBrief.mnu misspells these
|
||||
parts := strings.SplitN(strings.ToUpper(k), " ", 3)
|
||||
if len(parts) > 2 {
|
||||
k = strings.Join(parts[0:2], " ")
|
||||
}
|
||||
|
||||
switch strings.ToUpper(k) {
|
||||
case "BACKGROUND COLOR 0..255..-1 TRANS":
|
||||
case "BACKGROUND COLOR":
|
||||
menu.BackgroundColor = data.ColorPalette[vInt]
|
||||
case "HYPERTEXT COLOR 0..255":
|
||||
case "HYPERTEXT COLOR":
|
||||
menu.HypertextColor = data.ColorPalette[vInt]
|
||||
case "FONT TYPE 0..5":
|
||||
case "FONT TYPE":
|
||||
menu.FontType = vInt
|
||||
default:
|
||||
return fmt.Errorf("Unhandled menu property in %v: %q=%q", menu.Name, k, v)
|
||||
|
@@ -123,6 +123,15 @@ func (s *Scanner) ConsumeInt() (int, error) {
|
||||
return strconv.Atoi(str)
|
||||
}
|
||||
|
||||
func (s *Scanner) ConsumeBool() (bool, error) {
|
||||
integer, err := s.ConsumeInt()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return (integer > 0), nil
|
||||
}
|
||||
|
||||
// Reads a list of non-property lines, skipping any that match the given strings
|
||||
func (s *Scanner) ConsumeStringList(skip ...string) ([]string, error) {
|
||||
skipper := make(map[string]bool, len(skip))
|
||||
@@ -166,6 +175,16 @@ func (s *Scanner) ConsumeIntPtr(to *int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Scanner) ConsumeBoolPtr(to *bool) error {
|
||||
val, err := s.ConsumeBool()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*to = val
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Scanner) ConsumeIntPtrs(ptrs ...*int) error {
|
||||
for _, ptr := range ptrs {
|
||||
if err := s.ConsumeIntPtr(ptr); err != nil {
|
||||
@@ -175,3 +194,13 @@ func (s *Scanner) ConsumeIntPtrs(ptrs ...*int) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Scanner) ConsumeBoolPtrs(ptrs ...*bool) error {
|
||||
for _, ptr := range ptrs {
|
||||
if err := s.ConsumeBoolPtr(ptr); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user