scummvm/devtools/sci/scifx/scifx_to_cpp.py
matthewdippel 4f213d7a98 SCI: add typing to scifx_to_cpp script
Adding type hints to the various helper methods in this script
to make it easier to read and understand how the scifx parsing is
done.
2022-07-24 12:01:27 +03:00

232 lines
6.4 KiB
Python

from __future__ import print_function
import sys
from typing import List, Tuple, Any
def Chunker(seq: List[Any], size: int) -> List[List[Any]]:
return (seq[pos:pos + size] for pos in range(0, len(seq), size))
def ModToIndex(mods: List[Tuple[int]], m: int):
try:
return mods.index(m)
except ValueError:
mods.append(m)
return len(mods)-1
def PrintMods(gid: str, mods: List[Tuple[int]]):
L = [ "\t{ " + ", ".join( [ "%4d" % (round(128 * (val - 1)),) for val in m ] ) + " }" for m in mods ]
print("static const PaletteMod paletteMods" + gid + "[] = {")
print( ",\n".join(L) )
print("};")
def PrintPic(gid: str, pics: List[List[int]], comments: List[str]):
print("static const PicMod picMods" + gid + "[] = {")
for comment in comments:
print("\t// " + comment)
for chunk in Chunker(pics, 5):
t = ""
for pic in chunk:
t = t + "{ " + str(pic[0]).rjust(3, ' ') + ", " + str(pic[1]).rjust(2, ' ') + " }, "
print("\t" + t)
print("};")
def PrintView(gid: str, views: List[List[int]], comments: List[str]):
print("static const ViewMod viewMods" + gid + "[] = {")
for comment in comments:
print("\t// " + comment)
for chunk in Chunker(views, 5):
t = ""
for view in chunk:
t = t + "{ " + str(view[0]).rjust(3, ' ') + ", " + str(view[1]).rjust(2, ' ') + ", " + str(view[2]).rjust(2, ' ') + ", " + str(view[3]).rjust(2, ' ') + " }, "
print("\t" + t)
print("};")
def ParseList(l: str) -> Tuple[str, List[str]]:
assert(l[0] == '(')
e = l.find(")")
L = l[1:e].split(",")
tests = []
for t in L:
t = t.strip()
ell = t.find('..')
if ell >= 0:
start = int(t[0:ell])
end = int(t[ell+2:])
# interval
for x in range(start, end + 1):
tests.append(str(x))
else:
tests.append(t)
return l[e+1:], tests
def ParseTriple(l: str) -> List[str]:
assert(l[0] == '(')
e = l.find(")")
L = l[1:e].split(",")
assert(len(L) == 3)
return L
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python scifx_to_header.py [scifx files] > scifx.cpp")
sys.exit(-1)
print("""
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// NB: This file is AUTO-GENERATED by devtools/sci/scifx/scifx_to_cpp.py
// from devtools/sci/scifx/*.scifx
#include "sci/graphics/helpers.h"
#include "sci/graphics/screen.h"
namespace Sci {
""")
input_files = sys.argv[1:]
gids = []
for F in input_files:
comments = []
pics = []
views = []
mods = [(1.,1.,1.)]
gid = ""
for l in open(F, "r").readlines():
l = l.strip()
if len(l) == 0:
continue
if l[0] == '#':
comment = l[1:].strip()
# Only add the top comments (before the game ID is set)
if (gid == ""):
comments.append(comment)
continue
if l[0:6] == "gameid":
assert(gid == "")
l = l[6:].strip()
l = l.strip()
assert(l[0] == "=")
assert(l[-1] == ";")
l = l[1:-1].strip()
gid = l
continue
if l[0:4] == "view":
ruletype = "view"
l = l[4:]
elif l[0:3] == "pic":
ruletype = "pic"
l = l[3:]
else:
assert(False)
ids = []
loops = [-1]
cels = [-1]
l,ids = ParseList(l)
if l[0] == "(":
l,loops = ParseList(l)
if l[0] == "(":
l,cels = ParseList(l)
l = l.strip()
assert(l[0:2] == "*=")
assert(l[-1] == ";")
l = l[2:-1].strip()
if l[0] == "(":
val = ParseTriple(l)
val = (float(v) for v in val)
else:
val = (float(l), float(l), float(l))
if ruletype == "pic":
for pic in ids:
pics.append([pic, ModToIndex(mods, val)])
elif ruletype == "view":
for view in ids:
for loop in loops:
for cel in cels:
views.append([view, loop, cel, ModToIndex(mods, val)])
if gid == "":
raise ValueError("No gameid specified")
gids.append(gid)
PrintMods(gid, mods)
print()
PrintPic(gid, pics, comments)
print()
PrintView(gid, views, comments)
print()
print("static const SciFxMod mods[] = {")
for gid in gids:
print("\t{{ gid_{0}, paletteMods{0}, ARRAYSIZE(paletteMods{0}), picMods{0}, ARRAYSIZE(picMods{0}), viewMods{0}, ARRAYSIZE(viewMods{0}) }},".format(gid));
print("};")
print("""
void setupCustomPaletteMods(GfxScreen *screen) {
for (int i = 0; i < ARRAYSIZE(mods); i++) {
if (mods[i].gameId == g_sci->getGameId()) {
screen->setPaletteMods(mods[i].paletteMods, mods[i].paletteModsSize);
break;
}
}
}
void doCustomViewPalette(GfxScreen *screen, GuiResourceId view, int16 loop, int16 cel) {
for (int i = 0; i < ARRAYSIZE(mods); i++) {
SciFxMod mod = mods[i];
if (mod.gameId == g_sci->getGameId()) {
for (int j = 0; j < mod.viewModsSize; j++) {
ViewMod m = mod.viewMods[j];
if (m.id == view && (m.loop == -1 || m.loop == loop) && (m.cel == -1 || m.cel == cel)) {
screen->setCurPaletteMapValue(m.multiplier);
break;
}
}
break;
}
}
}
void doCustomPicPalette(GfxScreen *screen, GuiResourceId pic) {
for (int i = 0; i < ARRAYSIZE(mods); i++) {
SciFxMod mod = mods[i];
if (mod.gameId == g_sci->getGameId()) {
for (int j = 0; j < mod.picModsSize; j++) {
PicMod m = mod.picMods[j];
if (m.id == pic) {
screen->setCurPaletteMapValue(m.multiplier);
break;
}
}
break;
}
}
}
}""")