-
Notifications
You must be signed in to change notification settings - Fork 90
Expand file tree
/
Copy pathbuild.lua
More file actions
executable file
·195 lines (145 loc) · 6.11 KB
/
build.lua
File metadata and controls
executable file
·195 lines (145 loc) · 6.11 KB
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
#!/usr/bin/env lua
--------------
-- Settings --
--------------
-- Set this to true to use a better compression algorithm for the sound driver.
-- Having this set to false will use an inferior compression algorithm that
-- results in an accurate ROM being produced.
local improved_sound_driver_compression = false
-- These describe the Saxman decompression buffer in the sound driver.
local music_buffer_address = 0x1380 -- Should always match zMusicData in s2.sounddriver.asm.
local music_buffer_size = 0x7C0 -- Should always be zStack minus 0x40.
---------------------
-- End of settings --
---------------------
---------------
-- Utilities --
---------------
local common = require "build_tools.lua.common"
local repository = "https://github.com/sonicretro/s2disasm"
-- Just a shim for backwards-compatibility with things like Vladikcomper's debugger.
-- TODO: Remove this when nothing uses it any more.
local function message_abort_wrapper(message_printed, abort)
common.handle_failure(message_printed, abort)
end
local function generate_music_data()
-- Obtain the paths to the native build tools for the current platform.
local tools, platform_directory = common.find_tools("build tool bundle", "build_tools/source_code/", repository, "saxman")
-- Present an error message to the user if the build tools for their platform do not exist.
if tools == nil then
common.show_flashy_message("Build failed. See above for more details.")
os.exit(false)
end
local compressed_song_list_filename = "sound/music/list of compressed songs.txt"
-- Detemine which songs are going to be compressed.
local compressed_songs = {}
for song_name in io.lines(compressed_song_list_filename) do
compressed_songs[song_name] = true
end
local custom_hashes = {
improved_sound_driver_compression = improved_sound_driver_compression,
music_buffer_address = music_buffer_address,
music_buffer_size = music_buffer_size,
compressed_song_list = common.clownmd5.HashFile(compressed_song_list_filename),
smps2asm = common.clownmd5.HashFile("sound/_smps2asm_inc.asm")
}
for _, filename_stem in ipairs(common.get_directory_contents_changed("sound/music", ".asm", {".sax", ".inc"}, custom_hashes)) do
local is_compressed = compressed_songs[filename_stem] == true
local inc_file_path = "sound/music/generated/" .. filename_stem .. ".inc"
-- Generate an '.inc' file for the song, which communicates to the assembler the song's file path as well as whether it is compressed or not.
local include_file = io.open(inc_file_path, "w")
if is_compressed then
include_file:write(string.format(
[[
.is_compressed = TRUE
binclude "sound/music/generated/%s.sax"
]], filename_stem))
else
include_file:write(string.format(
[[
.is_compressed = FALSE
include "sound/music/%s.asm"
]], filename_stem))
end
include_file:close()
-- If the song is compressed then compress it!
if is_compressed then
local asm_file_path = "sound/music/" .. filename_stem .. ".asm"
local sax_file_path = "sound/music/generated/" .. filename_stem .. ".sax"
print("Reassembling song '" .. filename_stem .. ".asm'...")
-- To begin with, we'll create a wrapper ASM file to set the environment
-- in which to assemble the lone song file. Notably, this environment
-- includes SMPS2ASM and begins the song at address 0x1380 (the address
-- of the Saxman decompression buffer in Z80 RAM).
local song_file = io.open("song.asm", "w")
song_file:write(string.format(
[[
CPU 68000
padding off
z80_ptr function x,(x)<<8&$FF00|(x)>>8&$00FF
FixMusicAndSFXDataBugs = 0
SonicDriverVer = 2
include "sound/_smps2asm_inc.asm"
phase $%X
include "sound/music/%s.asm"
dephase
if *>$%X
error "This song is too big and will overflow the decompression buffer! It should be uncompressed instead!"
endif
]], music_buffer_address, filename_stem, music_buffer_size))
song_file:close()
-- Assemble the song to an uncompressed binary.
local message_printed, abort = common.assemble_file("song.asm", "song.bin", "", "", false, repository)
-- We can get rid of this wrapper ASM file now.
os.remove("song.asm")
common.handle_failure(message_printed, abort)
-- Now that we have an assembled song binary, compress it.
os.execute(tools.saxman .. " " .. (improved_sound_driver_compression and "" or "-a") .. " song.bin \"" .. sax_file_path .. "\"")
-- Remove junk files from the assembly process.
os.remove("song.lst")
os.remove("song.bin")
end
end
end
local function amend_sound_driver_size()
-- Correct the compressed sound driver size, which we couldn't do until p2bin had been ran.
local comp_z80_size, movewZ80CompSize
for line in io.lines("s2.h") do
local match_begin, match_end = string.find(line, "comp_z80_size")
if match_begin ~= nil then
comp_z80_size = tonumber(line:match("0x%x+", match_end))
end
local match_begin, match_end = string.find(line, "movewZ80CompSize")
if match_begin ~= nil then
movewZ80CompSize = tonumber(line:match("0x%x+", match_end))
end
end
if comp_z80_size ~= nil and movewZ80CompSize ~= nil then
local rom = io.open("s2built.bin", "r+b")
rom:seek("set", movewZ80CompSize + 2)
rom:write(string.pack(">I2", comp_z80_size))
rom:close()
end
-- Remove the header file, since we no longer need it.
os.remove("s2.h")
end
----------------------
-- End of utilities --
----------------------
-------------------------------------
-- Actual build script begins here --
-------------------------------------
-- Compress music data and generate music-related assembler input.
generate_music_data()
-- Produce PCM and DPCM data.
common.convert_pcm_files_in_directory("sound/PCM")
common.convert_dpcm_files_in_directory("sound/DAC")
-- Build the ROM.
local compression = improved_sound_driver_compression and "saxman-optimised" or "saxman-bugged"
common.build_rom_and_handle_failure("s2", "s2built", "", "-p=0 -z=0," .. compression .. ",Size_of_Snd_driver_guess,after", true, repository)
-- Patch the ROM with the correct sound driver size.
amend_sound_driver_size()
-- Correct the ROM's header with a proper checksum and end-of-ROM value.
common.fix_header("s2built.bin")
-- A successful build; we can quit now.
common.exit()