ReC98/Tupfile.lua

1052 lines
27 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--[[
⚠️ CAUTION! ⚠️
You are on the `master` branch, which builds PC-98 DOS binaries that are
identical to ZUN's originally released binaries. If you want to port the game
to other architectures or develop a mod that doesn't need to be byte-for-byte
comparable to the original binary, start from the cleaned-up `debloated` branch
instead. That branch is easier to read and modify, and builds smaller and
slightly faster PC-98 binaries while leaving all bugs and quirks from ZUN's
original code in place.
Seriously, you'd just be torturing yourself if you do anything nontrivial based
on this branch.
⚠️ CAUTION! ⚠️
--]]
---@alias ReC98Input string | { [1]: string, extra_inputs: string | string[], o?: string}
tup.include("Pipeline/rules.lua")
---@class (exact) ConfigShape
---@field obj_root? string Root directory for all intermediate files
---@field bin_root? string Root directory for shipped binaries
---@field aflags? string
---@field cflags? string
---@field lflags? string
---@class Config
local Config = {
obj_root = "obj/",
bin_root = "bin/",
aflags = "/m /mx /kh32768 /t",
cflags = "-I. -O -b- -3 -Z -d",
lflags = "-s",
}
Config.__index = Config
local Rules = NewRules(Config.obj_root)
MODEL_ASM = { lflags = "-t -3" }
MODEL_TINY = { cflags = "-mt", lflags = "-t" }
MODEL_SMALL = { cflags = "-ms" }
-- Currently, it only makes sense to enable extended dictionary processing for
-- binaries that don't link the original binary release of MASTERS.LIB, which
-- doesn't come with them.
MODEL_LARGE = { cflags = "-ml", lflags = "-E" }
---Generates a ConfigShape for an output subdirectory.
---@param dir string
---@return ConfigShape
function Subdir(dir)
return { obj_root = dir, bin_root = dir }
end
---Maps each source filename to its compiled object file. Allows the same
---source file to be listed in multiple binaries later occurrences get
---replaced with the previous build output.
---@type { [string]: string }
local PreviousOutputForSource = {}
---@param ... ConfigShape
function Config:branch(...)
local arg = { ... }
---@class Config
local ret = setmetatable({}, self)
ret.__index = self
for field, value in pairs(self) do
ret[field] = value
for _, other in pairs(arg) do
if other[field] then
-- By only space-separating flags, we allow custom directories.
if (field:sub(-5) == "flags") then
ret[field] = (ret[field] .. " " .. other[field])
else
ret[field] = (ret[field] .. other[field])
end
end
end
end
return ret
end
---@param input ReC98Input
function Config:build_uncached(input)
local fn = ((type(input) == "string" and input) or input[1])
local out_basename = (tup.base(fn):gsub("th0%d_", "") .. ".obj")
if input.o then
out_basename = input.o
input.o = nil
end
local out_file = (self.obj_root .. out_basename)
local ext = tup.ext(fn)
if (ext == "asm") then
-- We can't use %f since TASM32 wants backslashes and Tup would
-- automatically rewrite them to slashes.
local args = string.format("%s %s %%o", self.aflags, fn:gsub("/", "\\"))
return Rules:add_32(input, "tasm32", args, out_file:gsub("/", "\\"))[1]
elseif ((ext == "c") or (ext == "cpp")) then
local args = string.format("-c %s -n%s %%f", self.cflags, self.obj_root)
return Rules:add_16(input, "tcc", args, out_file)[1]
elseif ((ext == "obj") or (ext == "lib")) then
return fn
end
error(string.format("Unknown file extension, can't build: `%s`", fn))
end
---@param inputs ReC98Input[]
---@return string[]
function Config:build(inputs)
local ret = {}
for _, input in pairs(inputs) do
local fn = ((type(input) == "string" and input) or input[1])
local output = PreviousOutputForSource[fn]
if (output == nil) then
output = self:build_uncached(input)
PreviousOutputForSource[fn] = output
end
ret += { output }
end
return ret
end
---@param exe_stem string
---@param inputs ReC98Input[]
function Config:link(exe_stem, inputs)
local model_c = self.cflags:match("-m([tsmclh])")
local objs = self:build(inputs)
local obj_root = self.obj_root:gsub("/", "\\")
local bin_root = self.bin_root:gsub("/", "\\")
local ext = (self.lflags:find("-t") and ".com" or ".exe")
local rsp_fn = string.format("%s%s.@l", obj_root, exe_stem)
local map_fn = string.format("%s%s.map", obj_root, exe_stem)
local bin_fn = string.format("%s%s%s", bin_root, exe_stem, ext)
-- When TCC spawns TLINK, it writes the entire link command line into a
-- file with the fixed name `turboc.$ln`. This can't ever work with
-- parallel builds, so we have to replicate TCC's response file generation
-- ourselves here.
-- This not only saves one emulated process spawn call, but also gives us
-- full control over the linker command line, allowing us to place the map
-- file under `obj/` rather than next to the binary in `bin/`.
-- Thankfully, we can even omit the directory for Borland's C standard
-- library and rely on `TLINK.CFG` to supply it. Deriving it from the
-- `PATH` would be quite annoying on Windows 9x…
local lflags = string.format("-c %s ", self.lflags)
if model_c then
lflags = string.format("%sc0%s.obj", lflags, model_c)
end
-- Can't use %f because we need backslashes…
local libs = ""
for _, obj in pairs(objs) do
if (obj:sub(-4) == ".lib") then
libs = (libs .. obj:gsub("/", "\\") .. " ")
else
lflags = (lflags .. " " .. obj:gsub("/", "\\"))
end
end
lflags = string.format("%s, %s, %s, %s", lflags, bin_fn, map_fn, libs)
if model_c then
local model_math = (model_c == "t" and "s" or model_c)
lflags = string.format(
"%semu.lib math%s.lib c%s.lib", lflags, model_math, model_c
)
end
objs += Rules:add_32({}, "echo", (lflags .. ">%o"), rsp_fn)
local outputs = { bin_fn, map_fn }
return Rules:add_16(objs, "tlink", ("@" .. rsp_fn), outputs)[1]
end
-- Additional generally good compilation flags. Should be used for all code
-- that does not need to match the original binaries.
local optimized_cfg = Config:branch({ cflags = "-G -k- -p -x-" })
-- Pipeline
-- --------
local pipeline_cfg = optimized_cfg:branch(Subdir("Pipeline/"), {
cflags = "-IPipeline/",
})
local pipeline_tool_cfg = pipeline_cfg:branch(MODEL_TINY)
local pipeline_stub_cfg = pipeline_cfg:branch(MODEL_ASM)
pipeline_tool_cfg:link("grzview", {
"Pipeline/grzview.cpp",
"th01/formats/grz.cpp",
"platform/x86real/pc98/palette.cpp",
"bin/masters.lib",
})
local bmp2arr = pipeline_tool_cfg:link("bmp2arr", {
"Pipeline/bmp2arrl.c",
"Pipeline/bmp2arr.c",
})
---@class BMPShape
---@field [1] string Input .BMP file
---@field [2] "asm" | "cpp" Output format
---@field [3] string Symbol
---@field [4] integer Width
---@field [5] integer Height
---@field [6] string? Additional arguments
---@param bmp BMPShape
function BMP(bmp)
local out_fn = bmp[1]:gsub("%..+$", (bmp[2] == "asm" and ".asp" or ".csp"))
local inputs = { bmp[1], extra_inputs = bmp2arr }
local sym = ((bmp[2] == "asm" and "_" or "") .. bmp[3])
local additional = ((bmp[6] and (" " .. bmp[6])) or "")
local args = string.format(
"-q -i %%f -o %%o -sym %s -of %s -sw %d -sh %d%s",
sym, bmp[2], bmp[4], bmp[5], additional
)
return Rules:add_16(inputs, bmp2arr, args, out_fn)[1]
end
---@param bmps BMPShape[]
---@return table<string, string> sprites Sprite basename → source file
function Sprites(bmps)
local ret = {}
for _, bmp in pairs(bmps) do
ret[tup.base(bmp[1])] = BMP(bmp)
end
return ret
end
---@param input string
function Config:stub(input)
local obj_fn = self:build({ input })[1]
local bin_fn = obj_fn:gsub("%..+$", ".bin")
local args = string.format("-x -t %s, %s", obj_fn, bin_fn)
return Rules:add_16(obj_fn, "tlink", args:gsub("/", "\\"), bin_fn)[1]
end
local zungen = pipeline_tool_cfg:link("zungen", { "Pipeline/zungen.c" })
local comcstm = pipeline_tool_cfg:link("comcstm", { "Pipeline/comcstm.c" })
local zun_stub = pipeline_stub_cfg:stub("Pipeline/zun_stub.asm")
local cstmstub = pipeline_stub_cfg:stub("Pipeline/cstmstub.asm")
---@param bin_fn string
---@param procs [string, string][] [Menu name, input filename]
function Config:zungen(bin_fn, procs)
local rsp_fn = string.format(
"%s%s.@z", self.obj_root, tup.base(bin_fn)
):gsub("/", "\\")
local inputs = { extra_inputs = { zungen, zun_stub, rsp_fn }}
local names = ""
local fns = ""
for _, proc in pairs(procs) do
inputs += { proc[2] }
names = string.format("%s %s", names, proc[1])
fns = string.format("%s %s", fns, proc[2])
end
Rules:add_32(
{}, "echo", string.format("%d%s%s>%%o", #procs, names, fns), rsp_fn
)
return Rules:add_16(inputs, zungen, "%2i %3i %o", bin_fn)[1]
end
---@param out_basename string
---@param prog_fn string
---@param usage_fn string
---@param timestamp number
function Config:comcstm(out_basename, usage_fn, prog_fn, timestamp)
local inputs = { comcstm, usage_fn, prog_fn, cstmstub }
local cmd = string.format("%%2f %%3f %%4f %d %%o", timestamp)
return Rules:add_16(
inputs, comcstm, cmd, (self.bin_root .. out_basename)
)[1]
end
-- --------
-- Third-party libraries
-- ---------------------
local piloadc = Config:branch({ aflags = "/ml" }):build({
"libs/piloadc/piloadc.asm"
})[1]
local sprite16 = Config:branch({ aflags = "/dTHIEF" }):build({
{ "libs/sprite16/sprite16.asm", o = "th03/zunsp.obj" }
})[1]
-- ---------------------
-- Games
-- -----
---@param game number
function GameShape(game)
local ret = Subdir(string.format("th0%d/", game))
ret.aflags = string.format("/dGAME=%d", game)
ret.cflags = string.format("-DGAME=%d", game)
return ret
end
local th01 = Config:branch(GameShape(1))
local th02 = Config:branch(GameShape(2))
local th03 = Config:branch(GameShape(3))
local th04 = Config:branch(GameShape(4))
local th05 = Config:branch(GameShape(5))
-- -----
-- TH01
-- ----
local th01_sprites = Sprites({
{ "th01/sprites/leaf_s.bmp", "cpp", "sSPARK", 8, 8 },
{ "th01/sprites/leaf_l.bmp", "cpp", "sLEAF_LEFT", 8, 8 },
{ "th01/sprites/leaf_r.bmp", "cpp", "sLEAF_RIGHT", 8, 8 },
{ "th01/sprites/ileave_m.bmp", "cpp", "sINTERLEAVE_MASKS", 8, 8 },
-- ZUN bug: Supposed to be 8 preshifted sprites, with a height of 1 and a
-- width of SHOOTOUT_LASER_MAX_W pixels each, but ZUN messed up a single
-- pixel in the first pre-shifted sprite.
-- So, we're forced to manually unroll them…
{ "th01/sprites/laser_s.bmp", "cpp", "sSHOOTOUT_LASER", 16, 8 },
{ "th01/sprites/mousecur.bmp", "cpp", "sMOUSE_CURSOR", 16, 16 },
{ "th01/sprites/pellet.bmp", "cpp", "sPELLET", 8, 8, "-pshf inner" },
{ "th01/sprites/pellet_c.bmp", "cpp", "sPELLET_CLOUD", 16, 16 },
{ "th01/sprites/pillar.bmp", "cpp", "sPILLAR", 32, 8 },
{ "th01/sprites/shape8x8.bmp", "cpp", "sSHAPE8X8", 8, 8 },
{ "th01/sprites/bonusbox.bmp", "cpp", "sSTAGEBONUS_BOX", 8, 4 },
})
local th01_zunsoft = th01:branch(MODEL_TINY):link("zunsoft", {
"th01/zunsoft.cpp",
"bin/masters.lib",
})
th01:branch(MODEL_LARGE, { cflags = "-DBINARY='O'" }):link("op", {
piloadc,
"th01/op_01.cpp",
"th01/frmdelay.cpp",
{ "th01/vsync.cpp", extra_inputs = th01_sprites["mousecur"] },
"th01/ztext.cpp",
"th01/initexit.cpp",
"th01/graph.cpp",
"th01/ptn_0to1.cpp",
"th01/vplanset.cpp",
"th01/op_07.cpp",
"th01/grp_text.cpp",
"th01/ptn.cpp",
"th01/op_09.cpp",
"th01/f_imgd.cpp",
"th01/grz.cpp",
"th01_op.asm",
"th01/resstuff.cpp",
"th01/mdrv2.cpp",
"th01/pf.cpp",
})
th01:branch(MODEL_LARGE, { cflags = "-DBINARY='M'" }):link("reiiden", {
piloadc,
"th01/main_01.cpp",
"th01/frmdelay.cpp",
{ "th01/vsync.cpp", extra_inputs = th01_sprites["mousecur"] },
"th01/ztext.cpp",
"th01/initexit.cpp",
"th01/graph.cpp",
"th01/ptn_0to1.cpp",
"th01/vplanset.cpp",
"th01/main_07.cpp",
"th01/ptn.cpp",
"th01/main_08.cpp",
"th01/f_imgd.cpp",
"th01/grz.cpp",
"th01_reiiden.asm",
{ "th01/main_09.cpp", extra_inputs = th01_sprites["pellet_c"] },
"th01/bullet_l.cpp",
"th01/grpinv32.cpp",
"th01/resstuff.cpp",
"th01/scrollup.cpp",
"th01/egcrows.cpp",
{ "th01/pgtrans.cpp", extra_inputs = th01_sprites["ileave_m"] },
"th01/2x_main.cpp",
"th01/egcwave.cpp",
"th01/grph1to0.cpp",
"th01/main_14.cpp",
{ "th01/main_15.cpp", extra_inputs = th01_sprites["laser_s"] },
"th01/mdrv2.cpp",
"th01/main_17.cpp",
{ "th01/main_18.cpp", extra_inputs = th01_sprites["bonusbox"] },
"th01/main_19.cpp",
"th01/main_20.cpp",
"th01/main_21.cpp",
"th01/pf.cpp",
{ "th01/main_23.cpp", extra_inputs = th01_sprites["shape8x8"] },
"th01/main_24.cpp",
"th01/main_25.cpp",
"th01/main_26.cpp",
"th01/main_27.cpp",
"th01/main_28.cpp",
{ "th01/main_29.cpp", extra_inputs = th01_sprites["pillar"] },
"th01/main_30.cpp",
"th01/main_31.cpp",
"th01/main_32.cpp",
"th01/main_33.cpp",
"th01/main_34.cpp",
"th01/main_35.cpp",
{ "th01/main_36.cpp", extra_inputs = {
th01_sprites["leaf_s"],
th01_sprites["leaf_l"],
th01_sprites["leaf_r"],
} },
"th01/main_37.cpp",
{ "th01/main_38.cpp", extra_inputs = th01_sprites["pellet"] },
})
th01:branch(MODEL_LARGE, { cflags = "-DBINARY='E'" }):link("fuuin", {
piloadc,
"th01/fuuin_01.cpp",
"th01/input_mf.cpp",
"th01/fuuin_02.cpp",
"th01/fuuin_03.cpp",
"th01/fuuin_04.cpp",
{ "th01/vsync.cpp", extra_inputs = th01_sprites["mousecur"] },
"th01/ztext.cpp",
"th01/initexit.cpp",
"th01/graph.cpp",
"th01/grp_text.cpp",
"th01/fuuin_10.cpp",
"th01/f_imgd_f.cpp",
"th01/vplanset.cpp",
"th01/fuuin_11.cpp",
"th01/2x_fuuin.cpp",
"th01/mdrv2.cpp",
"th01_fuuin.asm",
})
-- ----
-- TH02
-- ----
local th02_sprites = Sprites({
{ "th02/sprites/bombpart.bmp", "asm", "sBOMB_PARTICLES", 8, 8 },
{ "th02/sprites/pellet.bmp", "asm", "sPELLET", 8, 8, "-pshf outer" },
{ "th02/sprites/sparks.bmp", "asm", "sSPARKS", 8, 8, "-pshf outer" },
{ "th02/sprites/pointnum.bmp", "asm", "sPOINTNUMS", 8, 8 },
{ "th02/sprites/verdict.bmp", "cpp", "sVERDICT_MASKS", 16, 16 },
})
local th02_zuninit = th02:branch(MODEL_ASM):link("zuninit", {
"th02_zuninit.asm",
})
th02:zungen("bin/th02/zun.com", {
{ "ONGCHK", "libs/kaja/ongchk.com" },
{ "ZUNINIT", th02_zuninit },
{ "ZUN_RES", th02:branch(MODEL_TINY):link("zun_res", {
"th02/zun_res1.cpp",
"th02/zun_res2.cpp",
"bin/masters.lib",
}) },
{ "ZUNSOFT", th01_zunsoft },
})
th02:branch(MODEL_LARGE):link("op", {
"th02/op_01.cpp",
"th02/exit_dos.cpp",
"th02/zunerror.cpp",
"th02/grppsafx.cpp",
"th02_op.asm",
"th01/vplanset.cpp",
"th02/pi_load.cpp",
"th02/grp_rect.cpp",
"th02/frmdely2.cpp",
"th02/input_rs.cpp",
"th02/initop.cpp",
"th02/exit.cpp",
"th02/snd_mmdr.c",
"th02/snd_mode.c",
"th02/snd_pmdr.c",
"th02/snd_load.cpp",
"th02/pi_put.cpp",
"th02/snd_kaja.cpp",
"th02/op_02_3.cpp",
"th02/snd_se_r.cpp",
"th02/snd_se.cpp",
"th02/frmdely1.cpp",
"th02/op_03.cpp",
"th02/globals.cpp",
"th02/op_04.cpp",
"th02/op_05.cpp",
"th02/op_music.cpp",
})
th02:branch(MODEL_LARGE, { cflags = "-DBINARY='M'" }):link("main", {
{ "th02_main.asm", extra_inputs = {
th02_sprites["pellet"],
th02_sprites["bombpart"],
th02_sprites["sparks"],
th02_sprites["pointnum"],
} },
"th02/tile.cpp",
"th02/pointnum.cpp",
"th02/item.cpp",
"th02/hud.cpp",
"th02/player_b.cpp",
"th02/zunerror.cpp",
"th02/keydelay.cpp",
"th02/main02_1.cpp",
"th01/vplanset.cpp",
"th02/pi_load.cpp",
"th02/vector.cpp",
"th02/frmdely1.cpp",
"th02/input_rs.cpp",
"th02/exit.cpp",
"th02/snd_mmdr.c",
"th02/snd_mode.c",
"th02/snd_pmdr.c",
"th02/snd_dlyv.c",
"th02/snd_load.cpp",
"th02/mpn_l_i.cpp",
"th02/initmain.cpp",
"th02/pi_put.cpp",
"th02/snd_kaja.cpp",
"th02/snd_dlym.cpp",
"th02/snd_se_r.cpp",
"th02/snd_se.cpp",
"th02/main_03.cpp",
"th02/hud_ovrl.cpp",
"th02/dialog.cpp",
"th02/boss_5.cpp",
"th02/regist_m.cpp",
})
th02:branch(MODEL_LARGE, { cflags = "-DBINARY='E'" }):link("maine", {
{ "th02/end.cpp", extra_inputs = th02_sprites["verdict"] },
"th02_maine.asm",
"th02/grppsafx.cpp",
"th02/keydelay.cpp",
"th01/vplanset.cpp",
"th02/pi_load.cpp",
"th02/frmdely1.cpp",
"th02/maine022.cpp",
"th02/input_rs.cpp",
"th02/exit.cpp",
"th02/snd_mmdr.c",
"th02/snd_mode.c",
"th02/snd_pmdr.c",
"th02/snd_load.cpp",
"th02/initmain.cpp",
"th02/pi_put.cpp",
"th02/snd_kaja.cpp",
"th02/snd_dlym.cpp",
"th02/globals.cpp",
"th02/maine_03.cpp",
"th02/maine_04.cpp",
"th02/staff.cpp",
})
-- ----
-- TH03
-- ----
local th03_sprites = Sprites({
{ "th03/sprites/score.bmp", "asm", "sSCORE_FONT", 8, 8, "-u" },
})
th03:zungen("bin/th03/zun.com", {
{ "-1", "libs/kaja/ongchk.com" },
{ "-2", th02_zuninit },
{ "-3", th01_zunsoft },
{ "-4", th03:branch(MODEL_ASM):link("zunsp", { sprite16 }) },
{ "-5", th03:branch(MODEL_TINY):link("res_yume", {
"th03/res_yume.cpp",
"bin/masters.lib",
})}
})
th03:branch(MODEL_LARGE, { cflags = "-DBINARY='O'" }):link("op", {
"th03/op_01.cpp",
"th03_op2.asm",
"th03/op_music.cpp",
"th03/op_02.cpp",
"th03/scoredat.cpp",
"th03/op_03.cpp",
"th03_op.asm",
"th02/exit_dos.cpp",
"th01/vplanset.cpp",
"th02/snd_mode.c",
"th02/snd_pmdr.c",
"th02/snd_load.cpp",
"th03/exit.cpp",
"th03/polar.cpp",
"th03/cdg_put.asm",
"th02/frmdely1.cpp",
"th03/input_s.cpp",
"th03/pi_put.cpp",
"th03/snd_kaja.cpp",
"th03/initop.cpp",
"th03/cdg_load.cpp",
"th03/grppsafx.cpp",
"th03/pi_load.cpp",
"th03/inp_m_w.cpp",
"th03/cdg_p_na.asm",
"th03/hfliplut.asm",
"th02/frmdely2.cpp",
})
th03:branch(MODEL_LARGE):link("main", {
{ "th03_main.asm", extra_inputs = th03_sprites["score"] },
"th03/playfld.cpp",
"th03/cfg_lres.cpp",
"th03/hitcirc.cpp",
"th03/player_m.cpp",
"th03/main_010.cpp",
"th03/main_011.cpp",
"th01/vplanset.cpp",
"th02/snd_mode.c",
"th02/snd_pmdr.c",
"th03/vector.cpp",
"th03/exit.cpp",
"th03/polar.cpp",
"th02/frmdely1.cpp",
"th03/input_s.cpp",
"th02/snd_se_r.cpp",
"th03/snd_se.cpp",
"th03/snd_kaja.cpp",
"th03/initmain.cpp",
"th03/pi_load.cpp",
"th03/inp_m_w.cpp",
"th03/collmap.asm",
"th03/hfliplut.asm",
"th03/mrs.cpp",
"th03/sprite16.cpp",
})
th03:branch(MODEL_LARGE, { cflags = "-DBINARY='L'" }):link("mainl", {
"th03/cfg_lres.cpp",
"th03/mainl_sc.cpp",
"th03_mainl.asm",
"th03/cutscene.cpp",
"th03/scoredat.cpp",
"th03/regist.cpp",
"th01/vplanset.cpp",
"th02/snd_mode.c",
"th02/snd_pmdr.c",
"th02/snd_dlyv.c",
"th02/snd_load.cpp",
"th03/vector.cpp",
"th03/exit.cpp",
"th03/cdg_put.asm",
"th02/frmdely1.cpp",
"th03/input_s.cpp",
"th03/pi_put.cpp",
"th03/pi_put_i.cpp",
"th02/snd_se_r.cpp",
"th03/snd_se.cpp",
"th03/snd_kaja.cpp",
"th03/initmain.cpp",
"th03/cdg_load.cpp",
"th03/exitmain.cpp",
"th03/grppsafx.cpp",
"th03/snd_dlym.cpp",
"th03/inp_wait.cpp",
"th03/pi_load.cpp",
"th03/pi_put_q.cpp",
"th03/inp_m_w.cpp",
"th03/cdg_p_na.asm",
"th03/hfliplut.asm",
})
-- ----
-- TH04
-- ----
local th04_sprites = Sprites({
{"th04/sprites/pelletbt.bmp", "asm", "sPELLET_BOTTOM", 8, 4, "-pshf outer"},
{"th04/sprites/pointnum.bmp", "asm", "sPOINTNUMS", 8, 8, "-pshf inner"},
})
local th04_zuncom = th04:zungen("obj/th04/zuncom.bin", {
{ "-O", "libs/kaja/ongchk.com" },
{ "-I", th04:branch(MODEL_ASM):link("zuninit", { "th04_zuninit.asm" }) },
{ "-S", th04:branch(MODEL_TINY):link("res_huma", {
"th04/res_huma.cpp",
"bin/masters.lib",
}) },
{ "-M", th04:branch(MODEL_TINY):link("memchk", { "th04_memchk.asm" }) },
})
th04:comcstm("zun.com", "th04/zun.txt", th04_zuncom, 621381155)
th04:branch(MODEL_LARGE):link("op", {
"th04/op_main.cpp",
{ "th04_op_master.asm", o = "opm.obj" },
"th01/vplanset.cpp",
"th02/frmdely1.cpp",
"th03/pi_put.cpp",
"th03/pi_load.cpp",
"th03/hfliplut.asm",
"th04/input_w.cpp",
"th04/vector.cpp",
"th04/snd_pmdr.c",
"th04/snd_mmdr.c",
"th04/snd_kaja.cpp",
"th04/cdg_p_nc.asm",
"th04/snd_mode.cpp",
"th04/snd_dlym.cpp",
"th02/exit_dos.cpp",
"th04/snd_load.cpp",
"th04/grppsafx.asm",
"th04_op2.asm",
"th04/cdg_put.asm",
"th04/exit.cpp",
"th04/initop.cpp",
"th04/cdg_p_na.cpp",
"th04/input_s.asm",
"th02/snd_se_r.cpp",
"th04/snd_se.cpp",
"th04/egcrect.cpp",
"th04/bgimage.cpp",
"th04/bgimager.asm",
"th04/cdg_load.asm",
"th02/frmdely2.cpp",
"th04/op_setup.cpp",
"th04/zunsoft.cpp",
"th04/op_music.cpp",
"th04_op.asm",
"th04/m_char.cpp",
})
th04:branch(MODEL_LARGE):link("main", {
{ "th04_main.asm", extra_inputs = {
th02_sprites["pellet"],
th02_sprites["sparks"],
th04_sprites["pelletbt"],
th04_sprites["pointnum"],
} },
"th04/slowdown.cpp",
"th04/demo.cpp",
"th04/ems.cpp",
"th04/tile_set.cpp",
"th04/std.cpp",
"th04/tile.cpp",
"th04/playfld.cpp",
"th04/midboss4.cpp",
"th04/f_dialog.cpp",
"th04/dialog.cpp",
"th04/boss_exp.cpp",
"th04/stages.cpp",
"th04/player_m.cpp",
"th04/player_p.cpp",
"th04/scoreupd.asm",
"th04/hud_ovrl.cpp",
"th04/cfg_lres.cpp",
"th04/checkerb.cpp",
"th04/mb_inv.cpp",
"th04/boss_bd.cpp",
"th01/vplanset.cpp",
"th03/vector.cpp",
"th02/frmdely1.cpp",
"th03/hfliplut.asm",
"th04/mpn_free.cpp",
"th04/input_w.cpp",
"th04/mpn_l_i.cpp",
"th04/vector.cpp",
"th04/snd_pmdr.c",
"th04/snd_mmdr.c",
"th04/snd_kaja.cpp",
"th04/snd_mode.cpp",
"th04/snd_load.cpp",
"th04/cdg_put.asm",
"th04/exit.cpp",
"th04/initmain.cpp",
"th04/cdg_p_na.cpp",
"th04/cdg_p_pr.asm",
"th04/input_s.asm",
"th02/snd_se_r.cpp",
"th04/snd_se.cpp",
"th04/cdg_load.asm",
"th04/gather.cpp",
"th04/scrolly3.cpp",
"th04/motion_3.asm",
"th04/midboss.cpp",
"th04/hud_hp.cpp",
"th04/mb_dft.cpp",
"th04/vector2n.asm",
"th04/spark_a.asm",
"th04/grcg_3.cpp",
"th04/it_spl_u.cpp",
"th04/boss_4m.cpp",
"th04/bullet_u.cpp",
"th04/bullet_a.cpp",
"th04/boss.cpp",
"th04/boss_4r.cpp",
"th04/boss_x2.cpp",
})
th04:branch(MODEL_LARGE):link("maine", {
"th04/maine_e.cpp",
{ "th04_maine_master.asm", o = "mainem.obj" },
"th01/vplanset.cpp",
"th02/frmdely1.cpp",
"th03/pi_put.cpp",
"th03/pi_load.cpp",
"th03/pi_put_q.cpp",
"th03/hfliplut.asm",
"th04/input_w.cpp",
"th04/vector.cpp",
"th04/snd_pmdr.c",
"th04/snd_mmdr.c",
"th04/snd_kaja.cpp",
"th04/snd_mode.cpp",
"th04/snd_dlym.cpp",
"th04/cdg_p_pl.asm",
"th04/snd_load.cpp",
"th04/grppsafx.asm",
"th04_maine.asm",
"th04/cdg_put.asm",
"th04/exit.cpp",
"th04/initmain.cpp",
"th04/input_s.asm",
"th02/snd_se_r.cpp",
"th04/snd_se.cpp",
"th04/bgimage.cpp",
"th04/bgimager.asm",
"th04/cdg_load.asm",
"th04/cutscene.cpp",
"th04/staff.cpp",
})
-- ----
-- TH05
-- ----
local th05_sprites = Sprites({
{ "th05/sprites/gaiji.bmp", "asm", "sGAIJI", 16, 16 },
{ "th05/sprites/piano_l.bmp", "asm", "sPIANO_LABEL_FONT", 8, 8 },
})
local th05_zuncom = th05:zungen("obj/th05/zuncom.bin", {
{ "-O", "libs/kaja/ongchk.com" },
{ "-I", th05:branch(MODEL_ASM):link("zuninit", { "th05_zuninit.asm" }) },
{ "-S", th05:branch(MODEL_TINY):link("res_kso", {
"th05/res_kso.cpp",
"bin/masters.lib",
}) },
{ "-G", th05:branch(MODEL_ASM):link("gjinit", {
{ "th05_gjinit.asm", extra_inputs = th05_sprites["gaiji"] },
}) },
{ "-M", th05:branch(MODEL_ASM):link("memchk", { "th05_memchk.asm" }) },
})
th05:comcstm("zun.com", "th05/zun.txt", th05_zuncom, 628731748)
th05:branch(MODEL_LARGE):link("op", {
"th05/op_main.cpp",
{ "th05_op_master.asm", o = "opm.obj" },
"th03/hfliplut.asm",
"th04/snd_pmdr.c",
"th04/snd_mmdr.c",
"th04/snd_mode.cpp",
"th02/exit_dos.cpp",
"th04/grppsafx.asm",
{ "th05_op2.asm", extra_inputs = th05_sprites["piano_l"] },
"th04/cdg_p_na.cpp",
"th02/snd_se_r.cpp",
"th04/snd_se.cpp",
"th04/bgimage.cpp",
"th05/cdg_put.asm",
"th04/exit.cpp",
"th05/vector.cpp",
"th05/musicp_c.cpp",
"th05/musicp_a.asm",
"th05/bgimager.asm",
"th05/snd_load.cpp",
"th05/snd_kaja.cpp",
"th05/pi_cpp_1.cpp",
"th05/pi_asm_1.asm",
"th05/pi_cpp_2.cpp",
"th05/pi_asm_2.asm",
"th05/initop.cpp",
"th05/input_s.asm",
"th05/inp_h_w.cpp",
"th05/snd_dlym.cpp",
"th05/cdg_p_nc.cpp",
"th05/frmdelay.cpp",
"th04/cdg_load.asm",
"th05/egcrect.cpp",
"th05/op_setup.cpp",
"th04/zunsoft.cpp",
"th05/cfg.cpp",
"th05/op_title.cpp",
"th05/op_music.cpp",
"th05_op.asm",
"th05/hi_view.cpp",
"th05/m_char.cpp",
})
th05:branch(MODEL_LARGE):link("main", {
{ "th05_main.asm", extra_inputs = {
th02_sprites["pellet"],
th02_sprites["sparks"],
th04_sprites["pelletbt"],
th04_sprites["pointnum"],
} },
"th04/slowdown.cpp",
"th05/demo.cpp",
"th05/ems.cpp",
"th05/cfg_lres.cpp",
"th04/tile.cpp",
"th05/main010.cpp",
"th05/f_dialog.cpp",
"th05/dialog.cpp",
"th05/boss_exp.cpp",
"th05/playfld.cpp",
"th04/mb_inv.cpp",
"th04/boss_bd.cpp",
"th05/boss_bg.cpp",
"th05/laser_rh.cpp",
"th05/p_common.cpp",
"th05/p_reimu.cpp",
"th05/p_marisa.cpp",
"th05/p_mima.cpp",
"th05/p_yuuka.cpp",
"th05/player.asm",
"th05/hud_bar.asm",
"th05/scoreupd.asm",
"th05/midboss5.cpp",
"th05/hud_ovrl.cpp",
"th04/player_p.cpp",
"th04/vector2n.asm",
"th05/spark_a.asm",
"th05/bullet_p.cpp",
"th04/grcg_3.cpp",
"th05/player_a.cpp",
"th05/bullet_1.asm",
"th05/bullet_c.cpp",
"th05/bullet.asm",
"th05/bullet_t.cpp",
"th03/vector.cpp",
"th03/hfliplut.asm",
"th04/snd_pmdr.c",
"th04/snd_mmdr.c",
"th04/snd_mode.cpp",
"th04/cdg_p_na.cpp",
"th02/snd_se_r.cpp",
"th04/snd_se.cpp",
"th05/cdg_put.asm",
"th04/exit.cpp",
"th05/vector.cpp",
"th05/snd_load.cpp",
"th05/snd_kaja.cpp",
"th05/initmain.cpp",
"th05/input_s.asm",
"th05/inp_h_w.cpp",
"th05/frmdelay.cpp",
"th04/cdg_load.asm",
"th04/scrolly3.cpp",
"th04/motion_3.asm",
"th05/gather.cpp",
"th05/main032.cpp",
"th05/midboss.cpp",
"th04/hud_hp.cpp",
"th05/mb_dft.cpp",
"th05/laser.cpp",
"th05/cheeto_u.cpp",
"th04/it_spl_u.cpp",
"th05/bullet_u.cpp",
"th05/midboss1.cpp",
"th05/boss_1.cpp",
"th05/boss_4.cpp",
"th05/boss_6.cpp",
"th05/boss_x.cpp",
"th05/boss.cpp",
"th05/main014.cpp",
})
th05:branch(MODEL_LARGE):link("maine", {
"th05/maine_e.cpp",
{ "th05_maine_master.asm", o = "mainem.obj" },
"th03/hfliplut.asm",
"th04/snd_pmdr.c",
"th04/snd_mmdr.c",
"th04/snd_mode.cpp",
"th04/grppsafx.asm",
"th05_maine.asm",
"th04/cdg_p_na.cpp",
"th02/snd_se_r.cpp",
"th04/snd_se.cpp",
"th04/bgimage.cpp",
"th04/exit.cpp",
"th05/vector.cpp",
"th05/bgimager.asm",
"th05/snd_load.cpp",
"th05/snd_kaja.cpp",
"th05/pi_cpp_1.cpp",
"th05/pi_asm_1.asm",
"th05/pi_cpp_2.cpp",
"th05/pi_asm_2.asm",
"th05/initmain.cpp",
"th05/input_s.asm",
"th05/inp_h_w.cpp",
"th05/snd_dlym.cpp",
"th05/frmdelay.cpp",
"th04/cdg_load.asm",
"th05/egcrect.cpp",
"th05/cutscene.cpp",
"th05/regist.cpp",
"th05/staff.cpp",
})
-- ----
-- Research
-- --------
local research_cfg = optimized_cfg:branch(Subdir("Research/"), MODEL_SMALL)
research_cfg:link("holdkey", {
"Research/holdkey.c",
"bin/masters.lib",
})
local research_sprites = Sprites({
{ "Research/blitperf.bmp", "cpp", "sBLITPERF", 16, 16 }
})
-- Must be an ordered table to retain the order for `build_dumb.bat`.
for _, t in pairs({ { "8086", " -1-" }, { "286", " -2" }, { "386", "" } }) do
local cfg = research_cfg:branch({
obj_root = (t[1] .. "/"),
cflags = string.format("-DCPU=%s%s", t[1], t[2]),
})
cfg:link(("blit" .. t[1]), {
-- Bypass `PreviousOutputForSource` by explicitly building each unit.
cfg:build_uncached({ "Research/blitperf.cpp", extra_inputs = {
research_sprites["blitperf"],
th01_sprites["pellet"],
} }),
cfg:build_uncached("platform/x86real/noexcept.cpp"),
cfg:build_uncached("platform/x86real/pc98/blitter.cpp"),
cfg:build_uncached("platform/x86real/pc98/font.cpp"),
cfg:build_uncached("platform/x86real/pc98/graph.cpp"),
cfg:build_uncached("platform/x86real/pc98/grcg.cpp"),
cfg:build_uncached("platform/x86real/pc98/palette.cpp"),
cfg:build_uncached("platform/x86real/pc98/vsync.cpp"),
})
end
-- --------
Rules:print()