349 lines
10 KiB
Python
349 lines
10 KiB
Python
# ScummVM - Graphic Adventure Engine
|
|
# Copyright (C) 2020 Stryzhniou Fiodar
|
|
|
|
# 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 2
|
|
# 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, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
from __future__ import with_statement
|
|
import os, shutil
|
|
from collections import defaultdict as defdict
|
|
from common_names import *
|
|
|
|
|
|
#ignore unfinished engines in release build
|
|
def CheckForRelease(line_):
|
|
if 'no' in line_:
|
|
return build != 'release'
|
|
else:
|
|
return True
|
|
|
|
|
|
# This function is frozen! Don't edit!
|
|
def processengine(path):
|
|
with open(os.path.join(path, "configure.engine")) as f:
|
|
ff = f.readlines()
|
|
ff = [n for n in ff if not n.startswith('# ')] #exclude comments
|
|
ff = [n for n in ff if len(n) > 2]
|
|
ff = [n.split('"', 2) for n in ff]
|
|
try:
|
|
tt = [n[0] + n[2] for n in ff]
|
|
ff = tt
|
|
except IndexError:
|
|
print "Something wrong here:"
|
|
print ff
|
|
return None
|
|
f = [n.split() for n in ff]
|
|
|
|
if f[0][2] == 'no' and build == "release":
|
|
return None
|
|
# print "MACRO ENABLE_%s // LIB:scummvm_%s.lib" %(f[0][1].upper(), f[0][1])
|
|
buildparam = ["MACRO ENABLE_%s // LIB:scummvm_%s.lib" %(f[0][1].upper(), f[0][1])]
|
|
libname = ["STATICLIBRARY scummvm_%s.lib" %f[0][1]]
|
|
|
|
if len(f) == 1:
|
|
return [buildparam, libname]
|
|
|
|
if len(f[0]) > 3:
|
|
f = f[1:]
|
|
|
|
for i in f:
|
|
if CheckForRelease(i[2]):
|
|
# print " MACRO ENABLE_%s // Subengine" %i[1].upper()
|
|
buildparam += [" MACRO ENABLE_%s // Subengine" %i[1].upper()]
|
|
|
|
return [buildparam, libname]
|
|
|
|
|
|
# This function is frozen! Don't edit!
|
|
def processModule_mk(path, buildparams):
|
|
with open(os.path.join(path, "module.mk")) as ff:
|
|
f = ff.readlines()
|
|
|
|
src = []
|
|
addsrc = None
|
|
|
|
for i in f:
|
|
#add engine base source code first
|
|
if "MODULE_OBJS" in i:
|
|
if addsrc is None:
|
|
addsrc = True
|
|
elif "ifdef ENABLE_" in i:
|
|
for x in buildparams:
|
|
if "MACRO %s"%i.strip()[6:] in x:
|
|
addsrc = True
|
|
src += ["// Subengine %s" %x[18:]]
|
|
elif "KYRARPG_COMMON_OBJ" in i: #special case for kyra engine
|
|
addsrc = True
|
|
elif "DETECT_OBJS" in i:
|
|
cpp = i.rstrip()
|
|
cpp = cpp.rsplit('$')[-1]
|
|
cpp = cpp[9:-2]
|
|
src += ["SOURCE %s.cpp" %cpp]
|
|
elif addsrc is True:
|
|
# if i.endswith(".o \\"): # this dont work, why?
|
|
if ".o \\" in i[-5:]:
|
|
src += ["SOURCE %s.cpp" %i[1:-5]]
|
|
elif ".o" in i[-3:]:
|
|
src += ["SOURCE %s.cpp" %i[1:-3]]
|
|
elif len(i) == 1:
|
|
addsrc = False
|
|
return src
|
|
|
|
|
|
# Add per engine fixes
|
|
libc_engines = ("ags", "bladerunner", "glk", "illusions", "nancy", "stark", "titanic", "ultima")
|
|
def CheckEngine(lst, game):
|
|
if game == "sword25":
|
|
return None
|
|
if game == "testbed":
|
|
return None
|
|
if game in libc_engines:
|
|
lst = lst + "\nOPTION GCCE -I'/Symbian/S60_5th_Edition_SDK_v1.0/epoc32/include/libc'\n"
|
|
if game == "zvision":
|
|
lst = lst + "\nMACRO USE_A52\n"
|
|
return lst
|
|
|
|
|
|
def ProcessDup(src):
|
|
"""Function saves file duplicates with new name, origin remains as is."""
|
|
ourDict = defdict(list)
|
|
destDict = {}
|
|
for item in src:
|
|
if "SOURCE" in item:
|
|
t = item.split()[1]
|
|
destDict[t] = t
|
|
m = os.path.split(t)
|
|
ourDict.setdefault(m[1], []).append(m[0])
|
|
|
|
ourDict = dict((k, v) for k, v in ourDict.iteritems() if len(v) > 1)
|
|
|
|
result = src
|
|
if( len(ourDict.values()) > 0):
|
|
result = []
|
|
fixed = FindDup(ourDict)
|
|
for item in src:
|
|
if "SOURCE" in item:
|
|
dst = item.split()[1]
|
|
if dst in fixed:
|
|
d = item.replace(dst, fixed[dst])
|
|
result.append(d)
|
|
else:
|
|
result.append(item)
|
|
ourDict.clear()
|
|
return result
|
|
|
|
|
|
def FindDup(files):
|
|
val = {}
|
|
# print "File duplicates found:\n %s" %files
|
|
keys = files.keys()
|
|
# print "for keys: %s" %keys
|
|
for k in keys:
|
|
for v in files[k]:
|
|
if len(v) > 0:
|
|
t = MakeRenamePair(v, k)
|
|
src = os.path.join(currentEngine, t[0])
|
|
dst = os.path.join(currentEngine, t[1])
|
|
val[t[0]] = t[1]
|
|
# if(os.path.exists(dst)): # todo: fix possible file duplicates
|
|
# dst = str(hash(dst)) + dst
|
|
# print "Rename file %s to %s" %(src, dst)
|
|
shutil.copyfile(src, dst)
|
|
t = open(dst) # Fail if file not exist
|
|
t.close()
|
|
return val
|
|
|
|
|
|
def MakeRenamePair(val, key):
|
|
# nuvie/core + events.cpp -> nuvie_core + events.cpp -> nuvie/core + nuvie_core_events.cpp -> nuvie/core/nuvie_core_events.cpp
|
|
v = val.replace("/", "_")
|
|
k = v + "_" + key # nuvie_core_events.cpp
|
|
newFile = val + "/" + k #nuvie/core/nuvie_core_events.cpp
|
|
oldFile = val + "/" + key
|
|
#if newFile exists: nuvie_core_events.cpp -> (hash)_nuvie_core_events.cpp
|
|
return [oldFile, newFile]
|
|
|
|
|
|
# This function is frozen! Don't edit!
|
|
def SafeWriteFile(path, mode, data):
|
|
"""Save list elments as strings. Save strings as is"""
|
|
with open(path, mode) as f:
|
|
if type(data) is list:
|
|
for s in data:
|
|
f.write(s + '\n')
|
|
else:
|
|
f.write(data)
|
|
|
|
|
|
def FilterUltima(src):
|
|
src = [x for x in src if "nuvie" not in x] #Ultima VI
|
|
src = [x for x in src if "ultima4" not in x]
|
|
print "Exclude nuvie and ultima4 engines from detection_tables.h and detection.cpp!"
|
|
return src
|
|
|
|
|
|
def FilterGrim(src):
|
|
src += ["#if !defined(WINS)"]
|
|
src += ["SOURCE movie/codecs/blocky8ARM.s"]
|
|
src += ["#endif"]
|
|
return src
|
|
|
|
|
|
def FilterScumm(src):
|
|
src += ["#if !defined(WINS)"]
|
|
src += ["SOURCE proc3ARM.s"]
|
|
src += ["SOURCE gfxARM.s"]
|
|
src += ["SOURCE smush/codec47ARM.s"]
|
|
src += ["#endif"]
|
|
return src
|
|
|
|
|
|
def FilterSrcs(src, engine):
|
|
if "grim" in engine:
|
|
return FilterGrim(src)
|
|
if "ultima" in engine:
|
|
return FilterUltima(src)
|
|
if "scumm" in engine:
|
|
return FilterScumm(src)
|
|
# if "" in engine:
|
|
# return Filter(src)
|
|
return src
|
|
|
|
|
|
guard_macro = "#ifdef SCUMMVM_PT_%s\n#endif // SCUMMVM_PT_%s\n"
|
|
ro_warning = """
|
|
// This is autogenerated file.\n\n
|
|
/* Warning! Carbide can silently change file.
|
|
Set read-onle attribute after manual update!!! */
|
|
"""
|
|
|
|
def MakeMMP(engine):
|
|
global firstRun, currentEngine
|
|
print "Start processing engine: %s" %engine
|
|
|
|
pth = os.path.join(pt, engine)
|
|
currentEngine = pth
|
|
tt = processengine(pth)
|
|
if tt is None:
|
|
return
|
|
|
|
macrolist = tt[0]
|
|
staticlib = tt[1]
|
|
|
|
src = processModule_mk(pth, macrolist)
|
|
src = ProcessDup(src)
|
|
src = FilterSrcs(src, engine)
|
|
|
|
mmp = """TARGET scummvm_%s.lib
|
|
TARGETTYPE lib\n
|
|
#include "../S60v3/build_config.mmh"
|
|
|
|
#include "build_parts.mmh"
|
|
#include "../S60v3/macros.mmh"\n
|
|
USERINCLUDE ..\..\..\..\engines\%s\n
|
|
// *** SOURCE files
|
|
SOURCEPATH ..\..\..\..\engines\%s\n
|
|
""" %(engine, engine, engine)
|
|
|
|
print "TARGET scummvm_%s.lib" %engine
|
|
mmp = CheckEngine(mmp, engine)
|
|
if mmp is None:
|
|
return
|
|
|
|
plugins_table = """
|
|
#if PLUGIN_ENABLED_STATIC(%s)
|
|
LINK_PLUGIN(%s)
|
|
#endif
|
|
""" %(engine.upper(), engine.upper())
|
|
|
|
detection_table = """
|
|
#if defined(ENABLE_%s) || defined(DETECTION_FULL)
|
|
LINK_PLUGIN(%s_DETECTION)
|
|
#endif
|
|
""" %(engine.upper(), engine.upper())
|
|
|
|
bldinf = os.path.join(local, "bld.inf")
|
|
mmpfile = os.path.join(local, "%s.mmp" %engine)
|
|
ptable = os.path.join(pt, "plugins_table.h")
|
|
dtable = os.path.join(pt, "detection_table.h")
|
|
macros = os.path.join(local, "macros.mmh")
|
|
engines = os.path.join(local, "engines.mmh")
|
|
#create files and add bld.inf header
|
|
if firstRun is True:
|
|
SafeWriteFile(bldinf, 'w', "PRJ_MMPFILES\n")
|
|
if(build == 'release'):
|
|
SafeWriteFile(macros, 'w', "MACRO RELEASE_BUILD\n")
|
|
guard_macros = [guard_macro %(i + 1, i + 1) for i in range(len(uids))]
|
|
SafeWriteFile(macros, 'w', ro_warning)
|
|
SafeWriteFile(macros, 'a', guard_macros)
|
|
SafeWriteFile(ptable, 'w', "// This is autogenerated file.\n")
|
|
SafeWriteFile(dtable, 'w', "// This is autogenerated file.\n")
|
|
SafeWriteFile(engines, 'w', ro_warning)
|
|
SafeWriteFile(engines, 'a', guard_macros)
|
|
firstRun = False
|
|
|
|
SafeWriteFile(mmpfile, 'w', mmp)
|
|
SafeWriteFile(mmpfile, 'a', src)
|
|
|
|
SafeWriteFile(bldinf, 'a', "%s.mmp\n" %engine)
|
|
SafeWriteFile(macros, 'a', macrolist)
|
|
SafeWriteFile(engines, 'a', staticlib)
|
|
SafeWriteFile(ptable, 'a', plugins_table)
|
|
SafeWriteFile(dtable, 'a', detection_table)
|
|
currentEngine = None
|
|
print "End processing\n"
|
|
|
|
firstRun = True
|
|
currentEngine = None
|
|
pt = '..\..\..\engines'
|
|
local = mmps
|
|
|
|
# pt = 'e:\Scu\engines'
|
|
# local = pt
|
|
|
|
def count_sc_parts():
|
|
t = []
|
|
for i in range(len(uids)):
|
|
d = "#define SCUMMVM_PT_%d" %(i+1)
|
|
t.append(d)
|
|
pth = os.path.join(local, "build_parts.mmh")
|
|
SafeWriteFile(pth, 'w', ro_warning)
|
|
SafeWriteFile(pth, 'a', t)
|
|
|
|
def create_engine_mmps(arg = 'full'):
|
|
global build
|
|
build = arg
|
|
if not os.path.exists(local):
|
|
os.mkdir(local)
|
|
if(os.path.isfile(local)):
|
|
raise TypeError("Expected dir but file found %s" %pt)
|
|
if(local != pt):
|
|
if(os.path.isdir(local)):
|
|
try:
|
|
shutil.rmtree(local)
|
|
os.mkdir(local)
|
|
except: pass
|
|
t = os.listdir(pt)
|
|
[MakeMMP(m) for m in t if os.path.isdir(os.path.join(pt, m))]
|
|
count_sc_parts()
|
|
|
|
if __name__ == "__main__":
|
|
create_engine_mmps()
|
|
|
|
|