diff options
Diffstat (limited to 'devtools')
-rw-r--r-- | devtools/README | 2 | ||||
-rw-r--r-- | devtools/create_hugo/create_hugo.h | 14 | ||||
-rw-r--r-- | devtools/create_hugo/enums.h | 2 | ||||
-rw-r--r-- | devtools/create_kyradat/module.mk | 3 | ||||
-rw-r--r-- | devtools/create_lure/create_lure_dat.cpp | 2 | ||||
-rw-r--r-- | devtools/create_mads/parser.cpp | 6 | ||||
-rw-r--r-- | devtools/create_project/codeblocks/create_project.cbp | 2 | ||||
-rw-r--r-- | devtools/create_project/create_project.cpp | 47 | ||||
-rw-r--r-- | devtools/create_project/module.mk | 8 | ||||
-rw-r--r-- | devtools/create_project/msvc10/create_project.vcxproj | 8 | ||||
-rw-r--r-- | devtools/create_project/msvc10/create_project.vcxproj.filters | 6 | ||||
-rw-r--r-- | devtools/create_project/msvc8/create_project.vcproj | 8 | ||||
-rw-r--r-- | devtools/create_project/msvc9/create_project.vcproj | 8 | ||||
-rwxr-xr-x | devtools/create_project/xcode.cpp | 933 | ||||
-rw-r--r-- | devtools/create_project/xcode.h | 307 | ||||
-rw-r--r-- | devtools/create_project/xcode/create_project.xcodeproj/project.pbxproj | 255 | ||||
-rwxr-xr-x | devtools/credits.pl | 79 |
17 files changed, 1629 insertions, 61 deletions
diff --git a/devtools/README b/devtools/README index b1c0f21cb0..7db5259e7c 100644 --- a/devtools/README +++ b/devtools/README @@ -65,7 +65,7 @@ create_lure (dreammaster) create_project (LordHoto, Littleboy) -------------- - Creates project files for Visual Studio 2005, 2008, 2010 and + Creates project files for Visual Studio 2005, 2008, 2010, Xcode and Code::Blocks out of the configure / Makefile based build system. It also offers a way to enable or disable certain engines and the use of external libraries similar to configure. Run the tool without diff --git a/devtools/create_hugo/create_hugo.h b/devtools/create_hugo/create_hugo.h index 16d15fe317..e176dbb195 100644 --- a/devtools/create_hugo/create_hugo.h +++ b/devtools/create_hugo/create_hugo.h @@ -144,7 +144,7 @@ struct act1 { // Type 1 - Start an object cycle_t cycle; // Direction to start cycling }; -struct act2 { // Type 2 - Initialise an object coords +struct act2 { // Type 2 - Initialize an object coords byte actType; // The type of action int timer; // Time to set off the action int objNumb; // The object number @@ -168,21 +168,21 @@ struct act4 { // Type 4 - Set new backgrou long newBkgColor; // New color }; -struct act5 { // Type 5 - Initialise an object velocity +struct act5 { // Type 5 - Initialize an object velocity byte actType; // The type of action int timer; // Time to set off the action int objNumb; // The object number int vx, vy; // velocity }; -struct act6 { // Type 6 - Initialise an object carrying +struct act6 { // Type 6 - Initialize an object carrying byte actType; // The type of action int timer; // Time to set off the action int objNumb; // The object number bool carriedFl; // carrying }; -struct act7 { // Type 7 - Initialise an object to hero's coords +struct act7 { // Type 7 - Initialize an object to hero's coords byte actType; // The type of action int timer; // Time to set off the action int objNumb; // The object number @@ -194,14 +194,14 @@ struct act8 { // Type 8 - switch to new sc int screenIndex; // The new screen number }; -struct act9 { // Type 9 - Initialise an object state +struct act9 { // Type 9 - Initialize an object state byte actType; // The type of action int timer; // Time to set off the action int objNumb; // The object number byte newState; // New state }; -struct act10 { // Type 10 - Initialise an object path type +struct act10 { // Type 10 - Initialize an object path type byte actType; // The type of action int timer; // Time to set off the action int objNumb; // The object number @@ -290,7 +290,7 @@ struct act21 { // Type 21 - Gameover. Disa int timer; // Time to set off the action }; -struct act22 { // Type 22 - Initialise an object to hero's coords +struct act22 { // Type 22 - Initialize an object to hero's coords byte actType; // The type of action int timer; // Time to set off the action int objNumb; // The object number diff --git a/devtools/create_hugo/enums.h b/devtools/create_hugo/enums.h index 90cb1d54f3..f721c3d4f5 100644 --- a/devtools/create_hugo/enums.h +++ b/devtools/create_hugo/enums.h @@ -1376,7 +1376,7 @@ enum action_t { // Parameters: INIT_MAZE = 30, // 30 - Start special maze hotspot processing EXIT_MAZE = 31, // 31 - Exit special maze processing INIT_PRIORITY = 32, // 32 - Initialize fbg field - INIT_SCREEN = 33, // 33 - Initialise screen field of object + INIT_SCREEN = 33, // 33 - Initialize screen field of object AGSCHEDULE = 34, // 34 - Global schedule - lasts over new screen REMAPPAL = 35, // 35 - Remappe palette - palette index, color COND_NOUN = 36, // 36 - Conditional on noun appearing in line diff --git a/devtools/create_kyradat/module.mk b/devtools/create_kyradat/module.mk index fb458b43ff..4241f82e34 100644 --- a/devtools/create_kyradat/module.mk +++ b/devtools/create_kyradat/module.mk @@ -14,5 +14,8 @@ MODULE_OBJS := \ # Set the name of the executable TOOL_EXECUTABLE := create_kyradat +# Link against common code (for scumm_stricmp) +TOOL_DEPS := common/libcommon.a + # Include common rules include $(srcdir)/rules.mk diff --git a/devtools/create_lure/create_lure_dat.cpp b/devtools/create_lure/create_lure_dat.cpp index c55252410c..c53a6bf81d 100644 --- a/devtools/create_lure/create_lure_dat.cpp +++ b/devtools/create_lure/create_lure_dat.cpp @@ -1920,7 +1920,7 @@ bool validate_executable() { dataSegment = 0xAD20; printf("Detected Spanish version\n"); } else { - printf("Lure executable version not recognised. Checksum = %xh\n", sumTotal); + printf("Lure executable version not recognized. Checksum = %xh\n", sumTotal); return false; } diff --git a/devtools/create_mads/parser.cpp b/devtools/create_mads/parser.cpp index 2daaff0d33..0c6df43046 100644 --- a/devtools/create_mads/parser.cpp +++ b/devtools/create_mads/parser.cpp @@ -237,10 +237,10 @@ void close_source_file() { } /** - * Initialises the scanner + * Initializes the scanner */ void init_scanner(const char *name) { - // Initialise character table + // Initialize character table for (int i = 0; i < 256; ++i) char_table[i] = SPECIAL; for (int i = '0'; i <= '9'; ++i) char_table[i] = DIGIT; for (int i = 'A'; i <= 'Z'; ++i) char_table[i] = LETTER; @@ -265,7 +265,7 @@ void quit_scanner() { /** - * Initialises the output + * Initializes the output */ void init_output(const char *destFilename) { dest_file = fopen(destFilename, "wb"); diff --git a/devtools/create_project/codeblocks/create_project.cbp b/devtools/create_project/codeblocks/create_project.cbp index 25b12d8cc2..1b592d5e96 100644 --- a/devtools/create_project/codeblocks/create_project.cbp +++ b/devtools/create_project/codeblocks/create_project.cbp @@ -47,6 +47,8 @@ <Unit filename="..\msvc.h" /> <Unit filename="..\visualstudio.cpp" /> <Unit filename="..\visualstudio.h" /> + <Unit filename="..\xcode.cpp" /> + <Unit filename="..\xcode.h" /> <Extensions> <code_completion /> <envvars /> diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp index b75b22a290..29bc5bfcd5 100644 --- a/devtools/create_project/create_project.cpp +++ b/devtools/create_project/create_project.cpp @@ -28,11 +28,12 @@ #include "config.h" #include "create_project.h" -#include "codeblocks.h" +#include "codeblocks.h" #include "msvc.h" #include "visualstudio.h" #include "msbuild.h" +#include "xcode.h" #include <fstream> #include <iostream> @@ -107,13 +108,14 @@ typedef std::list<FSNode> FileList; enum ProjectType { kProjectNone, kProjectCodeBlocks, - kProjectMSVC + kProjectMSVC, + kProjectXcode }; int main(int argc, char *argv[]) { #ifndef USE_WIN32_API // Initialize random number generator for UUID creation - std::srand(std::time(0)); + std::srand((uint)std::time(0)); #endif if (argc < 2) { @@ -175,6 +177,14 @@ int main(int argc, char *argv[]) { projectType = kProjectMSVC; + } else if (!std::strcmp(argv[i], "--xcode")) { + if (projectType != kProjectNone) { + std::cerr << "ERROR: You cannot pass more than one project type!\n"; + return -1; + } + + projectType = kProjectXcode; + } else if (!std::strcmp(argv[i], "--msvc-version")) { if (i + 1 >= argc) { std::cerr << "ERROR: Missing \"version\" parameter for \"--msvc-version\"!\n"; @@ -463,6 +473,32 @@ int main(int argc, char *argv[]) { provider = new CreateProjectTool::MSBuildProvider(globalWarnings, projectWarnings, msvcVersion); break; + + case kProjectXcode: + //////////////////////////////////////////////////////////////////////////// + // Xcode is also using GCC behind the scenes. See Code::Blocks comment + // for info on all warnings + //////////////////////////////////////////////////////////////////////////// + globalWarnings.push_back("-Wall"); + globalWarnings.push_back("-Wno-long-long"); + globalWarnings.push_back("-Wno-multichar"); + globalWarnings.push_back("-Wno-unknown-pragmas"); + globalWarnings.push_back("-Wno-reorder"); + globalWarnings.push_back("-Wpointer-arith"); + globalWarnings.push_back("-Wcast-qual"); + globalWarnings.push_back("-Wcast-align"); + globalWarnings.push_back("-Wshadow"); + globalWarnings.push_back("-Wimplicit"); + globalWarnings.push_back("-Wnon-virtual-dtor"); + globalWarnings.push_back("-Wwrite-strings"); + // The following are not warnings at all... We should consider adding them to + // a different list of parameters. + globalWarnings.push_back("-fno-rtti"); + globalWarnings.push_back("-fno-exceptions"); + globalWarnings.push_back("-fcheck-new"); + + provider = new CreateProjectTool::XCodeProvider(globalWarnings, projectWarnings); + break; } provider->createProject(setup); @@ -501,6 +537,7 @@ void displayHelp(const char *exe) { "Project specific settings:\n" " --codeblock build Code::Blocks project files\n" " --msvc build Visual Studio project files\n" + " --xcode build XCode project files\n" " --file-prefix prefix allow overwriting of relative file prefix in the\n" " MSVC project files. By default the prefix is the\n" " \"path\\to\\source\" argument\n" @@ -636,7 +673,7 @@ bool setEngineBuildState(const std::string &name, EngineDescList &engines, bool if (engine != engines.end()) { engine->enable = enable; - // When we disable an einge, we also need to disable all the sub engines. + // When we disable an engine, we also need to disable all the sub engines. if (!enable && !engine->subEngines.empty()) { for (StringList::const_iterator j = engine->subEngines.begin(); j != engine->subEngines.end(); ++j) { EngineDescList::iterator subEngine = std::find(engines.begin(), engines.end(), *j); @@ -729,7 +766,6 @@ const Feature s_features[] = { { "flac", "USE_FLAC", "libFLAC_static", true, "FLAC support" }, { "png", "USE_PNG", "libpng", true, "libpng support" }, { "theora", "USE_THEORADEC", "libtheora_static", true, "Theora decoding support" }, - { "mpeg2", "USE_MPEG2", "libmpeg2", false, "mpeg2 codec for cutscenes" }, // Feature flags { "scalers", "USE_SCALERS", "", true, "Scalers" }, @@ -738,7 +774,6 @@ const Feature s_features[] = { { "mt32emu", "USE_MT32EMU", "", true, "integrated MT-32 emulator" }, { "nasm", "USE_NASM", "", true, "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling. { "opengl", "USE_OPENGL", "opengl32", true, "OpenGL support" }, - { "indeo3", "USE_INDEO3", "", true, "Indeo3 codec support"}, { "translation", "USE_TRANSLATION", "", true, "Translation support" }, { "vkeybd", "ENABLE_VKEYBD", "", false, "Virtual keyboard support"}, { "langdetect", "USE_DETECTLANG", "", true, "System language detection support" } // This feature actually depends on "translation", there diff --git a/devtools/create_project/module.mk b/devtools/create_project/module.mk index 4238452c5d..0db070fa7c 100644 --- a/devtools/create_project/module.mk +++ b/devtools/create_project/module.mk @@ -6,11 +6,17 @@ MODULE_OBJS := \ codeblocks.o \ msvc.o \ visualstudio.o \ - msbuild.o + msbuild.o \ + xcode.o # Set the name of the executable TOOL_EXECUTABLE := create_project +# Set custom build flags for create_project.o: It uses C++ iostreams, +# which make use of global constructors. So we don't want warnings for +# that. +$(srcdir)/devtools/create_project/create_project.o: CXXFLAGS:=$(filter-out -Wglobal-constructors,$(CXXFLAGS)) + # Include common rules include $(srcdir)/rules.mk diff --git a/devtools/create_project/msvc10/create_project.vcxproj b/devtools/create_project/msvc10/create_project.vcxproj index bf5e415b5d..3d7f8fdd3d 100644 --- a/devtools/create_project/msvc10/create_project.vcxproj +++ b/devtools/create_project/msvc10/create_project.vcxproj @@ -58,10 +58,12 @@ <TargetMachine>MachineX86</TargetMachine> </Link> <PostBuildEvent> - <Command>xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc10\ + <Command>@echo off +xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc10\ xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc9\ xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc8\ -xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\codeblocks\</Command> +xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\codeblocks\ +xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\iphone\</Command> </PostBuildEvent> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> @@ -98,6 +100,7 @@ xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\codeblocks\</Command> <ClCompile Include="..\msbuild.cpp" /> <ClCompile Include="..\msvc.cpp" /> <ClCompile Include="..\visualstudio.cpp" /> + <ClCompile Include="..\xcode.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="..\codeblocks.h" /> @@ -106,6 +109,7 @@ xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\codeblocks\</Command> <ClInclude Include="..\msbuild.h" /> <ClInclude Include="..\msvc.h" /> <ClInclude Include="..\visualstudio.h" /> + <ClInclude Include="..\xcode.h" /> </ItemGroup> <ItemGroup> <None Include="..\scripts\installer.vbs" /> diff --git a/devtools/create_project/msvc10/create_project.vcxproj.filters b/devtools/create_project/msvc10/create_project.vcxproj.filters index b5e870824e..5ecd6c3dde 100644 --- a/devtools/create_project/msvc10/create_project.vcxproj.filters +++ b/devtools/create_project/msvc10/create_project.vcxproj.filters @@ -27,6 +27,9 @@ <ClInclude Include="..\visualstudio.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\xcode.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="..\config.h"> <Filter>Header Files</Filter> </ClInclude> @@ -47,6 +50,9 @@ <ClCompile Include="..\visualstudio.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\xcode.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <None Include="..\scripts\prebuild.cmd"> diff --git a/devtools/create_project/msvc8/create_project.vcproj b/devtools/create_project/msvc8/create_project.vcproj index 639b23d6e7..6e9e0d5cb0 100644 --- a/devtools/create_project/msvc8/create_project.vcproj +++ b/devtools/create_project/msvc8/create_project.vcproj @@ -184,6 +184,10 @@ RelativePath="..\visualstudio.cpp" > </File> + <File + RelativePath="..\xcode.cpp" + > + </File> </Filter> <Filter Name="Header Files" @@ -214,6 +218,10 @@ RelativePath="..\visualstudio.h" > </File> + <File + RelativePath="..\xcode.h" + > + </File> </Filter> <Filter Name="Scripts" diff --git a/devtools/create_project/msvc9/create_project.vcproj b/devtools/create_project/msvc9/create_project.vcproj index f56cbd711c..dc914248fb 100644 --- a/devtools/create_project/msvc9/create_project.vcproj +++ b/devtools/create_project/msvc9/create_project.vcproj @@ -185,6 +185,10 @@ RelativePath="..\visualstudio.cpp" > </File> + <File + RelativePath="..\xcode.cpp" + > + </File> </Filter> <Filter Name="Header Files" @@ -215,6 +219,10 @@ RelativePath="..\visualstudio.h" > </File> + <File + RelativePath="..\xcode.h" + > + </File> </Filter> <Filter Name="Scripts" diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp new file mode 100755 index 0000000000..77ac88f85d --- /dev/null +++ b/devtools/create_project/xcode.cpp @@ -0,0 +1,933 @@ +/* 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 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. + * + */ + +#include "xcode.h" + +#include <fstream> +#include <algorithm> + +#if defined(_WIN32) || defined(WIN32) +#include <windows.h> +#else +#include <sys/param.h> +#include <sys/stat.h> +#include <dirent.h> +#include <errno.h> +#endif + +namespace CreateProjectTool { + +#define DEBUG_XCODE_HASH 0 + +#define ADD_DEFINE(defines, name) \ + defines.push_back(name); + +#define ADD_SETTING(config, key, value) \ + config.settings[key] = Setting(value, "", SettingsNoQuote); + +#define ADD_SETTING_ORDER(config, key, value, order) \ + config.settings[key] = Setting(value, "", SettingsNoQuote, 0, order); + +#define ADD_SETTING_ORDER_NOVALUE(config, key, comment, order) \ + config.settings[key] = Setting("", comment, SettingsNoValue, 0, order); + +#define ADD_SETTING_QUOTE(config, key, value) \ + config.settings[key] = Setting(value); + +#define ADD_SETTING_QUOTE_VAR(config, key, value) \ + config.settings[key] = Setting(value, "", SettingsQuoteVariable); + +#define ADD_SETTING_LIST(config, key, values, flags, indent) \ + config.settings[key] = Setting(values, flags, indent); + +#define REMOVE_SETTING(config, key) \ + config.settings.erase(key); + +#define ADD_BUILD_FILE(id, name, comment) { \ + Object *buildFile = new Object(this, id, name, "PBXBuildFile", "PBXBuildFile", comment); \ + buildFile->addProperty("fileRef", getHash(name), name, SettingsNoValue); \ + _buildFile.add(buildFile); \ + _buildFile.flags = SettingsSingleItem; \ +} + +#define ADD_FILE_REFERENCE(name, properties) { \ + Object *fileRef = new Object(this, name, name, "PBXFileReference", "PBXFileReference", name); \ + if (!properties.fileEncoding.empty()) fileRef->addProperty("fileEncoding", properties.fileEncoding, "", SettingsNoValue); \ + if (!properties.lastKnownFileType.empty()) fileRef->addProperty("lastKnownFileType", properties.lastKnownFileType, "", SettingsNoValue); \ + if (!properties.fileName.empty()) fileRef->addProperty("name", properties.fileName, "", SettingsNoValue); \ + if (!properties.filePath.empty()) fileRef->addProperty("path", properties.filePath, "", SettingsNoValue); \ + if (!properties.sourceTree.empty()) fileRef->addProperty("sourceTree", properties.sourceTree, "", SettingsNoValue); \ + _fileReference.add(fileRef); \ + _fileReference.flags = SettingsSingleItem; \ +} + +XCodeProvider::XCodeProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version) + : ProjectProvider(global_warnings, project_warnings, version) { +} + +void XCodeProvider::createWorkspace(const BuildSetup &setup) { + // Create project folder + std::string workspace = setup.outputDir + '/' + "scummvm.xcodeproj"; + +#if defined(_WIN32) || defined(WIN32) + if (!CreateDirectory(workspace.c_str(), NULL)) + if (GetLastError() != ERROR_ALREADY_EXISTS) + error("Could not create folder \"" + setup.outputDir + '/' + "scummvm.xcodeproj\""); +#else + if (mkdir(workspace.c_str(), 0777) == -1) { + if (errno == EEXIST) { + // Try to open as a folder (might be a file / symbolic link) + DIR *dirp = opendir(workspace.c_str()); + if (dirp == NULL) { + error("Could not create folder \"" + setup.outputDir + '/' + "scummvm.xcodeproj\""); + } else { + // The folder exists, just close the stream and return + closedir(dirp); + } + } else { + error("Could not create folder \"" + setup.outputDir + '/' + "scummvm.xcodeproj\""); + } + } +#endif + + // Setup global objects + setupDefines(setup); + _targets.push_back("ScummVM-iPhone"); + _targets.push_back("ScummVM-OS X"); + _targets.push_back("ScummVM-Simulator"); + + setupCopyFilesBuildPhase(); + setupFrameworksBuildPhase(); + setupNativeTarget(); + setupProject(); + setupResourcesBuildPhase(); + setupBuildConfiguration(); +} + +// We are done with constructing all the object graph and we got through every project, output the main project file +// (this is kind of a hack since other providers use separate project files) +void XCodeProvider::createOtherBuildFiles(const BuildSetup &setup) { + // This needs to be done at the end when all build files have been accounted for + setupSourcesBuildPhase(); + + ouputMainProjectFile(setup); +} + +// Store information about a project here, for use at the end +void XCodeProvider::createProjectFile(const std::string &, const std::string &, const BuildSetup &setup, const std::string &moduleDir, + const StringList &includeList, const StringList &excludeList) { + std::string modulePath; + if (!moduleDir.compare(0, setup.srcDir.size(), setup.srcDir)) { + modulePath = moduleDir.substr(setup.srcDir.size()); + if (!modulePath.empty() && modulePath.at(0) == '/') + modulePath.erase(0, 1); + } + + std::ofstream project; + if (modulePath.size()) + addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix + '/' + modulePath); + else + addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix); +} + +////////////////////////////////////////////////////////////////////////// +// Main Project file +////////////////////////////////////////////////////////////////////////// +void XCodeProvider::ouputMainProjectFile(const BuildSetup &setup) { + std::ofstream project((setup.outputDir + '/' + "scummvm.xcodeproj" + '/' + "project.pbxproj").c_str()); + if (!project) + error("Could not open \"" + setup.outputDir + '/' + "scummvm.xcodeproj" + '/' + "project.pbxproj\" for writing"); + + ////////////////////////////////////////////////////////////////////////// + // Header + project << "// !$*UTF8*$!\n" + "{\n" + "\t" << writeSetting("archiveVersion", "1", "", SettingsNoQuote) << ";\n" + "\tclasses = {\n" + "\t};\n" + "\t" << writeSetting("objectVersion", "46", "", SettingsNoQuote) << ";\n" + "\tobjects = {\n"; + + ////////////////////////////////////////////////////////////////////////// + // List of objects + project << _buildFile.toString(); + project << _copyFilesBuildPhase.toString(); + project << _fileReference.toString(); + project << _frameworksBuildPhase.toString(); + project << _groups.toString(); + project << _nativeTarget.toString(); + project << _project.toString(); + project << _resourcesBuildPhase.toString(); + project << _sourcesBuildPhase.toString(); + project << _buildConfiguration.toString(); + project << _configurationList.toString(); + + ////////////////////////////////////////////////////////////////////////// + // Footer + project << "\t};\n" + "\t" << writeSetting("rootObject", getHash("PBXProject"), "Project object", SettingsNoQuote) << ";\n" + "}\n"; + +} + +////////////////////////////////////////////////////////////////////////// +// Files +////////////////////////////////////////////////////////////////////////// +void XCodeProvider::writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, + const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix) { + + // Add comments for shared lists + _buildFile.comment = "PBXBuildFile"; + _fileReference.comment = "PBXFileReference"; + + // Init root group + _groups.comment = "PBXGroup"; + Object *group = new Object(this, "PBXGroup", "PBXGroup", "PBXGroup", "", ""); + + //Property children; + //children.flags = SettingsAsList; + //group->properties["children"] = children; + group->addProperty("children", "", "", SettingsNoValue|SettingsAsList); + + group->addProperty("sourceTree", "<group>", "", SettingsNoValue|SettingsQuoteVariable); + + _groups.add(group); + + // TODO Add files +} + +////////////////////////////////////////////////////////////////////////// +// Setup functions +////////////////////////////////////////////////////////////////////////// +void XCodeProvider::setupCopyFilesBuildPhase() { + // Nothing to do here +} + +/** + * Sets up the frameworks build phase. + * + * (each native target has different build rules) + */ +void XCodeProvider::setupFrameworksBuildPhase() { + _frameworksBuildPhase.comment = "PBXFrameworksBuildPhase"; + + // Setup framework file properties + std::map<std::string, FileProperty> properties; + + // Frameworks + properties["ApplicationServices.framework"] = FileProperty("wrapper.framework", "ApplicationServices.framework", "System/Library/Frameworks/ApplicationServices.framework", "SDKROOT"); + properties["AudioToolbox.framework"] = FileProperty("wrapper.framework", "AudioToolbox.framework", "System/Library/Frameworks/AudioToolbox.framework", "SDKROOT"); + properties["AudioUnit.framework"] = FileProperty("wrapper.framework", "AudioUnit.framework", "System/Library/Frameworks/AudioUnit.framework", "SDKROOT"); + properties["Carbon.framework"] = FileProperty("wrapper.framework", "Carbon.framework", "System/Library/Frameworks/Carbon.framework", "SDKROOT"); + properties["Cocoa.framework"] = FileProperty("wrapper.framework", "Cocoa.framework", "System/Library/Frameworks/Cocoa.framework", "SDKROOT"); + properties["CoreAudio.framework"] = FileProperty("wrapper.framework", "CoreAudio.framework", "System/Library/Frameworks/CoreAudio.framework", "SDKROOT"); + properties["CoreFoundation.framework"] = FileProperty("wrapper.framework", "CoreFoundation.framework", "System/Library/Frameworks/CoreFoundation.framework", "SDKROOT"); + properties["CoreMIDI.framework"] = FileProperty("wrapper.framework", "CoreMIDI.framework", "System/Library/Frameworks/CoreMIDI.framework", "SDKROOT"); + properties["Foundation.framework"] = FileProperty("wrapper.framework", "Foundation.framework", "System/Library/Frameworks/Foundation.framework", "SDKROOT"); + properties["IOKit.framework"] = FileProperty("wrapper.framework", "IOKit.framework", "System/Library/Frameworks/IOKit.framework", "SDKROOT"); + properties["OpenGLES.framework"] = FileProperty("wrapper.framework", "OpenGLES.framework", "System/Library/Frameworks/OpenGLES.framework", "SDKROOT"); + properties["QuartzCore.framework"] = FileProperty("wrapper.framework", "QuartzCore.framework", "System/Library/Frameworks/QuartzCore.framework", "SDKROOT"); + properties["QuickTime.framework"] = FileProperty("wrapper.framework", "QuickTime.framework", "System/Library/Frameworks/QuickTime.framework", "SDKROOT"); + properties["UIKit.framework"] = FileProperty("wrapper.framework", "UIKit.framework", "System/Library/Frameworks/UIKit.framework", "SDKROOT"); + + // Local libraries + properties["libFLAC.a"] = FileProperty("archive.ar", "libFLAC.a", "lib/libFLAC.a", "\"<group>\""); + properties["libmad.a"] = FileProperty("archive.ar", "libmad.a", "lib/libmad.a", "\"<group>\""); + //properties["libmpeg2.a"] = FileProperty("archive.ar", "libmpeg2.a", "lib/libmpeg2.a", "\"<group>\""); + properties["libvorbisidec.a"] = FileProperty("archive.ar", "libvorbisidec.a", "lib/libvorbisidec.a", "\"<group>\""); + + ////////////////////////////////////////////////////////////////////////// + // iPhone + Object *framework_iPhone = new Object(this, "PBXFrameworksBuildPhase_" + _targets[0], "PBXFrameworksBuildPhase", "PBXFrameworksBuildPhase", "", "Frameworks"); + + framework_iPhone->addProperty("buildActionMask", "2147483647", "", SettingsNoValue); + framework_iPhone->addProperty("runOnlyForDeploymentPostprocessing", "0", "", SettingsNoValue); + + // List of frameworks + Property iPhone_files; + iPhone_files.hasOrder = true; + iPhone_files.flags = SettingsAsList; + + ValueList frameworks_iPhone; + frameworks_iPhone.push_back("CoreAudio.framework"); + frameworks_iPhone.push_back("CoreFoundation.framework"); + frameworks_iPhone.push_back("Foundation.framework"); + frameworks_iPhone.push_back("UIKit.framework"); + frameworks_iPhone.push_back("AudioToolbox.framework"); + frameworks_iPhone.push_back("QuartzCore.framework"); + frameworks_iPhone.push_back("libmad.a"); + //frameworks_iPhone.push_back("libmpeg2.a"); + frameworks_iPhone.push_back("libFLAC.a"); + frameworks_iPhone.push_back("libvorbisidec.a"); + frameworks_iPhone.push_back("OpenGLES.framework"); + + int order = 0; + for (ValueList::iterator framework = frameworks_iPhone.begin(); framework != frameworks_iPhone.end(); framework++) { + std::string id = "Frameworks_" + *framework + "_iphone"; + std::string comment = *framework + " in Frameworks"; + + ADD_SETTING_ORDER_NOVALUE(iPhone_files, getHash(id), comment, order++); + ADD_BUILD_FILE(id, *framework, comment); + ADD_FILE_REFERENCE(*framework, properties[*framework]); + } + + framework_iPhone->properties["files"] = iPhone_files; + + _frameworksBuildPhase.add(framework_iPhone); + + ////////////////////////////////////////////////////////////////////////// + // ScummVM-OS X + Object *framework_OSX = new Object(this, "PBXFrameworksBuildPhase_" + _targets[1], "PBXFrameworksBuildPhase", "PBXFrameworksBuildPhase", "", "Frameworks"); + + framework_OSX->addProperty("buildActionMask", "2147483647", "", SettingsNoValue); + framework_OSX->addProperty("runOnlyForDeploymentPostprocessing", "0", "", SettingsNoValue); + + // List of frameworks + Property osx_files; + osx_files.hasOrder = true; + osx_files.flags = SettingsAsList; + + ValueList frameworks_osx; + frameworks_osx.push_back("CoreFoundation.framework"); + frameworks_osx.push_back("Foundation.framework"); + frameworks_osx.push_back("AudioToolbox.framework"); + frameworks_osx.push_back("QuickTime.framework"); + frameworks_osx.push_back("CoreMIDI.framework"); + frameworks_osx.push_back("CoreAudio.framework"); + frameworks_osx.push_back("QuartzCore.framework"); + frameworks_osx.push_back("Carbon.framework"); + frameworks_osx.push_back("ApplicationServices.framework"); + frameworks_osx.push_back("IOKit.framework"); + frameworks_osx.push_back("Cocoa.framework"); + frameworks_osx.push_back("AudioUnit.framework"); + + order = 0; + for (ValueList::iterator framework = frameworks_osx.begin(); framework != frameworks_osx.end(); framework++) { + std::string id = "Frameworks_" + *framework + "_osx"; + std::string comment = *framework + " in Frameworks"; + + ADD_SETTING_ORDER_NOVALUE(osx_files, getHash(id), comment, order++); + ADD_BUILD_FILE(id, *framework, comment); + ADD_FILE_REFERENCE(*framework, properties[*framework]); + } + + framework_OSX->properties["files"] = osx_files; + + _frameworksBuildPhase.add(framework_OSX); + + ////////////////////////////////////////////////////////////////////////// + // Simulator + Object *framework_simulator = new Object(this, "PBXFrameworksBuildPhase_" + _targets[2], "PBXFrameworksBuildPhase", "PBXFrameworksBuildPhase", "", "Frameworks"); + + framework_simulator->addProperty("buildActionMask", "2147483647", "", SettingsNoValue); + framework_simulator->addProperty("runOnlyForDeploymentPostprocessing", "0", "", SettingsNoValue); + + // List of frameworks + Property simulator_files; + simulator_files.hasOrder = true; + simulator_files.flags = SettingsAsList; + + ValueList frameworks_simulator; + frameworks_simulator.push_back("CoreAudio.framework"); + frameworks_simulator.push_back("CoreFoundation.framework"); + frameworks_simulator.push_back("Foundation.framework"); + frameworks_simulator.push_back("UIKit.framework"); + frameworks_simulator.push_back("AudioToolbox.framework"); + frameworks_simulator.push_back("QuartzCore.framework"); + frameworks_simulator.push_back("OpenGLES.framework"); + + order = 0; + for (ValueList::iterator framework = frameworks_simulator.begin(); framework != frameworks_simulator.end(); framework++) { + std::string id = "Frameworks_" + *framework + "_simulator"; + std::string comment = *framework + " in Frameworks"; + + ADD_SETTING_ORDER_NOVALUE(simulator_files, getHash(id), comment, order++); + ADD_BUILD_FILE(id, *framework, comment); + ADD_FILE_REFERENCE(*framework, properties[*framework]); + } + + framework_simulator->properties["files"] = simulator_files; + + _frameworksBuildPhase.add(framework_simulator); +} + +void XCodeProvider::setupNativeTarget() { + _nativeTarget.comment = "PBXNativeTarget"; + + // Output native target section + for (unsigned int i = 0; i < _targets.size(); i++) { + Object *target = new Object(this, "PBXNativeTarget_" + _targets[i], "PBXNativeTarget", "PBXNativeTarget", "", _targets[i]); + + target->addProperty("buildConfigurationList", getHash("XCConfigurationList_" + _targets[i]), "Build configuration list for PBXNativeTarget \"" + _targets[i] + "\"", SettingsNoValue); + + Property buildPhases; + buildPhases.hasOrder = true; + buildPhases.flags = SettingsAsList; + buildPhases.settings[getHash("PBXResourcesBuildPhase_" + _targets[i])] = Setting("", "Resources", SettingsNoValue, 0, 0); + buildPhases.settings[getHash("PBXSourcesBuildPhase_" + _targets[i])] = Setting("", "Sources", SettingsNoValue, 0, 1); + buildPhases.settings[getHash("PBXFrameworksBuildPhase_" + _targets[i])] = Setting("", "Frameworks", SettingsNoValue, 0, 2); + target->properties["buildPhases"] = buildPhases; + + target->addProperty("buildRules", "", "", SettingsNoValue|SettingsAsList); + + target->addProperty("dependencies", "", "", SettingsNoValue|SettingsAsList); + + target->addProperty("name", _targets[i], "", SettingsNoValue|SettingsQuoteVariable); + target->addProperty("productName", "scummvm", "", SettingsNoValue); + target->addProperty("productReference", getHash("PBXFileReference_ScummVM.app_" + _targets[i]), "ScummVM.app", SettingsNoValue); + target->addProperty("productType", "com.apple.product-type.application", "", SettingsNoValue|SettingsQuoteVariable); + + _nativeTarget.add(target); + } +} + +void XCodeProvider::setupProject() { + _project.comment = "PBXProject"; + + Object *project = new Object(this, "PBXProject", "PBXProject", "PBXProject", "", "Project object"); + + project->addProperty("buildConfigurationList", getHash("XCConfigurationList_scummvm"), "Build configuration list for PBXProject \"scummvm\"", SettingsNoValue); + project->addProperty("compatibilityVersion", "Xcode 3.2", "", SettingsNoValue|SettingsQuoteVariable); + project->addProperty("developmentRegion", "English", "", SettingsNoValue); + project->addProperty("hasScannedForEncodings", "1", "", SettingsNoValue); + + // List of known regions + Property regions; + regions.flags = SettingsAsList; + ADD_SETTING_ORDER_NOVALUE(regions, "English", "", 0); + ADD_SETTING_ORDER_NOVALUE(regions, "Japanese", "", 1); + ADD_SETTING_ORDER_NOVALUE(regions, "French", "", 2); + ADD_SETTING_ORDER_NOVALUE(regions, "German", "", 3); + project->properties["knownRegions"] = regions; + + project->addProperty("mainGroup", getHash("PBXGroup_CustomTemplate"), "CustomTemplate", SettingsNoValue); + project->addProperty("projectDirPath", "", "", SettingsNoValue|SettingsQuoteVariable); + project->addProperty("projectRoot", "", "", SettingsNoValue|SettingsQuoteVariable); + + // List of targets + Property targets; + targets.flags = SettingsAsList; + targets.settings[getHash("PBXNativeTarget_" + _targets[0])] = Setting("", _targets[0], SettingsNoValue, 0, 0); + targets.settings[getHash("PBXNativeTarget_" + _targets[1])] = Setting("", _targets[1], SettingsNoValue, 0, 1); + targets.settings[getHash("PBXNativeTarget_" + _targets[2])] = Setting("", _targets[2], SettingsNoValue, 0, 2); + project->properties["targets"] = targets; + + _project.add(project); +} + +void XCodeProvider::setupResourcesBuildPhase() { + _resourcesBuildPhase.comment = "PBXResourcesBuildPhase"; + + // Setup resource file properties + std::map<std::string, FileProperty> properties; + properties["scummclassic.zip"] = FileProperty("archive.zip", "", "scummclassic.zip", "\"<group>\""); + properties["scummmodern.zip"] = FileProperty("archive.zip", "", "scummmodern.zip", "\"<group>\""); + + properties["kyra.dat"] = FileProperty("file", "", "kyra.dat", "\"<group>\""); + properties["lure.dat"] = FileProperty("file", "", "lure.dat", "\"<group>\""); + properties["queen.tbl"] = FileProperty("file", "", "queen.tbl", "\"<group>\""); + properties["sky.cpt"] = FileProperty("file", "", "sky.cpt", "\"<group>\""); + properties["drascula.dat"] = FileProperty("file", "", "drascula.dat", "\"<group>\""); + properties["hugo.dat"] = FileProperty("file", "", "hugo.dat", "\"<group>\""); + properties["m4.dat"] = FileProperty("file", "", "m4.dat", "\"<group>\""); + properties["teenagent.dat"] = FileProperty("file", "", "teenagent.dat", "\"<group>\""); + properties["toon.dat"] = FileProperty("file", "", "toon.dat", "\"<group>\""); + + properties["Default.png"] = FileProperty("image.png", "", "Default.png", "\"<group>\""); + properties["icon.png"] = FileProperty("image.png", "", "icon.png", "\"<group>\""); + properties["icon-72.png"] = FileProperty("image.png", "", "icon-72.png", "\"<group>\""); + properties["icon4.png"] = FileProperty("image.png", "", "icon4.png", "\"<group>\""); + + // Same as for containers: a rule for each native target + for (unsigned int i = 0; i < _targets.size(); i++) { + Object *resource = new Object(this, "PBXResourcesBuildPhase_" + _targets[i], "PBXResourcesBuildPhase", "PBXResourcesBuildPhase", "", "Resources"); + + resource->addProperty("buildActionMask", "2147483647", "", SettingsNoValue); + + // Add default files + Property files; + files.hasOrder = true; + files.flags = SettingsAsList; + + ValueList files_list; + files_list.push_back("scummclassic.zip"); + files_list.push_back("scummmodern.zip"); + files_list.push_back("kyra.dat"); + files_list.push_back("lure.dat"); + files_list.push_back("queen.tbl"); + files_list.push_back("sky.cpt"); + files_list.push_back("Default.png"); + files_list.push_back("icon.png"); + files_list.push_back("icon-72.png"); + files_list.push_back("icon4.png"); + files_list.push_back("drascula.dat"); + files_list.push_back("hugo.dat"); + files_list.push_back("m4.dat"); + files_list.push_back("teenagent.dat"); + files_list.push_back("toon.dat"); + + int order = 0; + for (ValueList::iterator file = files_list.begin(); file != files_list.end(); file++) { + std::string id = "PBXResources_" + *file; + std::string comment = *file + " in Resources"; + + ADD_SETTING_ORDER_NOVALUE(files, getHash(id), comment, order++); + // TODO Fix crash when adding build file for data + //ADD_BUILD_FILE(id, *file, comment); + ADD_FILE_REFERENCE(*file, properties[*file]); + } + + // Add custom files depending on the target + if (_targets[i] == "ScummVM-OS X") { + files.settings[getHash("PBXResources_scummvm.icns")] = Setting("", "scummvm.icns in Resources", SettingsNoValue, 0, 6); + + // Remove 2 iphone icon files + files.settings.erase(getHash("PBXResources_Default.png")); + files.settings.erase(getHash("PBXResources_icon.png")); + } + + resource->properties["files"] = files; + + resource->addProperty("runOnlyForDeploymentPostprocessing", "0", "", SettingsNoValue); + + _resourcesBuildPhase.add(resource); + } +} + +void XCodeProvider::setupSourcesBuildPhase() { + // TODO +} + +// Setup all build configurations +void XCodeProvider::setupBuildConfiguration() { + + _buildConfiguration.comment = "XCBuildConfiguration"; + _buildConfiguration.flags = SettingsAsList; + + ///**************************************** + // * iPhone + // ****************************************/ + + // Debug + Object *iPhone_Debug_Object = new Object(this, "XCBuildConfiguration_ScummVM-iPhone_Debug", _targets[0] /* ScummVM-iPhone */, "XCBuildConfiguration", "PBXNativeTarget", "Debug"); + Property iPhone_Debug; + ADD_SETTING_QUOTE(iPhone_Debug, "ARCHS", "$(ARCHS_UNIVERSAL_IPHONE_OS)"); + ADD_SETTING_QUOTE(iPhone_Debug, "CODE_SIGN_IDENTITY", "iPhone Developer"); + ADD_SETTING_QUOTE_VAR(iPhone_Debug, "CODE_SIGN_IDENTITY[sdk=iphoneos*]", "iPhone Developer"); + ADD_SETTING(iPhone_Debug, "COMPRESS_PNG_FILES", "NO"); + ADD_SETTING(iPhone_Debug, "COPY_PHASE_STRIP", "NO"); + ADD_SETTING_QUOTE(iPhone_Debug, "DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym"); + ValueList iPhone_FrameworkSearchPaths; + iPhone_FrameworkSearchPaths.push_back("$(inherited)"); + iPhone_FrameworkSearchPaths.push_back("\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\""); + ADD_SETTING_LIST(iPhone_Debug, "FRAMEWORK_SEARCH_PATHS", iPhone_FrameworkSearchPaths, SettingsAsList, 5); + ADD_SETTING(iPhone_Debug, "GCC_DYNAMIC_NO_PIC", "NO"); + ADD_SETTING(iPhone_Debug, "GCC_ENABLE_CPP_EXCEPTIONS", "NO"); + ADD_SETTING(iPhone_Debug, "GCC_ENABLE_FIX_AND_CONTINUE", "NO"); + ADD_SETTING(iPhone_Debug, "GCC_OPTIMIZATION_LEVEL", "0"); + ADD_SETTING(iPhone_Debug, "GCC_PRECOMPILE_PREFIX_HEADER", "NO"); + ADD_SETTING_QUOTE(iPhone_Debug, "GCC_PREFIX_HEADER", ""); + ADD_SETTING(iPhone_Debug, "GCC_THUMB_SUPPORT", "NO"); + ADD_SETTING(iPhone_Debug, "GCC_UNROLL_LOOPS", "YES"); + ValueList iPhone_HeaderSearchPaths; + iPhone_HeaderSearchPaths.push_back("../../engines/"); + iPhone_HeaderSearchPaths.push_back("../../"); + iPhone_HeaderSearchPaths.push_back("include/"); + ADD_SETTING_LIST(iPhone_Debug, "HEADER_SEARCH_PATHS", iPhone_HeaderSearchPaths, SettingsAsList|SettingsNoQuote, 5); + ADD_SETTING(iPhone_Debug, "INFOPLIST_FILE", "Info.plist"); + ValueList iPhone_LibPaths; + iPhone_LibPaths.push_back("$(inherited)"); + iPhone_LibPaths.push_back("\"$(SRCROOT)/lib\""); + ADD_SETTING_LIST(iPhone_Debug, "LIBRARY_SEARCH_PATHS", iPhone_LibPaths, SettingsAsList, 5); + ADD_SETTING(iPhone_Debug, "ONLY_ACTIVE_ARCH", "YES"); + ADD_SETTING(iPhone_Debug, "PREBINDING", "NO"); + ADD_SETTING(iPhone_Debug, "PRODUCT_NAME", "ScummVM"); + ADD_SETTING_QUOTE(iPhone_Debug, "PROVISIONING_PROFILE", "EF590570-5FAC-4346-9071-D609DE2B28D8"); + ADD_SETTING_QUOTE_VAR(iPhone_Debug, "PROVISIONING_PROFILE[sdk=iphoneos*]", ""); + ADD_SETTING(iPhone_Debug, "SDKROOT", "iphoneos4.0"); + ADD_SETTING_QUOTE(iPhone_Debug, "TARGETED_DEVICE_FAMILY", "1,2"); + + iPhone_Debug_Object->addProperty("name", "Debug", "", SettingsNoValue); + iPhone_Debug_Object->properties["buildSettings"] = iPhone_Debug; + + // Release + Object *iPhone_Release_Object = new Object(this, "XCBuildConfiguration_ScummVM-iPhone_Release", _targets[0] /* ScummVM-iPhone */, "XCBuildConfiguration", "PBXNativeTarget", "Release"); + Property iPhone_Release(iPhone_Debug); + ADD_SETTING(iPhone_Release, "GCC_OPTIMIZATION_LEVEL", "3"); + ADD_SETTING(iPhone_Release, "COPY_PHASE_STRIP", "YES"); + REMOVE_SETTING(iPhone_Release, "GCC_DYNAMIC_NO_PIC"); + ADD_SETTING(iPhone_Release, "WRAPPER_EXTENSION", "app"); + + iPhone_Release_Object->addProperty("name", "Release", "", SettingsNoValue); + iPhone_Release_Object->properties["buildSettings"] = iPhone_Release; + + _buildConfiguration.add(iPhone_Debug_Object); + _buildConfiguration.add(iPhone_Release_Object); + + /**************************************** + * scummvm + ****************************************/ + + // Debug + Object *scummvm_Debug_Object = new Object(this, "XCBuildConfiguration_scummvm_Debug", "scummvm", "XCBuildConfiguration", "PBXProject", "Debug"); + Property scummvm_Debug; + ADD_SETTING(scummvm_Debug, "ALWAYS_SEARCH_USER_PATHS", "NO"); + ADD_SETTING_QUOTE(scummvm_Debug, "ARCHS", "$(ARCHS_STANDARD_32_BIT)"); + ADD_SETTING_QUOTE(scummvm_Debug, "CODE_SIGN_IDENTITY", "Don't Code Sign"); + ADD_SETTING_QUOTE_VAR(scummvm_Debug, "CODE_SIGN_IDENTITY[sdk=iphoneos*]", "Don't Code Sign"); + ADD_SETTING_QUOTE(scummvm_Debug, "FRAMEWORK_SEARCH_PATHS", ""); + ADD_SETTING(scummvm_Debug, "GCC_C_LANGUAGE_STANDARD", "c99"); + ADD_SETTING(scummvm_Debug, "GCC_ENABLE_CPP_EXCEPTIONS", "NO"); + ADD_SETTING(scummvm_Debug, "GCC_ENABLE_CPP_RTTI", "NO"); + ADD_SETTING(scummvm_Debug, "GCC_INPUT_FILETYPE", "automatic"); + ADD_SETTING(scummvm_Debug, "GCC_OPTIMIZATION_LEVEL", "0"); + ValueList scummvm_defines(_defines); + ADD_DEFINE(scummvm_defines, "IPHONE"); + ADD_DEFINE(scummvm_defines, "XCODE"); + ADD_DEFINE(scummvm_defines, "IPHONE_OFFICIAL"); + ADD_SETTING_LIST(scummvm_Debug, "GCC_PREPROCESSOR_DEFINITIONS", scummvm_defines, SettingsNoQuote|SettingsAsList, 5); + ADD_SETTING(scummvm_Debug, "GCC_THUMB_SUPPORT", "NO"); + ADD_SETTING(scummvm_Debug, "GCC_USE_GCC3_PFE_SUPPORT", "NO"); + ADD_SETTING(scummvm_Debug, "GCC_WARN_ABOUT_RETURN_TYPE", "YES"); + ADD_SETTING(scummvm_Debug, "GCC_WARN_UNUSED_VARIABLE", "YES"); + ValueList scummvm_HeaderPaths; + scummvm_HeaderPaths.push_back("include/"); + scummvm_HeaderPaths.push_back("../../engines/"); + scummvm_HeaderPaths.push_back("../../"); + ADD_SETTING_LIST(scummvm_Debug, "HEADER_SEARCH_PATHS", scummvm_HeaderPaths, SettingsNoQuote|SettingsAsList, 5); + ADD_SETTING_QUOTE(scummvm_Debug, "LIBRARY_SEARCH_PATHS", ""); + ADD_SETTING(scummvm_Debug, "ONLY_ACTIVE_ARCH", "YES"); + ADD_SETTING_QUOTE(scummvm_Debug, "OTHER_CFLAGS", ""); + ADD_SETTING_QUOTE(scummvm_Debug, "OTHER_LDFLAGS", "-lz"); + ADD_SETTING(scummvm_Debug, "PREBINDING", "NO"); + ADD_SETTING(scummvm_Debug, "SDKROOT", "macosx10.6"); + + scummvm_Debug_Object->addProperty("name", "Debug", "", SettingsNoValue); + scummvm_Debug_Object->properties["buildSettings"] = scummvm_Debug; + + // Release + Object *scummvm_Release_Object = new Object(this, "XCBuildConfiguration_scummvm_Release", "scummvm", "XCBuildConfiguration", "PBXProject", "Release"); + Property scummvm_Release(scummvm_Debug); + REMOVE_SETTING(scummvm_Release, "GCC_C_LANGUAGE_STANDARD"); // Not sure why we remove that, or any of the other warnings + REMOVE_SETTING(scummvm_Release, "GCC_WARN_ABOUT_RETURN_TYPE"); + REMOVE_SETTING(scummvm_Release, "GCC_WARN_UNUSED_VARIABLE"); + REMOVE_SETTING(scummvm_Release, "ONLY_ACTIVE_ARCH"); + + scummvm_Release_Object->addProperty("name", "Release", "", SettingsNoValue); + scummvm_Release_Object->properties["buildSettings"] = scummvm_Release; + + _buildConfiguration.add(scummvm_Debug_Object); + _buildConfiguration.add(scummvm_Release_Object); + + /**************************************** + * ScummVM-OS X + ****************************************/ + + // Debug + Object *scummvmOSX_Debug_Object = new Object(this, "XCBuildConfiguration_ScummVM-OSX_Debug", _targets[1] /* ScummVM-OS X */, "XCBuildConfiguration", "PBXNativeTarget", "Debug"); + Property scummvmOSX_Debug; + ADD_SETTING_QUOTE(scummvmOSX_Debug, "ARCHS", "$(NATIVE_ARCH)"); + ADD_SETTING(scummvmOSX_Debug, "COMPRESS_PNG_FILES", "NO"); + ADD_SETTING(scummvmOSX_Debug, "COPY_PHASE_STRIP", "NO"); + ADD_SETTING_QUOTE(scummvmOSX_Debug, "DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym"); + ADD_SETTING_QUOTE(scummvmOSX_Debug, "FRAMEWORK_SEARCH_PATHS", ""); + ADD_SETTING(scummvmOSX_Debug, "GCC_C_LANGUAGE_STANDARD", "c99"); + ADD_SETTING(scummvmOSX_Debug, "GCC_ENABLE_CPP_EXCEPTIONS", "NO"); + ADD_SETTING(scummvmOSX_Debug, "GCC_ENABLE_CPP_RTTI", "NO"); + ADD_SETTING(scummvmOSX_Debug, "GCC_DYNAMIC_NO_PIC", "NO"); + ADD_SETTING(scummvmOSX_Debug, "GCC_ENABLE_FIX_AND_CONTINUE", "NO"); + ADD_SETTING(scummvmOSX_Debug, "GCC_OPTIMIZATION_LEVEL", "0"); + ADD_SETTING(scummvmOSX_Debug, "GCC_PRECOMPILE_PREFIX_HEADER", "NO"); + ADD_SETTING_QUOTE(scummvmOSX_Debug, "GCC_PREFIX_HEADER", ""); + ValueList scummvmOSX_defines(_defines); + ADD_DEFINE(scummvmOSX_defines, "SDL_BACKEND"); + ADD_DEFINE(scummvmOSX_defines, "MACOSX"); + ADD_SETTING_LIST(scummvmOSX_Debug, "GCC_PREPROCESSOR_DEFINITIONS", scummvmOSX_defines, SettingsNoQuote|SettingsAsList, 5); + ADD_SETTING_QUOTE(scummvmOSX_Debug, "GCC_VERSION", ""); + ValueList scummvmOSX_HeaderPaths; + scummvmOSX_HeaderPaths.push_back("/opt/local/include/SDL"); + scummvmOSX_HeaderPaths.push_back("/opt/local/include"); + scummvmOSX_HeaderPaths.push_back("include/"); + scummvmOSX_HeaderPaths.push_back("../../engines/"); + scummvmOSX_HeaderPaths.push_back("../../"); + ADD_SETTING_LIST(scummvmOSX_Debug, "HEADER_SEARCH_PATHS", scummvmOSX_HeaderPaths, SettingsNoQuote|SettingsAsList, 5); + ADD_SETTING_QUOTE(scummvmOSX_Debug, "INFOPLIST_FILE", "$(SRCROOT)/../macosx/Info.plist"); + ValueList scummvmOSX_LibPaths; + scummvmOSX_LibPaths.push_back("/sw/lib"); + scummvmOSX_LibPaths.push_back("/opt/local/lib"); + scummvmOSX_LibPaths.push_back("\"$(inherited)\""); + scummvmOSX_LibPaths.push_back("\"\\\\\\\"$(SRCROOT)/lib\\\\\\\"\""); // mmmh, all those slashes, it's almost Christmas \o/ + ADD_SETTING_LIST(scummvmOSX_Debug, "LIBRARY_SEARCH_PATHS", scummvmOSX_LibPaths, SettingsNoQuote|SettingsAsList, 5); + ADD_SETTING_QUOTE(scummvmOSX_Debug, "OTHER_CFLAGS", ""); + ValueList scummvmOSX_LdFlags; + scummvmOSX_LdFlags.push_back("-lSDLmain"); + scummvmOSX_LdFlags.push_back("-logg"); + scummvmOSX_LdFlags.push_back("-lvorbisfile"); + scummvmOSX_LdFlags.push_back("-lvorbis"); + scummvmOSX_LdFlags.push_back("-lmad"); + scummvmOSX_LdFlags.push_back("-lFLAC"); + scummvmOSX_LdFlags.push_back("-lSDL"); + scummvmOSX_LdFlags.push_back("-lz"); + ADD_SETTING_LIST(scummvmOSX_Debug, "OTHER_LDFLAGS", scummvmOSX_LdFlags, SettingsAsList, 5); + ADD_SETTING(scummvmOSX_Debug, "PREBINDING", "NO"); + ADD_SETTING(scummvmOSX_Debug, "PRODUCT_NAME", "ScummVM"); + + scummvmOSX_Debug_Object->addProperty("name", "Debug", "", SettingsNoValue); + scummvmOSX_Debug_Object->properties["buildSettings"] = scummvmOSX_Debug; + + // Release + Object *scummvmOSX_Release_Object = new Object(this, "XCBuildConfiguration_ScummVMOSX_Release", _targets[1] /* ScummVM-OS X */, "XCBuildConfiguration", "PBXNativeTarget", "Release"); + Property scummvmOSX_Release(scummvmOSX_Debug); + ADD_SETTING(scummvmOSX_Release, "COPY_PHASE_STRIP", "YES"); + REMOVE_SETTING(scummvmOSX_Release, "GCC_DYNAMIC_NO_PIC"); + REMOVE_SETTING(scummvmOSX_Release, "GCC_OPTIMIZATION_LEVEL"); + ADD_SETTING(scummvmOSX_Release, "WRAPPER_EXTENSION", "app"); + + scummvmOSX_Release_Object->addProperty("name", "Release", "", SettingsNoValue); + scummvmOSX_Release_Object->properties["buildSettings"] = scummvmOSX_Release; + + _buildConfiguration.add(scummvmOSX_Debug_Object); + _buildConfiguration.add(scummvmOSX_Release_Object); + + /**************************************** + * ScummVM-Simulator + ****************************************/ + + // Debug + Object *scummvmSimulator_Debug_Object = new Object(this, "XCBuildConfiguration_ScummVM-Simulator_Debug", _targets[2] /* ScummVM-Simulator */, "XCBuildConfiguration", "PBXNativeTarget", "Debug"); + Property scummvmSimulator_Debug(iPhone_Debug); + ADD_SETTING_QUOTE(scummvmSimulator_Debug, "FRAMEWORK_SEARCH_PATHS", "$(inherited)"); + ADD_SETTING_LIST(scummvmSimulator_Debug, "GCC_PREPROCESSOR_DEFINITIONS", scummvm_defines, SettingsNoQuote|SettingsAsList, 5); + ADD_SETTING(scummvmSimulator_Debug, "SDKROOT", "iphonesimulator3.2"); + REMOVE_SETTING(scummvmSimulator_Debug, "TARGETED_DEVICE_FAMILY"); + + scummvmSimulator_Debug_Object->addProperty("name", "Debug", "", SettingsNoValue); + scummvmSimulator_Debug_Object->properties["buildSettings"] = scummvmSimulator_Debug; + + // Release + Object *scummvmSimulator_Release_Object = new Object(this, "XCBuildConfiguration_ScummVM-Simulator_Release", _targets[2] /* ScummVM-Simulator */, "XCBuildConfiguration", "PBXNativeTarget", "Release"); + Property scummvmSimulator_Release(scummvmSimulator_Debug); + ADD_SETTING(scummvmSimulator_Release, "COPY_PHASE_STRIP", "YES"); + REMOVE_SETTING(scummvmSimulator_Release, "GCC_DYNAMIC_NO_PIC"); + ADD_SETTING(scummvmSimulator_Release, "WRAPPER_EXTENSION", "app"); + + scummvmSimulator_Release_Object->addProperty("name", "Release", "", SettingsNoValue); + scummvmSimulator_Release_Object->properties["buildSettings"] = scummvmSimulator_Release; + + _buildConfiguration.add(scummvmSimulator_Debug_Object); + _buildConfiguration.add(scummvmSimulator_Release_Object); + + ////////////////////////////////////////////////////////////////////////// + // Configuration List + _configurationList.comment = "XCConfigurationList"; + _configurationList.flags = SettingsAsList; + + // Warning: This assumes we have all configurations with a Debug & Release pair + for (std::vector<Object *>::iterator config = _buildConfiguration.objects.begin(); config != _buildConfiguration.objects.end(); config++) { + + Object *configList = new Object(this, "XCConfigurationList_" + (*config)->name, (*config)->name, "XCConfigurationList", "", "Build configuration list for " + (*config)->refType + " \"" + (*config)->name + "\""); + + Property buildConfigs; + buildConfigs.flags = SettingsAsList; + + buildConfigs.settings[getHash((*config)->id)] = Setting("", "Debug", SettingsNoValue, 0, 0); + buildConfigs.settings[getHash((*(++config))->id)] = Setting("", "Release", SettingsNoValue, 0, 1); + + configList->properties["buildConfigurations"] = buildConfigs; + + configList->addProperty("defaultConfigurationIsVisible", "0", "", SettingsNoValue); + configList->addProperty("defaultConfigurationName", "Release", "", SettingsNoValue); + + _configurationList.add(configList); + } +} + +////////////////////////////////////////////////////////////////////////// +// Misc +////////////////////////////////////////////////////////////////////////// + +// Setup global defines +void XCodeProvider::setupDefines(const BuildSetup &setup) { + + for (StringList::const_iterator i = setup.defines.begin(); i != setup.defines.end(); ++i) { + if (*i == "HAVE_NASM") // Not supported on Mac (TODO: change how it's handled in main class or add it only in MSVC/CodeBlocks providers?) + continue; + + ADD_DEFINE(_defines, *i); + } + // Add special defines for Mac support + ADD_DEFINE(_defines, "CONFIG_H"); + ADD_DEFINE(_defines, "SCUMM_NEED_ALIGNMENT"); + ADD_DEFINE(_defines, "SCUMM_LITTLE_ENDIAN"); + ADD_DEFINE(_defines, "UNIX"); + ADD_DEFINE(_defines, "SCUMMVM"); + ADD_DEFINE(_defines, "USE_TREMOR"); +} + +////////////////////////////////////////////////////////////////////////// +// Object hash +////////////////////////////////////////////////////////////////////////// + +// TODO use md5 to compute a file hash (and fall back to standard key generation if not passed a file) +std::string XCodeProvider::getHash(std::string key) { + +#if DEBUG_XCODE_HASH + return key; +#else + // Check to see if the key is already in the dictionary + std::map<std::string, std::string>::iterator hashIterator = _hashDictionnary.find(key); + if (hashIterator != _hashDictionnary.end()) + return hashIterator->second; + + // Generate a new key from the file hash and insert it into the dictionary + std::string hash = newHash(); + _hashDictionnary[key] = hash; + + return hash; +#endif +} + +bool isSeparator (char s) { return (s == '-'); } + +std::string XCodeProvider::newHash() const { + std::string hash = createUUID(); + + // Remove { and - from UUID and resize to 96-bits uppercase hex string + hash.erase(remove_if(hash.begin(), hash.end(), isSeparator), hash.end()); + + hash.resize(24); + std::transform(hash.begin(), hash.end(), hash.begin(), toupper); + + return hash; +} + +////////////////////////////////////////////////////////////////////////// +// Output +////////////////////////////////////////////////////////////////////////// + +std::string replace(std::string input, const std::string find, std::string replaceStr) { + std::string::size_type pos = 0; + std::string::size_type findLen = find.length(); + std::string::size_type replaceLen = replaceStr.length(); + + if (findLen == 0 ) + return input; + + for (;(pos = input.find(find, pos)) != std::string::npos;) { + input.replace(pos, findLen, replaceStr); + pos += replaceLen; + } + + return input; +} + +std::string XCodeProvider::writeProperty(const std::string &variable, Property &prop, int flags) const { + std::string output; + + output += (flags & SettingsSingleItem ? "" : "\t\t\t") + variable + " = "; + + if (prop.settings.size() > 1 || (prop.flags & SettingsSingleItem)) + output += (prop.flags & SettingsAsList) ? "(\n" : "{\n"; + + OrderedSettingList settings = prop.getOrderedSettingList(); + for (OrderedSettingList::const_iterator setting = settings.begin(); setting != settings.end(); ++setting) { + if (settings.size() > 1 || (prop.flags & SettingsSingleItem)) + output += (flags & SettingsSingleItem ? " " : "\t\t\t\t"); + + output += writeSetting((*setting).first, (*setting).second); + + if ((prop.flags & SettingsAsList) && prop.settings.size() > 1) { + output += (prop.settings.size() > 0) ? ",\n" : "\n"; + } else { + output += ";"; + output += (flags & SettingsSingleItem ? " " : "\n"); + } + } + + if (prop.settings.size() > 1 || (prop.flags & SettingsSingleItem)) + output += (prop.flags & SettingsAsList) ? "\t\t\t);\n" : "\t\t\t};\n"; + + return output; +} + +std::string XCodeProvider::writeSetting(const std::string &variable, std::string value, std::string comment, int flags, int indent) const { + return writeSetting(variable, Setting(value, comment, flags, indent)); +} +// Heavily modified (not in a good way) function, imported from QMake XCode project generator (licensed under the QT license) +std::string XCodeProvider::writeSetting(const std::string &variable, const Setting &setting) const { + std::string output; + const std::string quote = (setting.flags & SettingsNoQuote) ? "" : "\""; + const std::string escape_quote = quote.empty() ? "" : "\\" + quote; + std::string newline = "\n"; + + // Get indent level + for (int i = 0; i < setting.indent; ++i) + newline += "\t"; + + // Setup variable + std::string var = (setting.flags & SettingsQuoteVariable) ? "\"" + variable + "\"" : variable; + + // Output a list + if (setting.flags & SettingsAsList) { + + output += var + ((setting.flags & SettingsNoValue) ? "(" : " = (") + newline; + + for (unsigned int i = 0, count = 0; i < setting.entries.size(); ++i) { + + std::string value = setting.entries.at(i).value; + if(!value.empty()) { + if (count++ > 0) + output += "," + newline; + + output += quote + replace(value, quote, escape_quote) + quote; + + std::string comment = setting.entries.at(i).comment; + if (!comment.empty()) + output += " /* " + comment + " */"; + } + + } + // Add closing ")" on new line + newline.resize(newline.size() - 1); + output += (setting.flags & SettingsNoValue) ? "\t\t\t)" : "," + newline + ")"; + } else { + output += var; + + output += (setting.flags & SettingsNoValue) ? "" : " = " + quote; + + for(unsigned int i = 0; i < setting.entries.size(); ++i) { + std::string value = setting.entries.at(i).value; + if(i) + output += " "; + output += value; + + std::string comment = setting.entries.at(i).comment; + if (!comment.empty()) + output += " /* " + comment + " */"; + } + + output += (setting.flags & SettingsNoValue) ? "" : quote; + } + return output; +} + +} // End of CreateProjectTool namespace diff --git a/devtools/create_project/xcode.h b/devtools/create_project/xcode.h new file mode 100644 index 0000000000..f86e7c555c --- /dev/null +++ b/devtools/create_project/xcode.h @@ -0,0 +1,307 @@ +/* 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 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. + * + */ + +#ifndef TOOLS_CREATE_PROJECT_XCODE_H +#define TOOLS_CREATE_PROJECT_XCODE_H + +#include "create_project.h" + +#include <algorithm> +#include <vector> + +namespace CreateProjectTool { + +class XCodeProvider : public ProjectProvider { +public: + XCodeProvider(StringList &global_warnings, std::map<std::string, StringList> &project_warnings, const int version = 0); + +protected: + + void createWorkspace(const BuildSetup &setup); + + void createOtherBuildFiles(const BuildSetup &setup); + + void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, + const StringList &includeList, const StringList &excludeList); + + void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, + const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix); + +private: + enum { + SettingsAsList = 0x01, + SettingsSingleItem = 0x02, + SettingsNoQuote = 0x04, + SettingsQuoteVariable = 0x08, + SettingsNoValue = 0x10 + }; + + // File properties + struct FileProperty { + std::string fileEncoding; + std::string lastKnownFileType; + std::string fileName; + std::string filePath; + std::string sourceTree; + + FileProperty(std::string fileType = "", std::string name = "", std::string path = "", std::string source = "") : + fileEncoding(""), lastKnownFileType(fileType), fileName(name), filePath(path), sourceTree(source) + { + } + }; + + ////////////////////////////////////////////////////////////////////////// + // XCObject and children + typedef std::vector<std::string> ValueList; + + struct Entry { + std::string value; + std::string comment; + + Entry(std::string val, std::string cmt) : value(val), comment(cmt) {} + }; + + typedef std::vector<Entry> EntryList; + + struct Setting { + EntryList entries; + int flags; + int indent; + int order; + + explicit Setting(std::string value = "", std::string comment = "", int flgs = 0, int idt = 0, int ord = -1) : flags(flgs), indent(idt), order(ord) { + entries.push_back(Entry(value, comment)); + } + + explicit Setting(ValueList values, int flgs = 0, int idt = 0, int ord = -1) : flags(flgs), indent(idt), order(ord) { + for (unsigned int i = 0; i < values.size(); i++) + entries.push_back(Entry(values[i], "")); + } + + explicit Setting(EntryList ents, int flgs = 0, int idt = 0, int ord = -1) : entries(ents), flags(flgs), indent(idt), order(ord) {} + + void addEntry(std::string value, std::string comment = "") { + entries.push_back(Entry(value, comment)); + } + }; + + typedef std::map<std::string, Setting> SettingList; + typedef std::pair<std::string, Setting> SettingPair; + typedef std::vector<SettingPair> OrderedSettingList; + + static bool OrderSortPredicate(const SettingPair& s1, const SettingPair& s2) { + return s1.second.order < s2.second.order; + } + + struct Property { + public: + SettingList settings; + int flags; + bool hasOrder; + + Property() : flags(0), hasOrder(false) {} + + // Constructs a simple Property + explicit Property(std::string name, std::string value = "", std::string comment = "", int flgs = 0, int indent = 0, bool order = false) : flags(flgs), hasOrder(order) { + Setting setting(value, comment, flags, indent); + + settings[name] = setting; + } + + Property(std::string name, ValueList values, int flgs = 0, int indent = 0, bool order = false) : flags(flgs), hasOrder(order) { + Setting setting(values, flags, indent); + + settings[name] = setting; + } + + // Copy constructor + Property(const Property &rhs) { + settings = rhs.settings; + flags = rhs.flags; + } + + OrderedSettingList getOrderedSettingList() { + OrderedSettingList list; + + // Prepare vector to sort + for (SettingList::const_iterator setting = settings.begin(); setting != settings.end(); ++setting) + list.push_back(SettingPair(setting->first, setting->second)); + + // Sort vector using setting order + if (hasOrder) + std::sort(list.begin(), list.end(), OrderSortPredicate); + + return list; + } + }; + + typedef std::map<std::string, Property> PropertyList; + + // Main object struct + // This is all a big hack unfortunately, but making everything all properly abstracted would + // be overkill since we only have to generate a single project + struct Object { + public: + std::string id; // Unique identifier for this object + std::string name; // Name (may not be unique - for ex. configuration entries) + std::string refType; // Type of object this references (if any) + std::string comment; // Main comment (empty for no comment) + + PropertyList properties; // List of object properties, including output configuration + + // Constructs an object and add a default type property + Object(XCodeProvider *objectParent, std::string objectId, std::string objectName, std::string objectType, std::string objectRefType = "", std::string objectComment = "") + : id(objectId), name(objectName), refType(objectRefType), comment(objectComment), parent(objectParent) { + assert(objectParent); + assert(!objectId.empty()); + assert(!objectName.empty()); + assert(!objectType.empty()); + + addProperty("isa", objectType, "", SettingsNoQuote|SettingsNoValue); + } + + // Add a simple Property with just a name and a value + void addProperty(std::string propName, std::string propValue, std::string propComment = "", int propFlags = 0, int propIndent = 0) { + properties[propName] = Property(propValue, "", propComment, propFlags, propIndent); + } + + std::string toString(int flags = 0) { + std::string output; + output = "\t\t" + parent->getHash(id) + (comment.empty() ? "" : " /* " + comment + " */") + " = {"; + + if (flags & SettingsAsList) + output += "\n"; + + // Special case: always output the isa property first + output += parent->writeProperty("isa", properties["isa"], flags); + + // Write each property + for (PropertyList::iterator property = properties.begin(); property != properties.end(); ++property) { + if ((*property).first == "isa") + continue; + + output += parent->writeProperty((*property).first, (*property).second, flags); + } + + if (flags & SettingsAsList) + output += "\t\t"; + + output += "};\n"; + + return output; + } + + private: + XCodeProvider *parent; + + // Returns the type property (should always be the first in the properties map) + std::string getType() { + assert(!properties.empty()); + assert(!properties["isa"].settings.empty()); + + SettingList::iterator it = properties["isa"].settings.begin(); + + return (*it).first; + } + }; + + struct ObjectList { + private: + std::map<std::string, bool> objectMap; + + public: + std::vector<Object *> objects; + std::string comment; + int flags; + + void add(Object *obj) { + std::map<std::string, bool>::iterator it = objectMap.find(obj->id); + if (it != objectMap.end() && it->second == true) + return; + + objects.push_back(obj); + objectMap[obj->id] = true; + } + + std::string toString() { + std::string output; + + if (!comment.empty()) + output = "\n/* Begin " + comment + " section */\n"; + + for (std::vector<Object *>::iterator object = objects.begin(); object != objects.end(); ++object) + output += (*object)->toString(flags); + + if (!comment.empty()) + output += "/* End " + comment + " section */\n"; + + return output; + } + }; + + // All objects + std::map<std::string, std::string> _hashDictionnary; + ValueList _defines; + + // Targets + ValueList _targets; + + // Lists of objects + ObjectList _buildFile; + ObjectList _copyFilesBuildPhase; + ObjectList _fileReference; + ObjectList _frameworksBuildPhase; + ObjectList _groups; + ObjectList _nativeTarget; + ObjectList _project; + ObjectList _resourcesBuildPhase; + ObjectList _sourcesBuildPhase; + ObjectList _buildConfiguration; + ObjectList _configurationList; + + void ouputMainProjectFile(const BuildSetup &setup); + + // Setup objects + void setupCopyFilesBuildPhase(); + void setupFrameworksBuildPhase(); + void setupNativeTarget(); + void setupProject(); + void setupResourcesBuildPhase(); + void setupSourcesBuildPhase(); + void setupBuildConfiguration(); + + // Misc + void setupDefines(const BuildSetup &setup); // Setup the list of defines to be used on build configurations + + // Hash generation + std::string getHash(std::string key); + std::string newHash() const; + + // Output + std::string writeProperty(const std::string &variable, Property &property, int flags = 0) const; + std::string writeSetting(const std::string &variable, std::string name, std::string comment = "", int flags = 0, int indent = 0) const; + std::string writeSetting(const std::string &variable, const Setting &setting) const; +}; + +} // End of CreateProjectTool namespace + +#endif // TOOLS_CREATE_PROJECT_XCODE_H diff --git a/devtools/create_project/xcode/create_project.xcodeproj/project.pbxproj b/devtools/create_project/xcode/create_project.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..f13bcf6969 --- /dev/null +++ b/devtools/create_project/xcode/create_project.xcodeproj/project.pbxproj @@ -0,0 +1,255 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + F9A66C691396D4DF00CEE494 /* codeblocks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9A66C5F1396D4DF00CEE494 /* codeblocks.cpp */; }; + F9A66C6A1396D4DF00CEE494 /* create_project.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9A66C621396D4DF00CEE494 /* create_project.cpp */; }; + F9A66C6B1396D4DF00CEE494 /* msbuild.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9A66C651396D4DF00CEE494 /* msbuild.cpp */; }; + F9A66C6C1396D4DF00CEE494 /* msvc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9A66C671396D4DF00CEE494 /* msvc.cpp */; }; + F9A66C6F1396D4E800CEE494 /* visualstudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9A66C6D1396D4E800CEE494 /* visualstudio.cpp */; }; + F9A66C871396E2F500CEE494 /* xcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F9A66C861396E2F500CEE494 /* xcode.cpp */; }; + F9A66C91139704A400CEE494 /* create_project in CopyFiles */ = {isa = PBXBuildFile; fileRef = F9A66C271396D36100CEE494 /* create_project */; }; + F9BA99141398064E00C276C2 /* create_project in CopyFiles */ = {isa = PBXBuildFile; fileRef = F9A66C271396D36100CEE494 /* create_project */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + F9A66C251396D36100CEE494 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 12; + dstPath = ../../../../../dists/iphone; + dstSubfolderSpec = 16; + files = ( + F9A66C91139704A400CEE494 /* create_project in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F9BA99131398063A00C276C2 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ../../../../../dists/macosx; + dstSubfolderSpec = 16; + files = ( + F9BA99141398064E00C276C2 /* create_project in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + F9A66C271396D36100CEE494 /* create_project */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = create_project; sourceTree = BUILT_PRODUCTS_DIR; }; + F9A66C491396D47500CEE494 /* installer.vbs */ = {isa = PBXFileReference; lastKnownFileType = text; name = installer.vbs; path = ../scripts/installer.vbs; sourceTree = "<group>"; }; + F9A66C4A1396D47500CEE494 /* postbuild.cmd */ = {isa = PBXFileReference; lastKnownFileType = text; name = postbuild.cmd; path = ../scripts/postbuild.cmd; sourceTree = "<group>"; }; + F9A66C4B1396D47500CEE494 /* prebuild.cmd */ = {isa = PBXFileReference; lastKnownFileType = text; name = prebuild.cmd; path = ../scripts/prebuild.cmd; sourceTree = "<group>"; }; + F9A66C4C1396D47500CEE494 /* revision.vbs */ = {isa = PBXFileReference; lastKnownFileType = text; name = revision.vbs; path = ../scripts/revision.vbs; sourceTree = "<group>"; }; + F9A66C5F1396D4DF00CEE494 /* codeblocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = codeblocks.cpp; path = ../codeblocks.cpp; sourceTree = "<group>"; }; + F9A66C601396D4DF00CEE494 /* codeblocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = codeblocks.h; path = ../codeblocks.h; sourceTree = "<group>"; }; + F9A66C611396D4DF00CEE494 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config.h; path = ../config.h; sourceTree = "<group>"; }; + F9A66C621396D4DF00CEE494 /* create_project.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = create_project.cpp; path = ../create_project.cpp; sourceTree = "<group>"; }; + F9A66C631396D4DF00CEE494 /* create_project.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = create_project.h; path = ../create_project.h; sourceTree = "<group>"; }; + F9A66C641396D4DF00CEE494 /* module.mk */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = module.mk; path = ../module.mk; sourceTree = "<group>"; }; + F9A66C651396D4DF00CEE494 /* msbuild.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = msbuild.cpp; path = ../msbuild.cpp; sourceTree = "<group>"; }; + F9A66C661396D4DF00CEE494 /* msbuild.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = msbuild.h; path = ../msbuild.h; sourceTree = "<group>"; }; + F9A66C671396D4DF00CEE494 /* msvc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = msvc.cpp; path = ../msvc.cpp; sourceTree = "<group>"; }; + F9A66C681396D4DF00CEE494 /* msvc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = msvc.h; path = ../msvc.h; sourceTree = "<group>"; }; + F9A66C6D1396D4E800CEE494 /* visualstudio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = visualstudio.cpp; path = ../visualstudio.cpp; sourceTree = "<group>"; }; + F9A66C6E1396D4E800CEE494 /* visualstudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = visualstudio.h; path = ../visualstudio.h; sourceTree = "<group>"; }; + F9A66C841396E2D800CEE494 /* xcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xcode.h; path = ../xcode.h; sourceTree = "<group>"; }; + F9A66C861396E2F500CEE494 /* xcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = xcode.cpp; path = ../xcode.cpp; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + F9A66C241396D36100CEE494 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + F9A66C1C1396D36100CEE494 = { + isa = PBXGroup; + children = ( + F9A66C861396E2F500CEE494 /* xcode.cpp */, + F9A66C841396E2D800CEE494 /* xcode.h */, + F9A66C6D1396D4E800CEE494 /* visualstudio.cpp */, + F9A66C6E1396D4E800CEE494 /* visualstudio.h */, + F9A66C5F1396D4DF00CEE494 /* codeblocks.cpp */, + F9A66C601396D4DF00CEE494 /* codeblocks.h */, + F9A66C611396D4DF00CEE494 /* config.h */, + F9A66C621396D4DF00CEE494 /* create_project.cpp */, + F9A66C631396D4DF00CEE494 /* create_project.h */, + F9A66C641396D4DF00CEE494 /* module.mk */, + F9A66C651396D4DF00CEE494 /* msbuild.cpp */, + F9A66C661396D4DF00CEE494 /* msbuild.h */, + F9A66C671396D4DF00CEE494 /* msvc.cpp */, + F9A66C681396D4DF00CEE494 /* msvc.h */, + F9A66C481396D45D00CEE494 /* Scripts */, + F9A66C281396D36100CEE494 /* Products */, + ); + sourceTree = "<group>"; + }; + F9A66C281396D36100CEE494 /* Products */ = { + isa = PBXGroup; + children = ( + F9A66C271396D36100CEE494 /* create_project */, + ); + name = Products; + sourceTree = "<group>"; + }; + F9A66C481396D45D00CEE494 /* Scripts */ = { + isa = PBXGroup; + children = ( + F9A66C491396D47500CEE494 /* installer.vbs */, + F9A66C4A1396D47500CEE494 /* postbuild.cmd */, + F9A66C4B1396D47500CEE494 /* prebuild.cmd */, + F9A66C4C1396D47500CEE494 /* revision.vbs */, + ); + name = Scripts; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + F9A66C261396D36100CEE494 /* create_project */ = { + isa = PBXNativeTarget; + buildConfigurationList = F9A66C301396D36100CEE494 /* Build configuration list for PBXNativeTarget "create_project" */; + buildPhases = ( + F9A66C231396D36100CEE494 /* Sources */, + F9A66C241396D36100CEE494 /* Frameworks */, + F9A66C251396D36100CEE494 /* CopyFiles */, + F9BA99131398063A00C276C2 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = create_project; + productName = create_project; + productReference = F9A66C271396D36100CEE494 /* create_project */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + F9A66C1E1396D36100CEE494 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = F9A66C211396D36100CEE494 /* Build configuration list for PBXProject "create_project" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = F9A66C1C1396D36100CEE494; + productRefGroup = F9A66C281396D36100CEE494 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + F9A66C261396D36100CEE494 /* create_project */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + F9A66C231396D36100CEE494 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F9A66C691396D4DF00CEE494 /* codeblocks.cpp in Sources */, + F9A66C6A1396D4DF00CEE494 /* create_project.cpp in Sources */, + F9A66C6B1396D4DF00CEE494 /* msbuild.cpp in Sources */, + F9A66C6C1396D4DF00CEE494 /* msvc.cpp in Sources */, + F9A66C6F1396D4E800CEE494 /* visualstudio.cpp in Sources */, + F9A66C871396E2F500CEE494 /* xcode.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + F9A66C2E1396D36100CEE494 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.5; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + F9A66C2F1396D36100CEE494 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.5; + SDKROOT = macosx; + }; + name = Release; + }; + F9A66C311396D36100CEE494 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + F9A66C321396D36100CEE494 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + F9A66C211396D36100CEE494 /* Build configuration list for PBXProject "create_project" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F9A66C2E1396D36100CEE494 /* Debug */, + F9A66C2F1396D36100CEE494 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F9A66C301396D36100CEE494 /* Build configuration list for PBXNativeTarget "create_project" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F9A66C311396D36100CEE494 /* Debug */, + F9A66C321396D36100CEE494 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = F9A66C1E1396D36100CEE494 /* Project object */; +} diff --git a/devtools/credits.pl b/devtools/credits.pl index f515844e4d..b0f40cbe6e 100755 --- a/devtools/credits.pl +++ b/devtools/credits.pl @@ -500,33 +500,7 @@ begin_credits("Credits"); add_person("Ludvig Strigeus", "ludde", "(retired)"); end_section(); - begin_section("Beneath a Steel Sky"); - add_person("Robert Göffringmann", "lavosspawn", "(retired)"); - add_person("Oliver Kiehl", "olki", "(retired)"); - add_person("Joost Peters", "joostp", ""); - end_section(); - - begin_section("Broken Sword"); - add_person("Fabio Battaglia", "Hkz", "PSX version support"); - add_person("Thierry Crozat", "criezy", "Mac version support"); - add_person("Robert Göffringmann", "lavosspawn", "(retired)"); - end_section(); - - begin_section("Broken Sword II"); - add_person("Torbjörn Andersson", "eriktorbjorn", ""); - add_person("Fabio Battaglia", "Hkz", "PSX version support"); - add_person("Jonathan Gray", "khalek", "(retired)"); - end_section(); - - begin_section("Broken Sword 2.5"); - add_person("Eugene Sandulenko", "sev", ""); - add_person("Filippos Karapetis", "[md5]", ""); - add_person("Max Horn", "Fingolfin", ""); - add_person("Paul Gilbert", "dreammaster", ""); - add_person("Torbjörn Andersson", "eriktorbjorn", ""); - end_section(); - - begin_section("Cinematique evo 1"); + begin_section("Cine"); add_person("Vincent Hamm", "yaz0r", "(retired)"); add_person("Paweł Kołodziejski", "aquadran", ""); add_person("Gregory Montoir", "cyx", ""); @@ -534,12 +508,12 @@ begin_credits("Credits"); add_person("Eugene Sandulenko", "sev", ""); end_section(); - begin_section("Cinematique evo 2"); + begin_section("CruisE"); add_person("Paul Gilbert", "dreammaster", ""); add_person("Vincent Hamm", "yaz0r", "(retired)"); end_section(); - begin_section("Draci Historie"); + begin_section("Draci"); add_person("Denis Kasak", "dkasak13", ""); add_person("Robert Špalek", "spalek", ""); end_section(); @@ -549,12 +523,6 @@ begin_credits("Credits"); add_person("Paweł Kołodziejski", "aquadran", ""); end_section(); - begin_section("Flight of the Amazon Queen"); - add_person("David Eriksson", "twogood", "(retired)"); - add_person("Gregory Montoir", "cyx", ""); - add_person("Joost Peters", "joostp", ""); - end_section(); - begin_section("Gob"); add_person("Torbjörn Andersson", "eriktorbjorn", ""); add_person("Arnaud Boutonné", "Strangerke", ""); @@ -582,13 +550,13 @@ begin_credits("Credits"); add_person("Johannes Schickel", "LordHoto", ""); end_section(); - begin_section("Last Express"); + begin_section("Lastexpress"); add_person("Matthew Hoops", "clone2727", ""); add_person("Jordi Vilalta Prat", "jvprat", ""); add_person("Julien Templier", "littleboy", ""); end_section(); - begin_section("Lure of the Temptress"); + begin_section("Lure"); add_person("Paul Gilbert", "dreammaster", ""); end_section(); @@ -617,6 +585,12 @@ begin_credits("Credits"); add_person("", "peres", ""); end_section(); + begin_section("Queen"); + add_person("David Eriksson", "twogood", "(retired)"); + add_person("Gregory Montoir", "cyx", ""); + add_person("Joost Peters", "joostp", ""); + end_section(); + begin_section("SAGA"); add_person("Torbjörn Andersson", "eriktorbjorn", ""); add_person("Filippos Karapetis", "[md5]", ""); @@ -636,7 +610,33 @@ begin_credits("Credits"); add_person("Lars Skovlund", "lskovlun", ""); end_section(); - begin_section("Teen Agent"); + begin_section("Sky"); + add_person("Robert Göffringmann", "lavosspawn", "(retired)"); + add_person("Oliver Kiehl", "olki", "(retired)"); + add_person("Joost Peters", "joostp", ""); + end_section(); + + begin_section("Sword1"); + add_person("Fabio Battaglia", "Hkz", "PSX version support"); + add_person("Thierry Crozat", "criezy", "Mac version support"); + add_person("Robert Göffringmann", "lavosspawn", "(retired)"); + end_section(); + + begin_section("Sword2"); + add_person("Torbjörn Andersson", "eriktorbjorn", ""); + add_person("Fabio Battaglia", "Hkz", "PSX version support"); + add_person("Jonathan Gray", "khalek", "(retired)"); + end_section(); + + begin_section("Sword25"); + add_person("Eugene Sandulenko", "sev", ""); + add_person("Filippos Karapetis", "[md5]", ""); + add_person("Max Horn", "Fingolfin", ""); + add_person("Paul Gilbert", "dreammaster", ""); + add_person("Torbjörn Andersson", "eriktorbjorn", ""); + end_section(); + + begin_section("TeenAgent"); add_person("Robert Megone", "sanguine", "Help with callback rewriting"); add_person("Vladimir Menshakov", "whoozle", ""); end_section(); @@ -712,7 +712,8 @@ begin_credits("Credits"); begin_section("PocketPC / WinCE"); add_person("Nicolas Bacca", "arisme", "(retired)"); - add_person("Kostas Nakos", "Jubanka", ""); + add_person("Ismail Khatib", "CeRiAl", ""); + add_person("Kostas Nakos", "Jubanka", "(retired)"); end_section(); begin_section("PlayStation 2"); |