Skip to content

Commit af980cb

Browse files
Refactor how IFF chunks work to let the user to selectively decide which chunks are decoded and what decoder they want to use
1 parent 3046a2d commit af980cb

File tree

18 files changed

+327
-285
lines changed

18 files changed

+327
-285
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Another good example is the `:floormaker-common` and `:floormaker-cli` modules.
2727
| `SPR#` | Partial | Partial | The decoder does not support big endian sprites. The encoder is not optimized yet, does not support transparent pixels mixed with non-transparent pixels in the same row.
2828
| `SPR2` | Partial | Partial | The decoder and encoder still needs to be tested more because it has only been tested with floors, but all channels are able to be extracted and reencoded correctly.
2929

30-
Unsupported IFF chunks are parsed as `UnknownChunk` and are written to the IFF file as-is.
30+
By the default the IFF reader does not attempt to decode any of the chunk data, you can decode them by calling `chunk.decodeAs[ChunkName]()` (example: `decodeAsSPR2()`), this way you can selectively choose which chunks you want to read and edit and which ones you want to keep as-is.
3131

3232
### Important Things to Note
3333

floormaker-common/src/commonMain/kotlin/net/sneakysims/floormaker/FloorMaker.kt

Lines changed: 63 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,30 @@ object FloorMaker {
1414
): IFF {
1515
val iff = IFF.empty()
1616

17-
iff.chunks.add(
18-
IFFChunk(
19-
IFFChunk.STR_CHUNK_CODE,
20-
0,
21-
// Why does it need to be 16?
22-
// IFF Pencil, and the game, only works if this is 16
23-
16,
24-
ByteArray(64),
25-
STRChunkData(
26-
STRChunkData.StringFormat.StringFormatFDFF(
27-
mutableListOf(
28-
STRChunkData.StringFormat.StringFormatFDFF.SimsString(
29-
net.sneakysims.sneakylib.sims.TheSimsLanguage.getLanguageById(1),
30-
name ?: "",
31-
"!"
32-
),
33-
STRChunkData.StringFormat.StringFormatFDFF.SimsString(
34-
net.sneakysims.sneakylib.sims.TheSimsLanguage.getLanguageById(1),
35-
(price ?: 1).toString(),
36-
"!"
37-
),
38-
STRChunkData.StringFormat.StringFormatFDFF.SimsString(
39-
net.sneakysims.sneakylib.sims.TheSimsLanguage.getLanguageById(1),
40-
description ?: "",
41-
"!"
42-
)
17+
iff.addChunk(
18+
IFFChunk.STR_CHUNK_CODE,
19+
0,
20+
// Why does it need to be 16?
21+
// IFF Pencil, and the game, only works if this is 16
22+
16,
23+
null,
24+
STRChunkData(
25+
STRChunkData.StringFormat.StringFormatFDFF(
26+
mutableListOf(
27+
STRChunkData.StringFormat.StringFormatFDFF.SimsString(
28+
net.sneakysims.sneakylib.sims.TheSimsLanguage.getLanguageById(1),
29+
name,
30+
"!"
31+
),
32+
STRChunkData.StringFormat.StringFormatFDFF.SimsString(
33+
net.sneakysims.sneakylib.sims.TheSimsLanguage.getLanguageById(1),
34+
price.toString(),
35+
"!"
36+
),
37+
STRChunkData.StringFormat.StringFormatFDFF.SimsString(
38+
net.sneakysims.sneakylib.sims.TheSimsLanguage.getLanguageById(1),
39+
description,
40+
"!"
4341
)
4442
)
4543
)
@@ -48,65 +46,57 @@ object FloorMaker {
4846

4947
val colors = PaletteCreator.extractColors(sprite)
5048

51-
iff.chunks.add(
52-
IFFChunk(
53-
IFFChunk.PALT_CHUNK_CODE,
54-
1537,
49+
iff.addChunk(
50+
IFFChunk.PALT_CHUNK_CODE,
51+
1537,
52+
0,
53+
null,
54+
PALTChunkData(
55+
1,
5556
0,
56-
ByteArray(64),
57-
PALTChunkData(
58-
1,
59-
0,
60-
0,
61-
palette.map { Color(it.red, it.green, it.blue) }
62-
)
57+
0,
58+
palette.map { Color(it.red, it.green, it.blue) }
6359
)
6460
)
6561

66-
iff.chunks.add(
67-
IFFChunk(
68-
IFFChunk.SPR2_CHUNK_CODE,
69-
1,
70-
16,
71-
IFFChunkUtils.createChunkName("${stepSound.chunkPrefix}R3AG3AB4E"),
72-
SPR2ChunkData(
73-
1000,
74-
1537,
75-
mutableListOf(
76-
convertToSPR2Sprite(sprite, 31, 16, palette)
77-
)
62+
iff.addChunk(
63+
IFFChunk.SPR2_CHUNK_CODE,
64+
1,
65+
16,
66+
"${stepSound.chunkPrefix}R3AG3AB4E",
67+
SPR2ChunkData(
68+
1000,
69+
1537,
70+
mutableListOf(
71+
convertToSPR2Sprite(sprite, 31, 16, palette)
7872
)
7973
)
8074
)
8175

82-
iff.chunks.add(
83-
IFFChunk(
84-
IFFChunk.SPR2_CHUNK_CODE,
85-
257,
86-
16,
87-
ByteArray(64),
88-
SPR2ChunkData(
89-
1000,
90-
1537,
91-
mutableListOf(
92-
convertToSPR2Sprite(sprite, 63, 32, palette)
93-
)
76+
iff.addChunk(
77+
IFFChunk.SPR2_CHUNK_CODE,
78+
257,
79+
16,
80+
null,
81+
SPR2ChunkData(
82+
1000,
83+
1537,
84+
mutableListOf(
85+
convertToSPR2Sprite(sprite, 63, 32, palette)
9486
)
9587
)
9688
)
9789

98-
iff.chunks.add(
99-
IFFChunk(
100-
IFFChunk.SPR2_CHUNK_CODE,
101-
513,
102-
16,
103-
ByteArray(64),
104-
SPR2ChunkData(
105-
1000,
106-
1537,
107-
mutableListOf(
108-
convertToSPR2Sprite(sprite, 127, 64, palette)
109-
)
90+
iff.addChunk(
91+
IFFChunk.SPR2_CHUNK_CODE,
92+
513,
93+
16,
94+
null,
95+
SPR2ChunkData(
96+
1000,
97+
1537,
98+
mutableListOf(
99+
convertToSPR2Sprite(sprite, 127, 64, palette)
110100
)
111101
)
112102
)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import net.sneakysims.sneakylib.iff.IFF
2+
import net.sneakysims.sneakylib.iff.SPR2ChunkData
3+
import java.io.File
4+
5+
fun main() {
6+
val iff = IFF.read(File("C:\\Program Files (x86)\\Maxis\\The Sims\\GameData\\Floors\\FloorZenGravel.flr").readBytes())
7+
8+
println("Chunk Dumper:")
9+
iff.chunks.forEach {
10+
println("Chunk ID: ${it.id}")
11+
println("Chunk Code: ${it.code}")
12+
println("Chunk Flag: ${it.flags}")
13+
println("Chunk Name: ${it.name.joinToString("") { it.toInt().toChar().toString() }}")
14+
val data = it.data
15+
16+
if (data is SPR2ChunkData) {
17+
println("Version: ${data.version}")
18+
println("Palette ID: ${data.paletteId}")
19+
for (sprite in data.sprites) {
20+
println("Flags: ${sprite.flags}")
21+
println("Unknown: ${sprite.unknown}")
22+
println("Overriden: ${sprite.overridenPaletteId}")
23+
println("Transparent Pixel Palette Index ID: ${sprite.transparentPixelPaletteIndexId}")
24+
println("OffsetX: ${sprite.offsetX}")
25+
println("OffsetY: ${sprite.offsetY}")
26+
}
27+
}
28+
}
29+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import net.sneakysims.sneakylib.far.FAR3
2+
import java.io.File
3+
4+
fun main() {
5+
val farBytes = File("C:\\Games\\SimNation\\TSOData\\TSOClient\\uigraphics\\housepage\\housepage.dat").readBytes()
6+
7+
val far3 = FAR3.read(farBytes)
8+
9+
var idx = 0
10+
for (file in far3.files) {
11+
println("Writing ${file.fileName}")
12+
File("far3test/${file.fileName}").writeBytes(file.content)
13+
idx++
14+
}
15+
}

sneakylib-samples/scratchpad/src/main/kotlin/FloorFromScratchManual.kt

Lines changed: 63 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,30 @@ fun main() {
1212
val iff = IFF.empty()
1313

1414
// iff.chunks.addAll(originalIff.chunks.filter { it.code == "STR#" })
15-
iff.chunks.add(
16-
IFFChunk(
17-
IFFChunk.STR_CHUNK_CODE,
18-
0,
19-
// Why does it need to be 16?
20-
// IFF Pencil, and the game, only works if this is 16
21-
16,
22-
ByteArray(64),
23-
STRChunkData(
24-
STRChunkData.StringFormat.StringFormatFDFF(
25-
mutableListOf(
26-
STRChunkData.StringFormat.StringFormatFDFF.SimsString(
27-
net.sneakysims.sneakylib.sims.TheSimsLanguage.getLanguageById(1),
28-
"Loritta is so cute!!",
29-
"!"
30-
),
31-
STRChunkData.StringFormat.StringFormatFDFF.SimsString(
32-
net.sneakysims.sneakylib.sims.TheSimsLanguage.getLanguageById(1),
33-
"1",
34-
"!"
35-
),
36-
STRChunkData.StringFormat.StringFormatFDFF.SimsString(
37-
net.sneakysims.sneakylib.sims.TheSimsLanguage.getLanguageById(1),
38-
"hewwo",
39-
"!"
40-
)
15+
iff.addChunk(
16+
IFFChunk.STR_CHUNK_CODE,
17+
0,
18+
// Why does it need to be 16?
19+
// IFF Pencil, and the game, only works if this is 16
20+
16,
21+
null,
22+
STRChunkData(
23+
STRChunkData.StringFormat.StringFormatFDFF(
24+
mutableListOf(
25+
STRChunkData.StringFormat.StringFormatFDFF.SimsString(
26+
net.sneakysims.sneakylib.sims.TheSimsLanguage.getLanguageById(1),
27+
"Loritta is so cute!!",
28+
"!"
29+
),
30+
STRChunkData.StringFormat.StringFormatFDFF.SimsString(
31+
net.sneakysims.sneakylib.sims.TheSimsLanguage.getLanguageById(1),
32+
"1",
33+
"!"
34+
),
35+
STRChunkData.StringFormat.StringFormatFDFF.SimsString(
36+
net.sneakysims.sneakylib.sims.TheSimsLanguage.getLanguageById(1),
37+
"hewwo",
38+
"!"
4139
)
4240
)
4341
)
@@ -48,18 +46,16 @@ fun main() {
4846
val palette = PaletteCreator.kMeansQuantization(colors, 256)
4947
println("Palette Size is ${palette.size}")
5048

51-
iff.chunks.add(
52-
IFFChunk(
53-
IFFChunk.PALT_CHUNK_CODE,
54-
1537,
49+
iff.addChunk(
50+
IFFChunk.PALT_CHUNK_CODE,
51+
1537,
52+
0,
53+
null,
54+
PALTChunkData(
55+
1,
5556
0,
56-
ByteArray(64),
57-
PALTChunkData(
58-
1,
59-
0,
60-
0,
61-
palette.map { Color(it.red, it.green, it.blue) }
62-
)
57+
0,
58+
palette.map { Color(it.red, it.green, it.blue) }
6359
)
6460
)
6561

@@ -107,50 +103,44 @@ fun main() {
107103
)
108104
}
109105

110-
iff.chunks.add(
111-
IFFChunk(
112-
IFFChunk.SPR2_CHUNK_CODE,
113-
1,
114-
16,
115-
IFFChunkUtils.createChunkName("${FloorUtils.SOFT_FLOOR_SOUND_CHUNK_NAME}R3AG3AB4E"),
116-
SPR2ChunkData(
117-
1000,
118-
1537,
119-
mutableListOf(
120-
convertToSPR2Sprite(floor, 31, 16)
121-
)
106+
iff.addChunk(
107+
IFFChunk.SPR2_CHUNK_CODE,
108+
1,
109+
16,
110+
"${FloorUtils.SOFT_FLOOR_SOUND_CHUNK_NAME}R3AG3AB4E",
111+
SPR2ChunkData(
112+
1000,
113+
1537,
114+
mutableListOf(
115+
convertToSPR2Sprite(floor, 31, 16)
122116
)
123117
)
124118
)
125119

126-
iff.chunks.add(
127-
IFFChunk(
128-
IFFChunk.SPR2_CHUNK_CODE,
129-
257,
130-
16,
131-
ByteArray(64),
132-
SPR2ChunkData(
133-
1000,
134-
1537,
135-
mutableListOf(
136-
convertToSPR2Sprite(floor, 63, 32)
137-
)
120+
iff.addChunk(
121+
IFFChunk.SPR2_CHUNK_CODE,
122+
257,
123+
16,
124+
null,
125+
SPR2ChunkData(
126+
1000,
127+
1537,
128+
mutableListOf(
129+
convertToSPR2Sprite(floor, 63, 32)
138130
)
139131
)
140132
)
141133

142-
iff.chunks.add(
143-
IFFChunk(
144-
IFFChunk.SPR2_CHUNK_CODE,
145-
513,
146-
16,
147-
ByteArray(64),
148-
SPR2ChunkData(
149-
1000,
150-
1537,
151-
mutableListOf(
152-
convertToSPR2Sprite(floor, 127, 64)
153-
)
134+
iff.addChunk(
135+
IFFChunk.SPR2_CHUNK_CODE,
136+
513,
137+
16,
138+
null,
139+
SPR2ChunkData(
140+
1000,
141+
1537,
142+
mutableListOf(
143+
convertToSPR2Sprite(floor, 127, 64)
154144
)
155145
)
156146
)

sneakylib-samples/scratchpad/src/main/kotlin/IFFSPR2Test.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import java.io.File
55
import javax.imageio.ImageIO
66

77
fun main() {
8-
val input = File("C:\\Program Files (x86)\\Maxis\\The Sims\\GameData\\Floors\\noise.flr")
8+
val input = File("furalhacc.flr")
99

1010
val iff = IFF.read(input.readBytes())
1111

12-
dumpSPR2(iff, "noiseflr")
12+
dumpSPR2(iff, "furalhacc")
1313
/* val iff = IFF.empty()
1414
1515
iff.chunks.add(

0 commit comments

Comments
 (0)