-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtilex.rb
158 lines (142 loc) · 4.59 KB
/
tilex.rb
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
require 'rubygems'
require 'gd2'
Dir['./data/*.sty'].each do |filename|
File.open(filename, 'rb') do |f|
file_type = f.read(4)
next if file_type != "GBST"
# apparently 700, not 600 as in the dox
version_code = f.read(2).unpack("S")[0]
# extract all chunks from file
chunks = []
chunk_type = f.read(4)
while(!chunk_type.nil?)
chunk_size = f.read(4).unpack("I")[0]
p [chunk_type, chunk_size]
chunk_data = f.read(chunk_size)
chunks << [chunk_type, chunk_size, chunk_data]
# set up next loop
chunk_type = f.read(4)
end
processed = {}
chunks.each do |type, size, data|
case type
when "TILE"
processed[:tile] = {}
index = 0
tile_num = 0
# tiles are stored in 4x4 blocks in 64K pages
while index < size
page = data[index, 64*1024]
4.times do |y|
4.times do |x|
tile_dat = ""
64.times do |l|
tile_dat += page[x*64+(y*64+l)*256, 64]
end
processed[:tile][tile_num] = tile_dat
tile_num += 1
end
end
index += 64*1024
end
when "PPAL"
# note: palette in BGRA order
processed[:ppal] = {}
index = 0
ppal_num = 0
# palettes are stored as columns in 64K pages
while index < size
page = data[index, 64*1024]
64.times do |i|
ppal_dat = {}
256.times do |l|
ppal_dat[l] = page[i*4+l*256,4]
end
processed[:ppal][ppal_num] = ppal_dat
ppal_num += 1
end
index += 64*1024
end
when "SPRB"
sprb_arr = data.unpack("SSSSSS")
sprb = {}
sprb[:car] = sprb_arr[0]
sprb[:ped] = sprb_arr[1]
sprb[:code_obj] = sprb_arr[2]
sprb[:map_obj] = sprb_arr[3]
sprb[:user] = sprb_arr[4]
sprb[:font] = sprb_arr[5]
processed[:sprb] = sprb
when "FONB"
font_count = data[0,2].unpack("S")[0]
index = 2
bases = [0]
(font_count-1).times do
num_char = data[index,2].unpack("S")[0]
bases << bases[bases.length-1] + num_char
index += 2
end
processed[:fonb] = bases
when "DELX"
index = 0
delxs = []
while index < size
delx_arr = data[index,4].unpack("SCC")
which_sprite = delx_arr[0]
delta_count = delx_arr[1]
delta_size = data[index+4,2*delta_count].unpack("S"*delta_count)
delx = {}
delx[:which_sprite] = which_sprite
delx[:delta_count] = delta_count
delx[:delta_size] = delta_size
delxs << delx
index += 4+2*delta_count
end
processed[:delx] = delxs
when "PALX"
processed[:palx] = data.unpack("S"*16384)
when "PALB"
palb_arr = data.unpack("S"*8)
palb = {}
palb[:tile] = 0
palb[:sprite] = palb_arr[0]
palb[:car_remap] = palb[:sprite] + palb_arr[1]
palb[:ped_remap] = palb[:car_remap] + palb_arr[2]
palb[:code_obj_remap] = palb[:ped_remap] + palb_arr[3]
palb[:map_obj_remap] = palb[:code_obj_remap] + palb_arr[4]
palb[:user_remap] = palb[:map_obj_remap] + palb_arr[5]
palb[:font_remap] = palb[:user_remap] + palb_arr[6]
processed[:palb] = palb
else
puts "ERROR: Unknown Chunk Type: #{type}"
#exit
end
end
if(!processed[:tile].nil? and !processed[:ppal].nil? and
!processed[:palx].nil? and !processed[:palb].nil?)
output_dir = "./tiles/#{File::basename(filename).split(".")[0]}"
FileUtils.mkdir_p output_dir
tile = processed[:tile]
ppal = processed[:ppal]
palx = processed[:palx]
palb = processed[:palb]
tile_base = palb[:tile]
tile.each do |tile_num, tile_raw|
tile_pal_ind = palx[tile_base+tile_num]
tile_pal = ppal[tile_pal_ind]
# workaround for GD2 alpha
tile_img = GD2::Image.import('./blank_tile.png')
tile_img.save_alpha = 1
64.times do |x|
64.times do |y|
pix_raw = tile_raw[x+64*y]
color = tile_pal[pix_raw]
tile_img.set_pixel(x,y,GD2::Color.new(color[2],color[1],color[0],
pix_raw == 0 ? GD2::ALPHA_TRANSPARENT : GD2::ALPHA_OPAQUE).to_i)
end
end
tile_img.export("#{output_dir}/#{tile_num}.png")
end
end
end
end