1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
|
#!/usr/bin/mono /home/me/Packages/IronLanguages-main-ba2094c/bin/Release/ir.exe
## Requires IronRuby
$: << "/home/me/Dev/NW4RTools/NW4RTools/bin/Release"
require 'NW4RTools'
require 'System.Drawing'
include System
include NW4RTools
include NW4RTools::Models
brres = ResFile.new
models = brres.create_model_group
path = '/home/me/Games/Newer/ModelRev'
reader = System::IO::StreamReader.new("#{path}/fullworld-Z20nvrc.obj")
ObjImporter.ImportModel(path, reader, brres, "WorldBase", ObjImporter::LightmapType.Map)
model = models["WorldBase"]
alpha_tex = Texture.new
alpha_bitmap = System::Drawing::Bitmap.new("#{path}/images/alphaBlender.png")
alpha_tex.images = System::Array[System::Drawing::Bitmap].new([alpha_bitmap])
alpha_tex.format = TextureFormat.RGB5A3
brres.get_texture_group.add 'alphaBlender', alpha_tex
# yay
#model.shapes["World2_PathsPlumbing__World2_PathsPlumbing"].clr_data[0].raw_data = System::Array[Byte].new([255, 255, 255, 128])
# how's this for hackiness?
model.materials.each do |kvp|
next unless kvp.key =~ /path/i
if true
mat = kvp.value
# update the material
mat.tex_coord_gen_count = 4
mat.chan_count = 1
mat.tev_stage_count = 4
mat.ind_stage_count = 1
mat.cull_mode = 2
mat.z_comp_loc = 1
mat.light_set_i_d = 0xFF
mat.fog_i_d = 1
4.times { |i| mat.s_r_t_settings[i] = SRTSettingInfo.new }
mat.chan_ctrls[0].flag_c = 0x700
# for now, we'll just add the alpha texture
tex_info = TextureInfo.new
tex_info.texture_name = 'alphaBlender'
tex_info.wrap_s = TextureWrapType.REPEAT
tex_info.wrap_t = TextureWrapType.REPEAT
tex_info.min_filt = 1
tex_info.mag_filt = 1
mat.texture_infos.insert 0, tex_info
# need to make sure the order is correct
# now display lists. fun, fun, fun, fun
pix = DisplayListWriter.new
[0xF33F0000, 0x40000017, 0xFE00FFE3, 0x410034A1, 0x42000000].each do |p|
pix.load_b_p_reg p
end
pix.end
mat.pix_d_l = pix.get_buffer
tc = DisplayListWriter.new
tc.load_b_p_reg 0xE2000000
3.times { tc.load_b_p_reg 0xE3000000 }
tc.load_b_p_reg 0xE4000000
3.times { tc.load_b_p_reg 0xE5000000 }
tc.load_b_p_reg 0xE6000000
3.times { tc.load_b_p_reg 0xE7000000 }
tc.add_padding 4
(0..5).each { |x| tc.load_b_p_reg 0xE0800000 | (x << 24) }
tc.load_b_p_reg 0xE68FF000
tc.load_b_p_reg 0xE7800000
tc.end
mat.tev_color_d_l = tc.get_buffer
imas = DisplayListWriter.new
imas.load_b_p_reg 0x25000000
imas.load_b_p_reg 0x26000000
imas.pad_to_size 0x40
imas.end
mat.ind_mtx_and_scale_d_l = imas.get_buffer
tcg = DisplayListWriter.new
tcg.load_x_f_reg 0x1040, System::Array[Byte].new([0, 0, 0x52, 0x80])
tcg.load_x_f_reg 0x1050, System::Array[Byte].new([0, 0, 0, 0])
tcg.load_x_f_reg 0x1041, System::Array[Byte].new([0, 0, 0x53, 0])
tcg.load_x_f_reg 0x1051, System::Array[Byte].new([0, 0, 0, 3])
tcg.load_x_f_reg 0x1042, System::Array[Byte].new([0, 0, 0x50, 0x86])
tcg.load_x_f_reg 0x1052, System::Array[Byte].new([0, 0, 1, 6])
tcg.load_x_f_reg 0x1043, System::Array[Byte].new([0, 0, 0x50, 0x86])
tcg.load_x_f_reg 0x1053, System::Array[Byte].new([0, 0, 1, 9])
tcg.pad_to_size 0xA0
tcg.end
mat.tex_coord_gen_dl = tcg.get_buffer
shad = mat.shader_ref
shad.tev_stage_count = 4
shad.unk1 = 0x00010203
shad.unk2 = 0xFFFFFFFF
sh = DisplayListWriter.new
[6, 4, 7, 0xE, 8, 0, 9, 0xC, 0xA, 5, 0xB, 0xD, 0xC, 0xA, 0xD, 0xE].each_slice(2) do |bp|
sh.load_b_p_reg 0xFE00000F # BP mask
sh.load_b_p_reg 0xF0000000 | (bp[0] << 24) | bp[1]
end
sh.load_b_p_reg 0x27FFFFFF # IREF
sh.add_padding 11
sh.load_b_p_reg 0xFEFFFFF0
sh.load_b_p_reg 0xF6E338C0
sh.load_b_p_reg 0x283C9052
sh.load_b_p_reg 0xC008F8AF
sh.load_b_p_reg 0xC208F80F
sh.load_b_p_reg 0xC108FFD0
sh.load_b_p_reg 0xC308E270
sh.load_b_p_reg 0x10000000
sh.load_b_p_reg 0x11000000
sh.add_padding 3
sh.load_b_p_reg 0xFEFFFFF0
sh.load_b_p_reg 0xF7E33EF0
sh.load_b_p_reg 0x293C005B
sh.load_b_p_reg 0xC4080A8E
sh.load_b_p_reg 0xC608FFF0
sh.load_b_p_reg 0xC508E370
sh.load_b_p_reg 0xC708F070
sh.load_b_p_reg 0x12000000
sh.load_b_p_reg 0x13000000
sh.pad_to_size 0x1E0
sh.end
shad.display_list = sh.get_buffer
end
next
if false
mat = kvp.value
pix_dl = DisplayListWriter.new
pix_dl.load_b_p_reg 0xF33F0000
pix_dl.load_b_p_reg 0x40000017
pix_dl.load_b_p_reg 0xFE00FFE3
pix_dl.load_b_p_reg 0x410034A1
pix_dl.load_b_p_reg 0x42000000
pix_dl.end
mat.pix_d_l = pix_dl.get_buffer
shad = mat.shader_ref
dl = DisplayListWriter.new
# KSEL 0 => 4
# KSEL 1 => 0xE
# KSEL 2 => 0
# KSEL 3 => 0xC
# KSEL 4 => 5
# KSEL 5 => 0xD
# KSEL 6 => 0xA
# KSEL 7 => 0xE
[6, 4, 7, 0xE, 8, 0, 9, 0xC, 0xA, 5, 0xB, 0xD, 0xC, 0xA, 0xD, 0xE].each_slice(2) do |bp|
dl.load_b_p_reg 0xFE00000F # BP mask
dl.load_b_p_reg 0xF0000000 | (bp[0] << 24) | bp[1]
end
dl.load_b_p_reg 0x27FFFFFF # IREF
dl.add_padding 11
shad.tev_stage_count = 3
shad.unk1 = 0x000102FF
shad.unk2 = 0xFFFFFFFF
dl.load_b_p_reg 0xFEFFFFF0 # BP mask
dl.load_b_p_reg 0xF6E338C0 # KSel 0
dl.load_b_p_reg 0x283C0049
dl.load_b_p_reg 0xC008F8AF
dl.load_b_p_reg 0xC208F80F
dl.load_b_p_reg 0xC108FFD0
dl.load_b_p_reg 0xC308E270
dl.load_b_p_reg 0x10000000 # IND_CMD 0
dl.load_b_p_reg 0x11000000 # IND_CMD 1
dl.add_padding 3
dl.load_b_p_reg 0xFEFFFFF0
dl.load_b_p_reg 0xF7003EF0
dl.load_b_p_reg 0x293BF052
dl.load_b_p_reg 0xC4080A8E
dl.add_padding 5
dl.load_b_p_reg 0xC508E370
dl.add_padding 5
dl.load_b_p_reg 0x12000000
dl.pad_to_size 0x1E0
dl.end
shad.display_list = dl.get_buffer
end
# modify it!
# first off, we'll disable lightmaps and see how that goes
mat = kvp.value
tex_infos = mat.texture_infos.reject { |x| x.texture_name =~ /lm_.*/ }
mat.texture_infos = System::Collections::Generic::List[TextureInfo].new
tex_infos.each { |x| mat.texture_infos.add x }
mat.tex_coord_gen_count = 1
mat.chan_count = 1
mat.tev_stage_count = 2
mat.ind_stage_count = 0
mat.cull_mode = 2
# oops, case conversion fail right there
mat.light_set_i_d = 1
pix_dl = DisplayListWriter.new
pix_dl.load_b_p_reg 0xF31EFF80
pix_dl.load_b_p_reg 0x40000017
pix_dl.load_b_p_reg 0xFE00FFE3
pix_dl.load_b_p_reg 0x410034A0
#BlendMode, must analyse this
#pix_dl.load_b_p_reg 0x4100F281
pix_dl.load_b_p_reg 0x42000000
pix_dl.end
mat.pix_d_l = pix_dl.get_buffer
tc_dl = DisplayListWriter.new
tc_dl.load_b_p_reg 0xE20000FF
3.times { tc_dl.load_b_p_reg 0xE30FF0FF }
tc_dl.load_b_p_reg 0xE4000000
3.times { tc_dl.load_b_p_reg 0xE5000000 }
tc_dl.load_b_p_reg 0xE6000000
3.times { tc_dl.load_b_p_reg 0xE7000000 }
tc_dl.add_padding 4
(0..7).each { |x| tc_dl.load_b_p_reg 0xE0800000 | (x << 24) }
# add this
tc_dl.load_b_p_reg 0xE6080080
3.times { tc_dl.load_b_p_reg 0xE7080080 }
tc_dl.pad_to_size 0x80
tc_dl.end
mat.tev_color_d_l = tc_dl.get_buffer
imas_dl = DisplayListWriter.new
imas_dl.load_b_p_reg 0x25000000
imas_dl.load_b_p_reg 0x26000000
imas_dl.add_padding 54
imas_dl.end
mat.ind_mtx_and_scale_d_l = imas_dl.get_buffer
tcg_dl = DisplayListWriter.new
tcg_dl.load_x_f_reg 0x1040, System::Array[Byte].new([0, 0, 0x52, 0x80])
tcg_dl.load_x_f_reg 0x1050, System::Array[Byte].new([0, 0, 0, 0])
tcg_dl.pad_to_size 0xA0
tcg_dl.end
mat.tex_coord_gen_dl = tcg_dl.get_buffer
shad = mat.shader_ref
dl = DisplayListWriter.new
# KSEL 0 => 4
# KSEL 1 => 0xE
# KSEL 2 => 0
# KSEL 3 => 0xC
# KSEL 4 => 5
# KSEL 5 => 0xD
# KSEL 6 => 0xA
# KSEL 7 => 0xE
[6, 4, 7, 0xE, 8, 0, 9, 0xC, 0xA, 5, 0xB, 0xD, 0xC, 0xA, 0xD, 0xE].each_slice(2) do |bp|
dl.load_b_p_reg 0xFE00000F # BP mask
dl.load_b_p_reg 0xF0000000 | (bp[0] << 24) | bp[1]
end
dl.load_b_p_reg 0x27FFFFFF # IREF
dl.add_padding 11
shad.tev_stage_count = 2
shad.unk1 = 0x00FFFFFF
shad.unk2 = 0xFFFFFFFF
dl.load_b_p_reg 0xFEFFFFF0 # BP mask
dl.load_b_p_reg 0xF6E338C0 # KSel 0
dl.load_b_p_reg 0x2803F040 # TREF 0 - includes stages 0 and 1
# Stage 0: Map 0, Coord 0, Texture Enabled, Channel 0
# Stage 1: Map 7, Coord 7, Texture Disabled, Channel 0
dl.load_b_p_reg 0xC008F8AF # TEV_COLOR_ENV 0
# a = GX_CC_ZERO, b = GX_CC_TEXC, c = GX_CC_RASC, d = GX_CC_ZERO
# bias = GX_TB_ZERO, op = GX_TEV_ADD, clamp = GX_TRUE, scale = GX_CS_SCALE_1, dest = GX_TEVPREV
dl.load_b_p_reg 0xC208F20F # TEV_COLOR_ENV 1
# a = GX_CC_ZERO, b = GX_CC_C0, c = GX_CC_CPREV, d = GX_CC_ZERO
# bias = GX_TB_ZERO, op = GX_TEV_ADD, clamp = GX_TRUE, scale = GX_CS_SCALE_1, dest = GX_TEVPREV
dl.load_b_p_reg 0xC108F2F0 # TEV_ALPHA_ENV 0
# a = GX_CA_ZERO, b = GX_CA_TEXA, c = GX_CA_RASA, d = GX_CA_ZERO
# bias = GX_TB_ZERO, op = GX_TEV_ADD, clamp = GX_TRUE, scale = GX_CS_SCALE_1, dest = GX_TEVPREV
dl.load_b_p_reg 0xC3081FF0 # TEV_ALPHA_ENV 1
# a = GX_CA_APREV, b = GX_CA_ZERO, c = GX_CA_ZERO, d = GX_CA_ZERO
# bias = GX_TB_ZERO, op = GX_TEV_ADD, clamp = GX_TRUE, scale = GX_CS_SCALE_1, dest = GX_TEVPREV
dl.load_b_p_reg 0x10000000 # IND_CMD 0
dl.load_b_p_reg 0x11000000 # IND_CMD 1
dl.pad_to_size 0x1E0
dl.end
shad.display_list = dl.get_buffer
end
final_data = BrresWriter.write_file(brres)
System::IO::File.write_all_bytes("#{path}/MMFullWorld_mod.brres", final_data)
|