diff options
49 files changed, 1513 insertions, 507 deletions
diff --git a/.gitignore b/.gitignore index bff5ead245..906c6a8a83 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,8 @@ lib*.a /.cproject /.settings +/build + /backends/platform/dc/gui /backends/platform/dc/graphics /backends/platform/dc/sound diff --git a/common/macresman.cpp b/common/macresman.cpp index 489f8f93ce..0ecb430532 100644 --- a/common/macresman.cpp +++ b/common/macresman.cpp @@ -550,132 +550,4 @@ void MacResManager::readMap() { } } -void MacResManager::convertCrsrCursor(SeekableReadStream *data, byte **cursor, int &w, int &h, int &hotspotX, - int &hotspotY, int &keycolor, bool colored, byte **palette, int &palSize) { - - data->readUint16BE(); // type - data->readUint32BE(); // offset to pixel map - data->readUint32BE(); // offset to pixel data - data->readUint32BE(); // expanded cursor data - data->readUint16BE(); // expanded data depth - data->readUint32BE(); // reserved - - // Grab B/W icon data - *cursor = new byte[16 * 16]; - for (int i = 0; i < 32; i++) { - byte imageByte = data->readByte(); - for (int b = 0; b < 8; b++) - cursor[0][i * 8 + b] = (byte)((imageByte & (0x80 >> b)) > 0 ? 0x0F : 0x00); - } - - // Apply mask data - for (int i = 0; i < 32; i++) { - byte imageByte = data->readByte(); - for (int b = 0; b < 8; b++) - if ((imageByte & (0x80 >> b)) == 0) - cursor[0][i * 8 + b] = 0xff; - } - - hotspotY = data->readUint16BE(); - hotspotX = data->readUint16BE(); - w = h = 16; - keycolor = 0xff; - - // Use b/w cursor on backends which don't support cursor palettes - if (!colored) - return; - - data->readUint32BE(); // reserved - data->readUint32BE(); // cursorID - - // Color version of cursor - data->readUint32BE(); // baseAddr - - // Keep only lowbyte for now - data->readByte(); - int iconRowBytes = data->readByte(); - - if (!iconRowBytes) - return; - - int iconBounds[4]; - iconBounds[0] = data->readUint16BE(); - iconBounds[1] = data->readUint16BE(); - iconBounds[2] = data->readUint16BE(); - iconBounds[3] = data->readUint16BE(); - - data->readUint16BE(); // pmVersion - data->readUint16BE(); // packType - data->readUint32BE(); // packSize - - data->readUint32BE(); // hRes - data->readUint32BE(); // vRes - - data->readUint16BE(); // pixelType - data->readUint16BE(); // pixelSize - data->readUint16BE(); // cmpCount - data->readUint16BE(); // cmpSize - - data->readUint32BE(); // planeByte - data->readUint32BE(); // pmTable - data->readUint32BE(); // reserved - - // Pixel data for cursor - int iconDataSize = iconRowBytes * (iconBounds[3] - iconBounds[1]); - byte *iconData = new byte[iconDataSize]; - - if (!iconData) { - error("Cannot allocate iconData in macresman.cpp"); - } - - data->read(iconData, iconDataSize); - - // Color table - data->readUint32BE(); // ctSeed - data->readUint16BE(); // ctFlag - uint16 ctSize = data->readUint16BE() + 1; - - *palette = new byte[ctSize * 3]; - - // Read just high byte of 16-bit color - for (int c = 0; c < ctSize; c++) { - // We just use indices 0..ctSize, so ignore color ID - data->readUint16BE(); // colorID[c] - - palette[0][c * 3 + 0] = data->readByte(); - data->readByte(); - - palette[0][c * 3 + 1] = data->readByte(); - data->readByte(); - - palette[0][c * 3 + 2] = data->readByte(); - data->readByte(); - } - - palSize = ctSize; - - int pixelsPerByte = (iconBounds[2] - iconBounds[0]) / iconRowBytes; - int bpp = 8 / pixelsPerByte; - - // build a mask to make sure the pixels are properly shifted out - int bitmask = 0; - for (int m = 0; m < bpp; m++) { - bitmask <<= 1; - bitmask |= 1; - } - - // Extract pixels from bytes - for (int j = 0; j < iconDataSize; j++) - for (int b = 0; b < pixelsPerByte; b++) { - int idx = j * pixelsPerByte + (pixelsPerByte - 1 - b); - - if (cursor[0][idx] != 0xff) // if mask is not there - cursor[0][idx] = (byte)((iconData[j] >> (b * bpp)) & bitmask); - } - - delete[] iconData; - - assert(data->size() - data->pos() == 0); -} - } // End of namespace Common diff --git a/common/macresman.h b/common/macresman.h index fdb3ce491d..f588d8f853 100644 --- a/common/macresman.h +++ b/common/macresman.h @@ -152,25 +152,6 @@ public: String getBaseFileName() const { return _baseFileName; } /** - * Convert cursor from crsr format to format suitable for feeding to CursorMan - * @param data Pointer to the cursor datax - * @param cursor Pointer to memory where result cursor will be stored. The memory - * block will be malloc()'ed - * @param w Pointer to int where the cursor width will be stored - * @param h Pointer to int where the cursor height will be stored - * @param hotspotX Storage for cursor hotspot X coordinate - * @param hotspotY Storage for cursor hotspot Y coordinate - * @param keycolor Pointer to int where the transpared color value will be stored - * @param colored If set to true then colored cursor will be returned (if any). - * b/w version will be used otherwise - * @param palette Pointer to memory where the cursor palette will be stored. - * The memory will be malloc()'ed - * @param palSize Pointer to integer where the palette size will be stored. - */ - static void convertCrsrCursor(SeekableReadStream *data, byte **cursor, int &w, int &h, int &hotspotX, - int &hotspotY, int &keycolor, bool colored, byte **palette, int &palSize); - - /** * Return list of resource IDs with specified type ID */ MacResIDArray getResIDArray(uint32 typeID); diff --git a/common/stream.cpp b/common/stream.cpp index e870e68b2d..a785ac5164 100644 --- a/common/stream.cpp +++ b/common/stream.cpp @@ -242,6 +242,13 @@ bool SeekableSubReadStream::seek(int32 offset, int whence) { return ret; } +uint32 SafeSubReadStream::read(void *dataPtr, uint32 dataSize) { + // Make sure the parent stream is at the right position + seek(0, SEEK_CUR); + + return SeekableSubReadStream::read(dataPtr, dataSize); +} + #pragma mark - diff --git a/common/substream.h b/common/substream.h index ecf11c54c9..8b83dbda2e 100644 --- a/common/substream.h +++ b/common/substream.h @@ -102,6 +102,25 @@ public: } }; +/** + * A seekable substream that removes the exclusivity demand required by the + * normal SeekableSubReadStream, at the cost of seek()ing the parent stream + * before each read(). + * + * More than one SafeSubReadStream to the same parent stream can be used + * at the same time; they won't mess up each other. They will, however, + * reposition the parent stream, so don't depend on its position to be + * the same after a read() or seek() on one of its SafeSubReadStream. + */ +class SafeSubReadStream : public SeekableSubReadStream { +public: + SafeSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO) : + SeekableSubReadStream(parentStream, begin, end, disposeParentStream) { + } + + virtual uint32 read(void *dataPtr, uint32 dataSize); +}; + } // End of namespace Common @@ -173,7 +173,7 @@ _strip=strip _ar="ar cru" _as="as" _windres=windres -_win32path="C:/scummvm" +_win32path="build/x86" _aos4path="Games:ScummVM" _staticlibpath=/sw _sdlconfig=sdl-config diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp index 35f68a12c0..7d112c7ffe 100644 --- a/devtools/create_project/create_project.cpp +++ b/devtools/create_project/create_project.cpp @@ -245,6 +245,9 @@ int main(int argc, char *argv[]) { } else if (!std::strcmp(argv[i], "--build-events")) { setup.runBuildEvents = true; + } else if (!std::strcmp(argv[i], "--installer")) { + setup.runBuildEvents = true; + setup.createInstaller = true; } else { std::cerr << "ERROR: Unknown parameter \"" << argv[i] << "\"\n"; return -1; @@ -516,6 +519,8 @@ void displayHelp(const char *exe) { " The default is \"9\", thus \"Visual Studio 2008\"\n" " --build-events Run custom build events as part of the build\n" " (default: false)\n" + " --installer Create NSIS installer after the build (implies --build-events)\n" + " (default: false)\n" "\n" "Engines settings:\n" " --list-engines list all available engines and their default state\n" diff --git a/devtools/create_project/create_project.h b/devtools/create_project/create_project.h index f4d2a0a66a..e4ccd7313a 100644 --- a/devtools/create_project/create_project.h +++ b/devtools/create_project/create_project.h @@ -192,10 +192,12 @@ struct BuildSetup { StringList defines; ///< List of all defines for the build. StringList libraries; ///< List of all external libraries required for the build. - bool runBuildEvents; + bool runBuildEvents; ///< Run build events as part of the build (generate revision number and copy engine/theme data & needed files to the build folder + bool createInstaller; ///< Create NSIS installer after the build BuildSetup() { - runBuildEvents = false; + runBuildEvents = false; + createInstaller = false; } }; diff --git a/devtools/create_project/msbuild.cpp b/devtools/create_project/msbuild.cpp index 8143c92c35..f9a2e936f0 100644 --- a/devtools/create_project/msbuild.cpp +++ b/devtools/create_project/msbuild.cpp @@ -283,7 +283,7 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s // Copy data files to the build folder project << "\t\t<PostBuildEvent>\n" "\t\t\t<Message>Copy data files to the build folder</Message>\n" - "\t\t\t<Command>" << getPostBuildEvent(isWin32) << "</Command>\n" + "\t\t\t<Command>" << getPostBuildEvent(isWin32, setup.createInstaller) << "</Command>\n" "\t\t</PostBuildEvent>\n"; } } diff --git a/devtools/create_project/msvc.cpp b/devtools/create_project/msvc.cpp index 49998cd738..af3aa4a519 100644 --- a/devtools/create_project/msvc.cpp +++ b/devtools/create_project/msvc.cpp @@ -158,7 +158,7 @@ std::string MSVCProvider::getPreBuildEvent() const { return cmdLine; } -std::string MSVCProvider::getPostBuildEvent(bool isWin32) const { +std::string MSVCProvider::getPostBuildEvent(bool isWin32, bool createInstaller) const { std::string cmdLine = ""; cmdLine = "@echo off\n" @@ -168,7 +168,10 @@ std::string MSVCProvider::getPostBuildEvent(bool isWin32) const { cmdLine += (isWin32) ? "x86" : "x64"; - cmdLine += " %SCUMMVM_LIBS%"; + cmdLine += " %SCUMMVM_LIBS% "; + + // Specify if installer needs to be built or not + cmdLine += (createInstaller ? "1" : "0"); cmdLine += "\n" "EXIT /B0"; diff --git a/devtools/create_project/msvc.h b/devtools/create_project/msvc.h index b2f2a5d33f..6c8ac33a76 100644 --- a/devtools/create_project/msvc.h +++ b/devtools/create_project/msvc.h @@ -89,11 +89,14 @@ protected: std::string getPreBuildEvent() const; /** - * Get the command line for copying data files to the build directory + * Get the command line for copying data files to the build directory. * - * @param isWin32 Bitness of property file + * @param isWin32 Bitness of property file. + * @param createInstaller true to NSIS create installer + * + * @return The post build event. */ - std::string getPostBuildEvent(bool isWin32) const; + std::string getPostBuildEvent(bool isWin32, bool createInstaller) const; }; } // End of CreateProjectTool namespace diff --git a/devtools/create_project/msvc10/create_project.vcxproj b/devtools/create_project/msvc10/create_project.vcxproj index 15ce217bfc..bf5e415b5d 100644 --- a/devtools/create_project/msvc10/create_project.vcxproj +++ b/devtools/create_project/msvc10/create_project.vcxproj @@ -108,6 +108,7 @@ xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\codeblocks\</Command> <ClInclude Include="..\visualstudio.h" /> </ItemGroup> <ItemGroup> + <None Include="..\scripts\installer.vbs" /> <None Include="..\scripts\postbuild.cmd" /> <None Include="..\scripts\prebuild.cmd" /> <None Include="..\scripts\revision.vbs" /> diff --git a/devtools/create_project/msvc10/create_project.vcxproj.filters b/devtools/create_project/msvc10/create_project.vcxproj.filters index 42db5aa97e..b5e870824e 100644 --- a/devtools/create_project/msvc10/create_project.vcxproj.filters +++ b/devtools/create_project/msvc10/create_project.vcxproj.filters @@ -58,5 +58,8 @@ <None Include="..\scripts\postbuild.cmd"> <Filter>scripts</Filter> </None> + <None Include="..\scripts\installer.vbs"> + <Filter>scripts</Filter> + </None> </ItemGroup> </Project>
\ No newline at end of file diff --git a/devtools/create_project/msvc8/create_project.vcproj b/devtools/create_project/msvc8/create_project.vcproj index 9cd833ea23..639b23d6e7 100644 --- a/devtools/create_project/msvc8/create_project.vcproj +++ b/devtools/create_project/msvc8/create_project.vcproj @@ -232,6 +232,10 @@ RelativePath="..\scripts\revision.vbs" > </File> + <File + RelativePath="..\scripts\installer.vbs" + > + </File> </Filter> </Files> <Globals> diff --git a/devtools/create_project/msvc9/create_project.vcproj b/devtools/create_project/msvc9/create_project.vcproj index 4e0375c35e..f56cbd711c 100644 --- a/devtools/create_project/msvc9/create_project.vcproj +++ b/devtools/create_project/msvc9/create_project.vcproj @@ -233,6 +233,10 @@ RelativePath="..\scripts\revision.vbs" > </File> + <File + RelativePath="..\scripts\installer.vbs" + > + </File> </Filter> </Files> <Globals> diff --git a/devtools/create_project/scripts/installer.vbs b/devtools/create_project/scripts/installer.vbs new file mode 100644 index 0000000000..6bcd794bef --- /dev/null +++ b/devtools/create_project/scripts/installer.vbs @@ -0,0 +1,196 @@ +' +' 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, version 2 +' of the License. +' +' 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. +' +'/ + +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +' This script calls the makensis tool to generate a NSIS Windows installer for ScummVM +' +' It tries to read the NSIS installation folder from the registry and then calls the +' command line script compiler to create the installer. +' +' This is called from the postbuild.cmd batch file +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +'================================================================ +' TODO: Reduce duplication with revision.vbs script +' (ReadRegistryKey and ParseCommandLine are identical) +'================================================================ + +Option Explicit + +Dim FSO : Set FSO = CreateObject("Scripting.FileSystemObject") +Dim WshShell : Set WshShell = CreateObject("WScript.Shell") + +' Folders +Dim rootFolder : rootFolder = "" +Dim targetFolder : targetFolder = "" +Dim arch : arch = "" + +' Parse our command line arguments +If ParseCommandLine() Then + CreateInstaller() +End If + +'//////////////////////////////////////////////////////////////// +'// Installer creation +'//////////////////////////////////////////////////////////////// +Sub CreateInstaller() + ' Get nsis installation folder + Dim nsisPath : nsisPath = GetNSISPath() + If (nsisPath = "") Then + Exit Sub + End If + + ' Preprocess architecture + Select Case arch + Case "x86" + arch = "win32" + + Case "x64" + arch = "win64" + End Select + + ' Build command line + Dim commandLine : commandLine = """" & nsisPath & "\makensis.exe"" /V2" & _ + " /Dtop_srcdir=""" & rootFolder & """" & _ + " /Dbuild_dir=""" & targetFolder & """" & _ + " /Dtext_dir=""" & targetFolder & """" & _ + " /DARCH=""" & arch & """" & _ + " """ & rootFolder & "\dists\nsis\scummvm.nsi""" + + Dim oExec: Set oExec = WshShell.Exec(commandline) + If Err.Number <> 0 Then + Wscript.StdErr.WriteLine "Error running makensis.exe!" + Exit Sub + End If + + ' Wait till the application is finished ... + Dim ostdOut : Set oStdOut = oExec.StdOut + Do While oExec.Status = 0 + If Not ostdOut.AtEndOfStream Then + Wscript.StdErr.WriteLine ostdOut.ReadAll + End If + + WScript.Sleep 100 + Loop + + If oExec.ExitCode <> 0 Then + Wscript.StdErr.WriteLine "Error while creating installer!" + Exit Sub + End If +End Sub + +Function GetNSISPath() + ' Get the directory where NSIS (should) reside(s) + Dim sNSIS + + ' First, try with 32-bit architecture + sNSIS = ReadRegistryKey("HKLM", "SOFTWARE\NSIS", "", 32) + + If sNSIS = "" Or IsNull(sNSIS) Then + ' No 32-bit version of TortoiseSVN installed, try 64-bit version (doesn't hurt on 32-bit machines, it returns nothing or is ignored) + sNSIS = ReadRegistryKey("HKLM", "SOFTWARE\NSIS", "", 64) + End If + + ' Check if Tortoise is present + If sNSIS = "" Then + Wscript.StdErr.WriteLine "NSIS not installed!" + Exit Function + End If + + GetNSISPath = sNSIS +End Function + +'//////////////////////////////////////////////////////////////// +'// Utilities +'//////////////////////////////////////////////////////////////// +Function ParseCommandLine() + ParseCommandLine = True + + If Wscript.Arguments.Count <> 3 Then + Wscript.StdErr.WriteLine "[Error] Invalid number of arguments (was: " & Wscript.Arguments.Count & ", expected: 3)" + + ParseCommandLine = False + Exit Function + End If + + ' Get our arguments + rootFolder = Wscript.Arguments.Item(0) + targetFolder = Wscript.Arguments.Item(1) + arch = Wscript.Arguments.Item(2) + + ' Check that the folders are valid + If Not FSO.FolderExists(rootFolder) Then + Wscript.StdErr.WriteLine "[Error] Invalid root folder (" & rootFolder & ")" + + ParseCommandLine = False + Exit Function + End If + + If Not FSO.FolderExists(targetFolder) Then + Wscript.StdErr.WriteLine "[Error] Invalid target folder (" & targetFolder & ")" + + ParseCommandLine = False + Exit Function + End If + + ' Set absolute paths + rootFolder = FSO.GetAbsolutePathName(rootFolder) + targetFolder = FSO.GetAbsolutePathName(targetFolder) +End Function + +Function ReadRegistryKey(shive, subkey, valuename, architecture) + Dim hiveKey, objCtx, objLocator, objServices, objReg, Inparams, Outparams + + ' First, get the Registry Provider for the requested architecture + Set objCtx = CreateObject("WbemScripting.SWbemNamedValueSet") + objCtx.Add "__ProviderArchitecture", architecture ' Must be 64 of 32 + Set objLocator = CreateObject("Wbemscripting.SWbemLocator") + Set objServices = objLocator.ConnectServer("","root\default","","",,,,objCtx) + Set objReg = objServices.Get("StdRegProv") + + ' Check the hive and give it the right value + Select Case shive + Case "HKCR", "HKEY_CLASSES_ROOT" + hiveKey = &h80000000 + Case "HKCU", "HKEY_CURRENT_USER" + hiveKey = &H80000001 + Case "HKLM", "HKEY_LOCAL_MACHINE" + hiveKey = &h80000002 + Case "HKU", "HKEY_USERS" + hiveKey = &h80000003 + Case "HKCC", "HKEY_CURRENT_CONFIG" + hiveKey = &h80000005 + Case "HKDD", "HKEY_DYN_DATA" ' Only valid for Windows 95/98 + hiveKey = &h80000006 + Case Else + MsgBox "Hive not valid (ReadRegistryKey)" + End Select + + Set Inparams = objReg.Methods_("GetStringValue").Inparameters + Inparams.Hdefkey = hiveKey + Inparams.Ssubkeyname = subkey + Inparams.Svaluename = valuename + Set Outparams = objReg.ExecMethod_("GetStringValue", Inparams,,objCtx) + + ReadRegistryKey = Outparams.SValue +End Function diff --git a/devtools/create_project/scripts/postbuild.cmd b/devtools/create_project/scripts/postbuild.cmd index e5f29058b9..e78861463a 100644 --- a/devtools/create_project/scripts/postbuild.cmd +++ b/devtools/create_project/scripts/postbuild.cmd @@ -1,36 +1,52 @@ -REM @echo off
+@echo off
REM ---------------------------------------------------------------
REM -- Post-Build Script
REM ---------------------------------------------------------------
REM
REM Copy engine data, themes, translation and required dlls to the
-REM output folder.
+REM output folder and optionally create an installer
REM
REM Expected parameters
REM Root folder
REM Output folder
REM Architecture
REM Libs folder
+REM Installer ("1" to build, "0" to skip)
if "%~1"=="" goto error_root
if "%~2"=="" goto error_output
if "%~3"=="" goto error_arch
if "%~4"=="" goto error_libs
+if "%~5"=="" goto error_installer
echo Copying data files
echo.
-REM Copy files
-xcopy /F /Y "%~1/dists/engine-data/*.dat" %~2 > NUL 2>&1
-xcopy /F /Y "%~1/dists/engine-data/*.tbl" %~2 > NUL 2>&1
-xcopy /F /Y "%~1/dists/engine-data/*.cpt" %~2 > NUL 2>&1
-xcopy /F /Y "%~1/dists/engine-data/README" %~2 > NUL 2>&1
-xcopy /F /Y "%~1/gui/themes/*.zip" %~2 > NUL 2>&1
+xcopy /F /Y "%~1/AUTHORS" %~2 > NUL 2>&1
+xcopy /F /Y "%~1/COPYING.GPL" %~2 > NUL 2>&1
+xcopy /F /Y "%~1/COPYING" %~2 > NUL 2>&1
+xcopy /F /Y "%~1/COPYING.LGPL" %~2 > NUL 2>&1
+xcopy /F /Y "%~1/COPYRIGHT" %~2 > NUL 2>&1
+xcopy /F /Y "%~1/NEWS" %~2 > NUL 2>&1
+xcopy /F /Y "%~1/README" %~2 > NUL 2>&1
+
+xcopy /F /Y "%~1/dists/engine-data/*.dat" %~2 > NUL 2>&1
+xcopy /F /Y "%~1/dists/engine-data/*.tbl" %~2 > NUL 2>&1
+xcopy /F /Y "%~1/dists/engine-data/*.cpt" %~2 > NUL 2>&1
+xcopy /F /Y "%~1/gui/themes/*.zip" %~2 > NUL 2>&1
xcopy /F /Y "%~1/gui/themes/translations.dat" %~2 > NUL 2>&1
-xcopy /F /Y "%~4/lib/%~3/SDL.dll" %~2 > NUL 2>&1
+xcopy /F /Y "%~4/lib/%~3/SDL.dll" %~2 > NUL 2>&1
+xcopy /F /Y "%~4/README-SDL" %~2 > NUL 2>&1
xcopy /F /Y "%~1/backends/vkeybd/packs/vkeybd_default.zip" %~2 > NUL 2>&1
+
+if "%~5"=="0" goto done
+
+echo Running installer script
+echo.
+@call cscript "%~1/devtools/create_project/scripts/installer.vbs" %~1 %~2 %~3 1>NUL
+if not %errorlevel% == 0 goto error_script
goto done
:error_root
@@ -49,5 +65,13 @@ goto done echo Invalid libs folder (%~4)!
goto done
+:error_installer
+echo Invalid installer parameter. Should be "0" or "1" (was %~5)!
+goto done
+
+:error_script:
+echo An error occured while running the installer script!
+goto done
+
:done
exit /B0
diff --git a/devtools/create_project/scripts/revision.vbs b/devtools/create_project/scripts/revision.vbs index 9c29a88f2d..3e1212521c 100644 --- a/devtools/create_project/scripts/revision.vbs +++ b/devtools/create_project/scripts/revision.vbs @@ -23,6 +23,21 @@ ' '/ +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +' This script tries to determine a revision number based on the current working tree +' by trying revision control tools in the following order: +' - git (with hg-git detection) +' - mercurial +' - TortoiseSVN +' - SVN +' +' It then writes a new header file to be included during build, with the revision +' information, the current branch, the revision control system (when not git) and +' a flag when the tree is dirty. +' +' This is called from the prebuild.cmd batch file +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + Option Explicit ' Working copy check priority: @@ -82,14 +97,15 @@ Sub DetermineRevision() End If End If End If - - Wscript.StdErr.WriteLine "Found revision " & revision & " on branch " & branch & vbCrLf - + + Dim outputInfo : outputInfo = "Found revision " & revision & " on branch " & branch + ' Setup our revision string Dim revisionString : revisionString = revision If (modified) Then revisionString = revisionString & "-dirty" + outputInfo = outputInfo & " (dirty)" End If ' If we are not on trunk, add the branch name to the revision string @@ -100,7 +116,10 @@ Sub DetermineRevision() ' Add the DVCS name at the end (when not git) If (tool <> "git") Then revisionString = revisionString & "-" & tool + outputInfo = outputInfo & " using " & tool End If + + Wscript.StdErr.WriteLine outputInfo & vbCrLf ' Output revision header file FSO.CopyFile rootFolder & "\\base\\internal_revision.h.in", targetFolder & "\\internal_revision.h" @@ -213,10 +232,11 @@ Function DetermineGitVersion() Err.Clear On Error Resume Next DetermineGitVersion = False + Dim line Wscript.StdErr.Write " Git... " tool = "git" - ' First check if we have both a .git & .svn folders (in case hg-git has been set up to have the git folder at the working copy level) + ' First check if we have both a .git & .hg folders (in case hg-git has been set up to have the git folder at the working copy level) If FSO.FolderExists(rootFolder & "/.git") And FSO.FolderExists(rootFolder & "/.hg") Then Wscript.StdErr.WriteLine "Mercurial clone with git repository in tree!" Exit Function @@ -250,10 +270,10 @@ Function DetermineGitVersion() End If ' Get the version hash - Dim hash: hash = oExec.StdOut.ReadLine() + Dim hash : hash = oExec.StdOut.ReadLine() ' Make sure index is in sync with disk - Set oExec = WshShell.Exec(gitPath & "update-index --refresh") + Set oExec = WshShell.Exec(gitPath & "update-index --refresh --unmerged") If Err.Number = 0 Then ' Wait till the application is finished ... Do While oExec.Status = 0 @@ -261,7 +281,7 @@ Function DetermineGitVersion() Loop End If - Set oExec = WshShell.Exec(gitPath & "diff-index --exit-code --quiet HEAD " & rootFolder) + Set oExec = WshShell.Exec(gitPath & "diff-index --quiet HEAD " & rootFolder) If oExec.ExitCode <> 0 Then Wscript.StdErr.WriteLine "Error parsing git revision!" Exit Function @@ -279,14 +299,24 @@ Function DetermineGitVersion() ' Get branch name Set oExec = WshShell.Exec(gitPath & "symbolic-ref HEAD") If Err.Number = 0 Then - Dim line: line = oExec.StdOut.ReadLine() + line = oExec.StdOut.ReadLine() line = Mid(line, InStrRev(line, "/") + 1) If line <> "master" Then branch = line End If End If - ' Fallback to abbreviated revision number + ' Get revision description + Set oExec = WshShell.Exec(gitPath & "describe --match desc/*") + If Err.Number = 0 Then + line = oExec.StdOut.ReadLine() + line = Mid(line, InStr(line, "-") + 1) + If line <> "" Then + revision = line + End If + End If + + ' Fallback to abbreviated revision number if needed If revision = "" Then revision = Mid(hash, 1, 7) End If diff --git a/devtools/create_project/visualstudio.cpp b/devtools/create_project/visualstudio.cpp index 1c52e9d3c1..8642f071ff 100644 --- a/devtools/create_project/visualstudio.cpp +++ b/devtools/create_project/visualstudio.cpp @@ -148,7 +148,7 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std: void VisualStudioProvider::outputConfiguration(std::ostream &project, const BuildSetup &setup, const std::string &libraries, const std::string &config, const std::string &platform, const std::string &props, const bool isWin32) { project << "\t\t<Configuration Name=\"" << config << "|" << platform << "\" ConfigurationType=\"1\" InheritedPropertySheets=\".\\" << PROJECT_DESCRIPTION << "_" << config << props << ".vsprops\">\n" "\t\t\t<Tool\tName=\"VCCLCompilerTool\" DisableLanguageExtensions=\"false\" />\n" - "\t\t\t<Tool\tName=\"VCLinkerTool\" OutputFile=\"$(OutDir)/" << PROJECT_NAME << "\"\n" + "\t\t\t<Tool\tName=\"VCLinkerTool\" OutputFile=\"$(OutDir)/" << PROJECT_NAME << ".exe\"\n" "\t\t\t\tAdditionalDependencies=\"" << libraries << "\"\n" "\t\t\t/>\n"; outputBuildEvents(project, setup, isWin32); @@ -167,7 +167,7 @@ void VisualStudioProvider::outputBuildEvents(std::ostream &project, const BuildS "\t\t\t\tCommandLine=\"" << getPreBuildEvent() << "\"\n" "\t\t\t/>\n" "\t\t\t<Tool\tName=\"VCPostBuildEventTool\"\n" - "\t\t\t\tCommandLine=\"" << getPostBuildEvent(isWin32) << "\"\n" + "\t\t\t\tCommandLine=\"" << getPostBuildEvent(isWin32, setup.createInstaller) << "\"\n" "\t\t\t/>\n"; } } @@ -223,8 +223,7 @@ void VisualStudioProvider::outputGlobalPropFile(std::ofstream &properties, int b properties << "\t\tRuntimeTypeInfo=\"false\"\n"; #endif - properties << "\t\tRuntimeTypeInfo=\"false\"\n" - "\t\tWarningLevel=\"4\"\n" + properties << "\t\tWarningLevel=\"4\"\n" "\t\tWarnAsError=\"false\"\n" "\t\tCompileAs=\"0\"\n" "\t\t/>\n" diff --git a/devtools/update-version.pl b/devtools/update-version.pl index 91e9e2492b..788cbc7e40 100755 --- a/devtools/update-version.pl +++ b/devtools/update-version.pl @@ -39,6 +39,7 @@ my @subs_files = qw( dists/macosx/Info.plist dists/iphone/Info.plist dists/irix/scummvm.spec + dists/nsis/scummvm.nsi dists/wii/meta.xml dists/android/AndroidManifest.xml dists/android/plugin-manifest.xml diff --git a/dists/nsis/graphics/left.bmp b/dists/nsis/graphics/left.bmp Binary files differnew file mode 100644 index 0000000000..8b31d7d09a --- /dev/null +++ b/dists/nsis/graphics/left.bmp diff --git a/dists/nsis/graphics/scummvm-install.ico b/dists/nsis/graphics/scummvm-install.ico Binary files differnew file mode 100644 index 0000000000..b8b118c7bd --- /dev/null +++ b/dists/nsis/graphics/scummvm-install.ico diff --git a/dists/nsis/scummvm.nsi b/dists/nsis/scummvm.nsi new file mode 100644 index 0000000000..aeabcca039 --- /dev/null +++ b/dists/nsis/scummvm.nsi @@ -0,0 +1,351 @@ +# 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. + +#!define _DEBUG + +Name ScummVM + +# Included files +!include MUI2.nsh + +######################################################################################### +# Command line options +######################################################################################### + +#!define top_srcdir "" +#!define build_dir "" +#!define text_dir "" +#!define ARCH "" ;(optional, defaults to win32) + +# Check parameters +!ifndef top_srcdir + !error "Top source folder has not been passed to command line!" +!endif + +!ifndef build_dir + !error "Build folder has not been passed to command line (this folder should contain the executable and linked DLLs)!" +!endif + +!ifndef text_dir + !error "Text folder has not been passed to command line (this folder should contain all the text files used by the installer)!" +!endif + +!ifndef ARCH + !warning "ARCH has not been defined, defaulting to 'win32'" + !define ARCH "win32" +!endif + +######################################################################################### +# Folders +######################################################################################### +!define engine_data "${top_srcdir}\dists\engine-data" +!define theme_data "${top_srcdir}\gui\themes" + +######################################################################################### +# General Symbol Definitions +######################################################################################### +!define REGKEY "Software\$(^Name)\$(^Name)" +!define VERSION "1.4.0git" +!define COMPANY "ScummVM Team" +!define URL "http://scummvm.org/" +!define DESCRIPTION "ScummVM Installer. Look! A three headed monkey (TM)!" +!define COPYRIGHT "Copyright © 2001-2011 The ScummVM Team" + +######################################################################################### +# Installer configuration +######################################################################################### +OutFile ${build_dir}\scummvm-${VERSION}-${ARCH}.exe +InstallDir $PROGRAMFILES\ScummVM ; Default installation folder +InstallDirRegKey HKCU "Software\ScummVM\ScummVM" "InstallPath" ; Get installation folder from registry if available + ; The application name needs to be refered directly instead of through ${REGKEY} + ; because lang strings aren't initialized at the point InstallDirRegKey is called + +CRCCheck on +XPStyle on +#TargetMinimalOS 5.0 ; Minimal version of windows for installer: Windows 2000 or more recent + ; (will build unicode installer with NSIS 2.50+) + +VIProductVersion 1.4.0.0 +VIAddVersionKey ProductName $(^Name) +VIAddVersionKey ProductVersion "${VERSION}" +VIAddVersionKey CompanyName "${COMPANY}" +VIAddVersionKey CompanyWebsite "${URL}" +VIAddVersionKey FileVersion "${VERSION}" +VIAddVersionKey FileDescription "${DESCRIPTION}" +VIAddVersionKey LegalCopyright "${COPYRIGHT}" + +BrandingText "$(^Name) ${VERSION}" ; Change branding text on the installer to show our name and version instead of NSIS's + +# Show Details when installing/uninstalling files +ShowInstDetails show +ShowUninstDetails show + +!ifdef _DEBUG + SetCompress off ; for debugging the installer, lzma takes forever + RequestExecutionLevel user +!else + SetCompressor /FINAL /SOLID lzma + SetCompressorDictSize 64 + RequestExecutionLevel admin ; for installation into program files folders +!endif + +######################################################################################### +# MUI Symbol Definitions +######################################################################################### +!define MUI_WELCOMEFINISHPAGE_BITMAP "graphics\left.bmp" +!define MUI_ICON "graphics\scummvm-install.ico" +!define MUI_UNICON "graphics\scummvm-install.ico" + +#Start menu +!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKCU +!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} +!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup +!define MUI_STARTMENUPAGE_DEFAULTFOLDER $(^Name) + +# Finish page +!define MUI_FINISHPAGE_RUN "$INSTDIR\scummvm.exe" +!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\README.txt" +!define MUI_FINISHPAGE_RUN_NOTCHECKED +!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED + +!define MUI_LICENSEPAGE_RADIOBUTTONS + +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_UNFINISHPAGE_NOAUTOCLOSE + +######################################################################################### +# Installer pages +######################################################################################### +# Variables +Var StartMenuGroup + +;Remember the installer language +!define MUI_LANGDLL_REGISTRY_ROOT HKCU +!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY} +!define MUI_LANGDLL_REGISTRY_VALUENAME "InstallerLanguage" + +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE ${top_srcdir}\COPYING +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +# Installer languages +!insertmacro MUI_LANGUAGE "English" ;first language is the default language + +!ifndef _DEBUG ; Skip other languages when building debug builds +;!insertmacro MUI_LANGUAGE "Afrikaans" +;!insertmacro MUI_LANGUAGE "Albanian" +;!insertmacro MUI_LANGUAGE "Arabic" +;!insertmacro MUI_LANGUAGE "Belarusian" +;!insertmacro MUI_LANGUAGE "Bosnian" +;!insertmacro MUI_LANGUAGE "Breton" +;!insertmacro MUI_LANGUAGE "Bulgarian" +!insertmacro MUI_LANGUAGE "Catalan" +;!insertmacro MUI_LANGUAGE "Croatian" +!insertmacro MUI_LANGUAGE "Czech" +!insertmacro MUI_LANGUAGE "Danish" +;!insertmacro MUI_LANGUAGE "Dutch" +;!insertmacro MUI_LANGUAGE "Esperanto" +;!insertmacro MUI_LANGUAGE "Estonian" +;!insertmacro MUI_LANGUAGE "Farsi" +;!insertmacro MUI_LANGUAGE "Finnish" +!insertmacro MUI_LANGUAGE "French" +;!insertmacro MUI_LANGUAGE "Galician" +!insertmacro MUI_LANGUAGE "German" +;!insertmacro MUI_LANGUAGE "Greek" +;!insertmacro MUI_LANGUAGE "Hebrew" +!insertmacro MUI_LANGUAGE "Hungarian" +;!insertmacro MUI_LANGUAGE "Icelandic" +;!insertmacro MUI_LANGUAGE "Indonesian" +;!insertmacro MUI_LANGUAGE "Irish" +!insertmacro MUI_LANGUAGE "Italian" +;!insertmacro MUI_LANGUAGE "Japanese" +;!insertmacro MUI_LANGUAGE "Korean" +;!insertmacro MUI_LANGUAGE "Kurdish" +;!insertmacro MUI_LANGUAGE "Latvian" +;!insertmacro MUI_LANGUAGE "Lithuanian" +;!insertmacro MUI_LANGUAGE "Luxembourgish" +;!insertmacro MUI_LANGUAGE "Macedonian" +;!insertmacro MUI_LANGUAGE "Malay" +;!insertmacro MUI_LANGUAGE "Mongolian" +!insertmacro MUI_LANGUAGE "Norwegian" +!insertmacro MUI_LANGUAGE "NorwegianNynorsk" +!insertmacro MUI_LANGUAGE "Polish" +;!insertmacro MUI_LANGUAGE "Portuguese" +!insertmacro MUI_LANGUAGE "PortugueseBR" +;!insertmacro MUI_LANGUAGE "Romanian" +!insertmacro MUI_LANGUAGE "Russian" +;!insertmacro MUI_LANGUAGE "Serbian" +;!insertmacro MUI_LANGUAGE "SerbianLatin" +;!insertmacro MUI_LANGUAGE "SimpChinese" +;!insertmacro MUI_LANGUAGE "Slovak" +;!insertmacro MUI_LANGUAGE "Slovenian" +!insertmacro MUI_LANGUAGE "Spanish" +;!insertmacro MUI_LANGUAGE "SpanishInternational" +!insertmacro MUI_LANGUAGE "Swedish" +;!insertmacro MUI_LANGUAGE "Thai" +;!insertmacro MUI_LANGUAGE "TradChinese" +;!insertmacro MUI_LANGUAGE "Turkish" +!insertmacro MUI_LANGUAGE "Ukrainian" +;!insertmacro MUI_LANGUAGE "Uzbek" +!endif + +;Reserve Files (will make sure the file will be stored first in the data block +; making the installer start faster when compressing in solid mode) +!insertmacro MUI_RESERVEFILE_LANGDLL + +######################################################################################### +# Installer sections +######################################################################################### +Section "ScummVM" SecMain + SetOutPath $INSTDIR + SetOverwrite on + + # Text files + File /oname=AUTHORS.txt "${text_dir}\AUTHORS" + File /oname=COPYING.LGPL.txt "${text_dir}\COPYING.LGPL" + File /oname=COPYING.txt "${text_dir}\COPYING" + File /oname=COPYRIGHT.txt "${text_dir}\COPYRIGHT" + File /oname=NEWS.txt "${text_dir}\NEWS" + File /oname=README.txt "${text_dir}\README" + File /oname=README-SDL.txt "${build_dir}\README-SDL" + + # Engine data + File "${engine_data}\drascula.dat" + File "${engine_data}\hugo.dat" + File "${engine_data}\kyra.dat" + File "${engine_data}\lure.dat" + File "${engine_data}\m4.dat" + File "${engine_data}\queen.tbl" + File "${engine_data}\sky.cpt" + File "${engine_data}\teenagent.dat" + File "${engine_data}\toon.dat" + + File "${top_srcdir}\dists\pred.dic" + + # Themes + File "${theme_data}\scummclassic.zip" + File "${theme_data}\scummmodern.zip" + File "${theme_data}\translations.dat" + + # Main exe and dlls + File "${build_dir}\scummvm.exe" + File "${build_dir}\SDL.dll" + + WriteRegStr HKCU "${REGKEY}" InstallPath "$INSTDIR" ; Store installation folder +SectionEnd + +# Write Start menu entries and uninstaller +Section -post SecMainPost + SetOutPath $INSTDIR + WriteUninstaller $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + SetShellVarContext all ; Create shortcuts in the all-users folder + CreateDirectory "$SMPROGRAMS\$StartMenuGroup" + CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\$(^Name).exe "" "$INSTDIR\$(^Name).exe" 0 ; Create shortcut with icon + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Readme.lnk" $INSTDIR\README.txt + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_END + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" InstallLocation $INSTDIR + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 +SectionEnd + +# Installer functions +Function .onInit + !insertmacro MUI_LANGDLL_DISPLAY + +!ifdef _DEBUG && NSIS_CONFIG_LOG + LogSet on ; Will write a log file to the install folder (when using the special NSIS logging build) +!endif +FunctionEnd + +######################################################################################### +# Uninstaller sections +######################################################################################### +Section -un.Main SecUninstall + Delete /REBOOTOK $INSTDIR\AUTHORS.txt + Delete /REBOOTOK $INSTDIR\COPYING.txt + Delete /REBOOTOK $INSTDIR\COPYING.LGPL.txt + Delete /REBOOTOK $INSTDIR\COPYRIGHT.txt + Delete /REBOOTOK $INSTDIR\NEWS.txt + Delete /REBOOTOK $INSTDIR\README.txt + Delete /REBOOTOK $INSTDIR\README-SDL.txt + + Delete /REBOOTOK $INSTDIR\drascula.dat + Delete /REBOOTOK $INSTDIR\hugo.dat + Delete /REBOOTOK $INSTDIR\kyra.dat + Delete /REBOOTOK $INSTDIR\lure.dat + Delete /REBOOTOK $INSTDIR\m4.dat + Delete /REBOOTOK $INSTDIR\queen.tbl + Delete /REBOOTOK $INSTDIR\sky.cpt + Delete /REBOOTOK $INSTDIR\teenagent.dat + Delete /REBOOTOK $INSTDIR\toon.dat + + Delete /REBOOTOK $INSTDIR\pred.dic + + Delete /REBOOTOK $INSTDIR\scummclassic.zip + Delete /REBOOTOK $INSTDIR\scummmodern.zip + Delete /REBOOTOK $INSTDIR\translations.dat + + Delete /REBOOTOK $INSTDIR\scummvm.exe + Delete /REBOOTOK $INSTDIR\SDL.dll +SectionEnd + +Section -un.post SecUninstallPost + # Remove start menu entries + SetShellVarContext all + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Readme.lnk" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" + RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup + + Delete /REBOOTOK $INSTDIR\uninstall.exe + + DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" + DeleteRegValue HKCU "${REGKEY}" StartMenuGroup + DeleteRegValue HKCU "${REGKEY}" InstallPath + DeleteRegValue HKCU "${REGKEY}" InstallerLanguage + DeleteRegKey /IfEmpty HKCU "${REGKEY}" + + RmDir $INSTDIR ; will only remove if empty (pass /r flag for recursive behavior) + Push $R0 + StrCpy $R0 $StartMenuGroup 1 + StrCmp $R0 ">" no_smgroup +no_smgroup: + Pop $R0 +SectionEnd + +# Uninstaller functions +Function un.onInit + !insertmacro MUI_UNGETLANGUAGE + ReadRegStr $INSTDIR HKCU "${REGKEY}" InstallPath + !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup +FunctionEnd diff --git a/dists/nsis/scummvm.nsi.in b/dists/nsis/scummvm.nsi.in new file mode 100644 index 0000000000..766a20633f --- /dev/null +++ b/dists/nsis/scummvm.nsi.in @@ -0,0 +1,351 @@ +# 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. + +#!define _DEBUG + +Name ScummVM + +# Included files +!include MUI2.nsh + +######################################################################################### +# Command line options +######################################################################################### + +#!define top_srcdir "" +#!define build_dir "" +#!define text_dir "" +#!define ARCH "" ;(optional, defaults to win32) + +# Check parameters +!ifndef top_srcdir + !error "Top source folder has not been passed to command line!" +!endif + +!ifndef build_dir + !error "Build folder has not been passed to command line (this folder should contain the executable and linked DLLs)!" +!endif + +!ifndef text_dir + !error "Text folder has not been passed to command line (this folder should contain all the text files used by the installer)!" +!endif + +!ifndef ARCH + !warning "ARCH has not been defined, defaulting to 'win32'" + !define ARCH "win32" +!endif + +######################################################################################### +# Folders +######################################################################################### +!define engine_data "${top_srcdir}\dists\engine-data" +!define theme_data "${top_srcdir}\gui\themes" + +######################################################################################### +# General Symbol Definitions +######################################################################################### +!define REGKEY "Software\$(^Name)\$(^Name)" +!define VERSION "@VERSION@" +!define COMPANY "ScummVM Team" +!define URL "http://scummvm.org/" +!define DESCRIPTION "ScummVM Installer. Look! A three headed monkey (TM)!" +!define COPYRIGHT "Copyright © 2001-2011 The ScummVM Team" + +######################################################################################### +# Installer configuration +######################################################################################### +OutFile ${build_dir}\scummvm-${VERSION}-${ARCH}.exe +InstallDir $PROGRAMFILES\ScummVM ; Default installation folder +InstallDirRegKey HKCU "Software\ScummVM\ScummVM" "InstallPath" ; Get installation folder from registry if available + ; The application name needs to be refered directly instead of through ${REGKEY} + ; because lang strings aren't initialized at the point InstallDirRegKey is called + +CRCCheck on +XPStyle on +#TargetMinimalOS 5.0 ; Minimal version of windows for installer: Windows 2000 or more recent + ; (will build unicode installer with NSIS 2.50+) + +VIProductVersion @VER_MAJOR@.@VER_MINOR@.@VER_PATCH@.0 +VIAddVersionKey ProductName $(^Name) +VIAddVersionKey ProductVersion "${VERSION}" +VIAddVersionKey CompanyName "${COMPANY}" +VIAddVersionKey CompanyWebsite "${URL}" +VIAddVersionKey FileVersion "${VERSION}" +VIAddVersionKey FileDescription "${DESCRIPTION}" +VIAddVersionKey LegalCopyright "${COPYRIGHT}" + +BrandingText "$(^Name) ${VERSION}" ; Change branding text on the installer to show our name and version instead of NSIS's + +# Show Details when installing/uninstalling files +ShowInstDetails show +ShowUninstDetails show + +!ifdef _DEBUG + SetCompress off ; for debugging the installer, lzma takes forever + RequestExecutionLevel user +!else + SetCompressor /FINAL /SOLID lzma + SetCompressorDictSize 64 + RequestExecutionLevel admin ; for installation into program files folders +!endif + +######################################################################################### +# MUI Symbol Definitions +######################################################################################### +!define MUI_WELCOMEFINISHPAGE_BITMAP "graphics\left.bmp" +!define MUI_ICON "graphics\scummvm-install.ico" +!define MUI_UNICON "graphics\scummvm-install.ico" + +#Start menu +!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKCU +!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} +!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup +!define MUI_STARTMENUPAGE_DEFAULTFOLDER $(^Name) + +# Finish page +!define MUI_FINISHPAGE_RUN "$INSTDIR\scummvm.exe" +!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\README.txt" +!define MUI_FINISHPAGE_RUN_NOTCHECKED +!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED + +!define MUI_LICENSEPAGE_RADIOBUTTONS + +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_UNFINISHPAGE_NOAUTOCLOSE + +######################################################################################### +# Installer pages +######################################################################################### +# Variables +Var StartMenuGroup + +;Remember the installer language +!define MUI_LANGDLL_REGISTRY_ROOT HKCU +!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY} +!define MUI_LANGDLL_REGISTRY_VALUENAME "InstallerLanguage" + +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE ${top_srcdir}\COPYING +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +# Installer languages +!insertmacro MUI_LANGUAGE "English" ;first language is the default language + +!ifndef _DEBUG ; Skip other languages when building debug builds +;!insertmacro MUI_LANGUAGE "Afrikaans" +;!insertmacro MUI_LANGUAGE "Albanian" +;!insertmacro MUI_LANGUAGE "Arabic" +;!insertmacro MUI_LANGUAGE "Belarusian" +;!insertmacro MUI_LANGUAGE "Bosnian" +;!insertmacro MUI_LANGUAGE "Breton" +;!insertmacro MUI_LANGUAGE "Bulgarian" +!insertmacro MUI_LANGUAGE "Catalan" +;!insertmacro MUI_LANGUAGE "Croatian" +!insertmacro MUI_LANGUAGE "Czech" +!insertmacro MUI_LANGUAGE "Danish" +;!insertmacro MUI_LANGUAGE "Dutch" +;!insertmacro MUI_LANGUAGE "Esperanto" +;!insertmacro MUI_LANGUAGE "Estonian" +;!insertmacro MUI_LANGUAGE "Farsi" +;!insertmacro MUI_LANGUAGE "Finnish" +!insertmacro MUI_LANGUAGE "French" +;!insertmacro MUI_LANGUAGE "Galician" +!insertmacro MUI_LANGUAGE "German" +;!insertmacro MUI_LANGUAGE "Greek" +;!insertmacro MUI_LANGUAGE "Hebrew" +!insertmacro MUI_LANGUAGE "Hungarian" +;!insertmacro MUI_LANGUAGE "Icelandic" +;!insertmacro MUI_LANGUAGE "Indonesian" +;!insertmacro MUI_LANGUAGE "Irish" +!insertmacro MUI_LANGUAGE "Italian" +;!insertmacro MUI_LANGUAGE "Japanese" +;!insertmacro MUI_LANGUAGE "Korean" +;!insertmacro MUI_LANGUAGE "Kurdish" +;!insertmacro MUI_LANGUAGE "Latvian" +;!insertmacro MUI_LANGUAGE "Lithuanian" +;!insertmacro MUI_LANGUAGE "Luxembourgish" +;!insertmacro MUI_LANGUAGE "Macedonian" +;!insertmacro MUI_LANGUAGE "Malay" +;!insertmacro MUI_LANGUAGE "Mongolian" +!insertmacro MUI_LANGUAGE "Norwegian" +!insertmacro MUI_LANGUAGE "NorwegianNynorsk" +!insertmacro MUI_LANGUAGE "Polish" +;!insertmacro MUI_LANGUAGE "Portuguese" +!insertmacro MUI_LANGUAGE "PortugueseBR" +;!insertmacro MUI_LANGUAGE "Romanian" +!insertmacro MUI_LANGUAGE "Russian" +;!insertmacro MUI_LANGUAGE "Serbian" +;!insertmacro MUI_LANGUAGE "SerbianLatin" +;!insertmacro MUI_LANGUAGE "SimpChinese" +;!insertmacro MUI_LANGUAGE "Slovak" +;!insertmacro MUI_LANGUAGE "Slovenian" +!insertmacro MUI_LANGUAGE "Spanish" +;!insertmacro MUI_LANGUAGE "SpanishInternational" +!insertmacro MUI_LANGUAGE "Swedish" +;!insertmacro MUI_LANGUAGE "Thai" +;!insertmacro MUI_LANGUAGE "TradChinese" +;!insertmacro MUI_LANGUAGE "Turkish" +!insertmacro MUI_LANGUAGE "Ukrainian" +;!insertmacro MUI_LANGUAGE "Uzbek" +!endif + +;Reserve Files (will make sure the file will be stored first in the data block +; making the installer start faster when compressing in solid mode) +!insertmacro MUI_RESERVEFILE_LANGDLL + +######################################################################################### +# Installer sections +######################################################################################### +Section "ScummVM" SecMain + SetOutPath $INSTDIR + SetOverwrite on + + # Text files + File /oname=AUTHORS.txt "${text_dir}\AUTHORS" + File /oname=COPYING.LGPL.txt "${text_dir}\COPYING.LGPL" + File /oname=COPYING.txt "${text_dir}\COPYING" + File /oname=COPYRIGHT.txt "${text_dir}\COPYRIGHT" + File /oname=NEWS.txt "${text_dir}\NEWS" + File /oname=README.txt "${text_dir}\README" + File /oname=README-SDL.txt "${build_dir}\README-SDL" + + # Engine data + File "${engine_data}\drascula.dat" + File "${engine_data}\hugo.dat" + File "${engine_data}\kyra.dat" + File "${engine_data}\lure.dat" + File "${engine_data}\m4.dat" + File "${engine_data}\queen.tbl" + File "${engine_data}\sky.cpt" + File "${engine_data}\teenagent.dat" + File "${engine_data}\toon.dat" + + File "${top_srcdir}\dists\pred.dic" + + # Themes + File "${theme_data}\scummclassic.zip" + File "${theme_data}\scummmodern.zip" + File "${theme_data}\translations.dat" + + # Main exe and dlls + File "${build_dir}\scummvm.exe" + File "${build_dir}\SDL.dll" + + WriteRegStr HKCU "${REGKEY}" InstallPath "$INSTDIR" ; Store installation folder +SectionEnd + +# Write Start menu entries and uninstaller +Section -post SecMainPost + SetOutPath $INSTDIR + WriteUninstaller $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + SetShellVarContext all ; Create shortcuts in the all-users folder + CreateDirectory "$SMPROGRAMS\$StartMenuGroup" + CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\$(^Name).exe "" "$INSTDIR\$(^Name).exe" 0 ; Create shortcut with icon + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Readme.lnk" $INSTDIR\README.txt + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_END + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" InstallLocation $INSTDIR + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 +SectionEnd + +# Installer functions +Function .onInit + !insertmacro MUI_LANGDLL_DISPLAY + +!ifdef _DEBUG && NSIS_CONFIG_LOG + LogSet on ; Will write a log file to the install folder (when using the special NSIS logging build) +!endif +FunctionEnd + +######################################################################################### +# Uninstaller sections +######################################################################################### +Section -un.Main SecUninstall + Delete /REBOOTOK $INSTDIR\AUTHORS.txt + Delete /REBOOTOK $INSTDIR\COPYING.txt + Delete /REBOOTOK $INSTDIR\COPYING.LGPL.txt + Delete /REBOOTOK $INSTDIR\COPYRIGHT.txt + Delete /REBOOTOK $INSTDIR\NEWS.txt + Delete /REBOOTOK $INSTDIR\README.txt + Delete /REBOOTOK $INSTDIR\README-SDL.txt + + Delete /REBOOTOK $INSTDIR\drascula.dat + Delete /REBOOTOK $INSTDIR\hugo.dat + Delete /REBOOTOK $INSTDIR\kyra.dat + Delete /REBOOTOK $INSTDIR\lure.dat + Delete /REBOOTOK $INSTDIR\m4.dat + Delete /REBOOTOK $INSTDIR\queen.tbl + Delete /REBOOTOK $INSTDIR\sky.cpt + Delete /REBOOTOK $INSTDIR\teenagent.dat + Delete /REBOOTOK $INSTDIR\toon.dat + + Delete /REBOOTOK $INSTDIR\pred.dic + + Delete /REBOOTOK $INSTDIR\scummclassic.zip + Delete /REBOOTOK $INSTDIR\scummmodern.zip + Delete /REBOOTOK $INSTDIR\translations.dat + + Delete /REBOOTOK $INSTDIR\scummvm.exe + Delete /REBOOTOK $INSTDIR\SDL.dll +SectionEnd + +Section -un.post SecUninstallPost + # Remove start menu entries + SetShellVarContext all + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Readme.lnk" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" + RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup + + Delete /REBOOTOK $INSTDIR\uninstall.exe + + DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" + DeleteRegValue HKCU "${REGKEY}" StartMenuGroup + DeleteRegValue HKCU "${REGKEY}" InstallPath + DeleteRegValue HKCU "${REGKEY}" InstallerLanguage + DeleteRegKey /IfEmpty HKCU "${REGKEY}" + + RmDir $INSTDIR ; will only remove if empty (pass /r flag for recursive behavior) + Push $R0 + StrCpy $R0 $StartMenuGroup 1 + StrCmp $R0 ">" no_smgroup +no_smgroup: + Pop $R0 +SectionEnd + +# Uninstaller functions +Function un.onInit + !insertmacro MUI_UNGETLANGUAGE + ReadRegStr $INSTDIR HKCU "${REGKEY}" InstallPath + !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup +FunctionEnd diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp index 78fc0ab3c1..aa2743b5ed 100644 --- a/engines/gob/dataio.cpp +++ b/engines/gob/dataio.cpp @@ -26,6 +26,7 @@ #include "common/endian.h" #include "common/types.h" #include "common/memstream.h" +#include "common/substream.h" #include "gob/gob.h" #include "gob/dataio.h" @@ -345,9 +346,8 @@ Common::SeekableReadStream *DataIO::getFile(File &file) { if (!file.archive->file.seek(file.offset)) return 0; - Common::SeekableReadStream *rawData = file.archive->file.readStream(file.size); - if (!rawData) - return 0; + Common::SeekableReadStream *rawData = + new Common::SafeSubReadStream(&file.archive->file, file.offset, file.offset + file.size); if (!file.packed) return rawData; diff --git a/engines/gob/save/savehandler.cpp b/engines/gob/save/savehandler.cpp index 8cb8274402..21102ae786 100644 --- a/engines/gob/save/savehandler.cpp +++ b/engines/gob/save/savehandler.cpp @@ -113,8 +113,8 @@ void SlotFileIndexed::buildIndex(byte *buffer, SavePartInfo &info, if (setLongest) { uint32 slot0Len; for (slot0Len = strlen((const char *) bufferStart); slot0Len < longest; slot0Len++) - buffer[slot0Len] = ' '; - buffer[slot0Len] = '\0'; + bufferStart[slot0Len] = ' '; + bufferStart[slot0Len] = '\0'; } } diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp index 66669e35c9..3327860913 100644 --- a/engines/mohawk/cursors.cpp +++ b/engines/mohawk/cursors.cpp @@ -29,9 +29,11 @@ #include "common/macresman.h" #include "common/system.h" +#include "common/textconsole.h" #include "common/winexe_ne.h" #include "common/winexe_pe.h" #include "graphics/cursorman.h" +#include "graphics/maccursor.h" #include "graphics/wincursor.h" #ifdef ENABLE_MYST @@ -41,11 +43,6 @@ namespace Mohawk { -static const byte s_bwPalette[] = { - 0x00, 0x00, 0x00, // Black - 0xFF, 0xFF, 0xFF // White -}; - void CursorManager::showCursor() { CursorMan.showMouse(true); } @@ -78,8 +75,13 @@ void CursorManager::setDefaultCursor() { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 }; + static const byte bwPalette[] = { + 0x00, 0x00, 0x00, // Black + 0xFF, 0xFF, 0xFF // White + }; + CursorMan.replaceCursor(defaultCursor, 12, 20, 0, 0, 0); - CursorMan.replaceCursorPalette(s_bwPalette, 1, 2); + CursorMan.replaceCursorPalette(bwPalette, 1, 2); } void CursorManager::setCursor(uint16 id) { @@ -87,35 +89,24 @@ void CursorManager::setCursor(uint16 id) { setDefaultCursor(); } -void CursorManager::setMacXorCursor(Common::SeekableReadStream *stream) { +void CursorManager::setMacCursor(Common::SeekableReadStream *stream) { assert(stream); - byte cursorBitmap[16 * 16]; + Graphics::MacCursor *macCursor = new Graphics::MacCursor(); - // Get black and white data - for (int i = 0; i < 32; i++) { - byte imageByte = stream->readByte(); - for (int b = 0; b < 8; b++) - cursorBitmap[i * 8 + b] = (imageByte & (0x80 >> b)) ? 1 : 2; - } + if (!macCursor->readFromStream(*stream)) + error("Could not parse Mac cursor"); - // Apply mask data - for (int i = 0; i < 32; i++) { - byte imageByte = stream->readByte(); - for (int b = 0; b < 8; b++) - if ((imageByte & (0x80 >> b)) == 0) - cursorBitmap[i * 8 + b] = 0; - } - - uint16 hotspotY = stream->readUint16BE(); - uint16 hotspotX = stream->readUint16BE(); + CursorMan.replaceCursor(macCursor->getSurface(), macCursor->getWidth(), macCursor->getHeight(), + macCursor->getHotspotX(), macCursor->getHotspotY(), macCursor->getKeyColor()); + CursorMan.replaceCursorPalette(macCursor->getPalette(), 0, 256); - CursorMan.replaceCursor(cursorBitmap, 16, 16, hotspotX, hotspotY, 0); - CursorMan.replaceCursorPalette(s_bwPalette, 1, 2); + delete macCursor; + delete stream; } void DefaultCursorManager::setCursor(uint16 id) { - setMacXorCursor(_vm->getResource(_tag, id)); + setMacCursor(_vm->getResource(_tag, id)); } #ifdef ENABLE_MYST @@ -223,26 +214,12 @@ void MacCursorManager::setCursor(uint16 id) { // Try a color cursor first Common::SeekableReadStream *stream = _resFork->getResource(MKTAG('c','r','s','r'), id); - if (stream) { - byte *cursor, *palette; - int width, height, hotspotX, hotspotY, keyColor, palSize; - - _resFork->convertCrsrCursor(stream, &cursor, width, height, hotspotX, hotspotY, keyColor, true, &palette, palSize); - - CursorMan.replaceCursor(cursor, width, height, hotspotX, hotspotY, keyColor); - CursorMan.replaceCursorPalette(palette, 0, palSize); - - delete[] cursor; - delete[] palette; - delete stream; - return; - } - - // Fall back to b&w cursors - stream = _resFork->getResource(MKTAG('C','U','R','S'), id); + // Fall back to monochrome cursors + if (!stream) + stream = _resFork->getResource(MKTAG('C','U','R','S'), id); if (stream) { - setMacXorCursor(stream); + setMacCursor(stream); delete stream; } else { setDefaultCursor(); @@ -265,7 +242,7 @@ LivingBooksCursorManager_v2::~LivingBooksCursorManager_v2() { void LivingBooksCursorManager_v2::setCursor(uint16 id) { if (_sysArchive && _sysArchive->hasResource(ID_TCUR, id)) { - setMacXorCursor(_sysArchive->getResource(ID_TCUR, id)); + setMacCursor(_sysArchive->getResource(ID_TCUR, id)); } else { // TODO: Handle generated cursors } diff --git a/engines/mohawk/cursors.h b/engines/mohawk/cursors.h index 1fb8b35714..ba9700c9f9 100644 --- a/engines/mohawk/cursors.h +++ b/engines/mohawk/cursors.h @@ -63,8 +63,8 @@ public: virtual bool hasSource() const { return false; } protected: - // Set a Mac XOR/AND map cursor to the screen - void setMacXorCursor(Common::SeekableReadStream *stream); + // Set a Mac CURS/crsr cursor to the screen + void setMacCursor(Common::SeekableReadStream *stream); }; // The default Mohawk cursor manager diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp index 3b95a5c955..d4d7dcfd4f 100644 --- a/engines/sci/graphics/cursor.cpp +++ b/engines/sci/graphics/cursor.cpp @@ -25,11 +25,11 @@ #include "common/config-manager.h" #include "common/events.h" -#include "common/macresman.h" #include "common/memstream.h" #include "common/system.h" #include "common/util.h" #include "graphics/cursorman.h" +#include "graphics/maccursor.h" #include "sci/sci.h" #include "sci/event.h" @@ -473,49 +473,19 @@ void GfxCursor::kernelSetMacCursor(GuiResourceId viewNum, int loopNum, int celNu assert(resource); - if (resource->size == 32 * 2 + 4) { - // Mac CURS cursor - // See http://developer.apple.com/legacy/mac/library/documentation/mac/QuickDraw/QuickDraw-402.html - // for more information. - byte *cursorBitmap = new byte[16 * 16]; - byte *data = resource->data; - - // Get B&W data - for (byte i = 0; i < 32; i++) { - byte imageByte = *data++; - for (byte b = 0; b < 8; b++) - cursorBitmap[i * 8 + b] = (byte)((imageByte & (0x80 >> b)) > 0 ? 1 : 2); - } - - // Apply mask data - for (byte i = 0; i < 32; i++) { - byte imageByte = *data++; - for (byte b = 0; b < 8; b++) - if ((imageByte & (0x80 >> b)) == 0) - cursorBitmap[i * 8 + b] = 0; // Doesn't matter, just is transparent - } - - uint16 hotspotY = READ_BE_UINT16(data); - uint16 hotspotX = READ_BE_UINT16(data + 2); - - static const byte cursorPalette[] = { 0x00, 0x00, 0x00, 0xff, 0xff, 0xff }; - - CursorMan.replaceCursor(cursorBitmap, 16, 16, hotspotX, hotspotY, 0); - CursorMan.replaceCursorPalette(cursorPalette, 1, 2); + Common::MemoryReadStream resStream(resource->data, resource->size); + Graphics::MacCursor *macCursor = new Graphics::MacCursor(); - delete[] cursorBitmap; - } else { - // Mac crsr cursor - byte *cursorBitmap, *palette; - int width, height, hotspotX, hotspotY, palSize, keycolor; - Common::MemoryReadStream resStream(resource->data, resource->size); - Common::MacResManager::convertCrsrCursor(&resStream, &cursorBitmap, width, height, hotspotX, hotspotY, keycolor, true, &palette, palSize); - CursorMan.replaceCursor(cursorBitmap, width, height, hotspotX, hotspotY, keycolor); - CursorMan.replaceCursorPalette(palette, 0, palSize); - delete[] cursorBitmap; - delete[] palette; + if (!macCursor->readFromStream(resStream)) { + warning("Failed to load Mac cursor %d", viewNum); + return; } + CursorMan.replaceCursor(macCursor->getSurface(), macCursor->getWidth(), macCursor->getHeight(), + macCursor->getHotspotX(), macCursor->getHotspotY(), macCursor->getKeyColor()); + CursorMan.replaceCursorPalette(macCursor->getPalette(), 0, 256); + + delete macCursor; kernelShow(); } diff --git a/engines/scumm/he/resource_he.cpp b/engines/scumm/he/resource_he.cpp index ecb094f29b..552c420755 100644 --- a/engines/scumm/he/resource_he.cpp +++ b/engines/scumm/he/resource_he.cpp @@ -32,6 +32,7 @@ #include "audio/decoders/wave.h" #include "graphics/cursorman.h" +#include "graphics/maccursor.h" #include "graphics/wincursor.h" #include "common/archive.h" @@ -172,11 +173,49 @@ bool MacResExtractor::extractResource(int id, CachedCursor *cc) { if (!dataStream) return false; - int keyColor; // HACK: key color is ignored - _resMgr->convertCrsrCursor(dataStream, &cc->bitmap, cc->width, cc->height, cc->hotspotX, cc->hotspotY, - keyColor, _vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette), - &cc->palette, cc->palSize); + // If we don't have a cursor palette, force monochrome cursors + bool forceMonochrome = !_vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette); + Graphics::MacCursor *macCursor = new Graphics::MacCursor(); + + if (!macCursor->readFromStream(*dataStream, forceMonochrome)) { + delete dataStream; + delete macCursor; + return false; + } + + cc->bitmap = new byte[macCursor->getWidth() * macCursor->getHeight()]; + cc->width = macCursor->getWidth(); + cc->height = macCursor->getHeight(); + cc->hotspotX = macCursor->getHotspotX(); + cc->hotspotY = macCursor->getHotspotY(); + + if (forceMonochrome) { + // Convert to the SCUMM palette + const byte *srcBitmap = macCursor->getSurface(); + + for (int i = 0; i < macCursor->getWidth() * macCursor->getHeight(); i++) { + if (srcBitmap[i] == macCursor->getKeyColor()) // Transparent + cc->bitmap[i] = 255; + else if (srcBitmap[i] == 0) // Black + cc->bitmap[i] = 253; + else // White + cc->bitmap[i] = 254; + } + } else { + // Copy data and palette + + // Sanity check. This code assumes that the key color is the same + assert(macCursor->getKeyColor() == 255); + + memcpy(cc->bitmap, macCursor->getSurface(), macCursor->getWidth() * macCursor->getHeight()); + + cc->palette = new byte[256 * 3]; + cc->palSize = 256; + memcpy(cc->palette, macCursor->getPalette(), 256 * 3); + } + + delete macCursor; delete dataStream; return true; } diff --git a/engines/sword2/music.cpp b/engines/sword2/music.cpp index 233d9369d2..ae6e2f1268 100644 --- a/engines/sword2/music.cpp +++ b/engines/sword2/music.cpp @@ -53,40 +53,6 @@ namespace Sword2 { -/** - * This class behaves like SeekableSubReadStream, except it remembers where the - * previous read() or seek() took it, so that it can continue from that point - * the next time. This is because we're frequently streaming two pieces of - * music from the same file. - */ -class SafeSubReadStream : public Common::SeekableSubReadStream { -protected: - uint32 _previousPos; -public: - SafeSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end); - virtual uint32 read(void *dataPtr, uint32 dataSize); - virtual bool seek(int32 offset, int whence = SEEK_SET); -}; - -SafeSubReadStream::SafeSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end) - : SeekableSubReadStream(parentStream, begin, end, DisposeAfterUse::NO) { - _previousPos = 0; -} - -uint32 SafeSubReadStream::read(void *dataPtr, uint32 dataSize) { - uint32 result; - SeekableSubReadStream::seek(_previousPos); - result = SeekableSubReadStream::read(dataPtr, dataSize); - _previousPos = pos(); - return result; -} - -bool SafeSubReadStream::seek(int32 offset, int whence) { - bool result = SeekableSubReadStream::seek(offset, whence); - _previousPos = pos(); - return result; -} - static Audio::AudioStream *makeCLUStream(Common::File *fp, int size); static Audio::AudioStream *makePSXCLUStream(Common::File *fp, int size); @@ -197,19 +163,19 @@ static Audio::AudioStream *getAudioStream(SoundFileHandle *fh, const char *base, return makeCLUStream(&fh->file, enc_len); #ifdef USE_MAD case kMP3Mode: { - SafeSubReadStream *tmp = new SafeSubReadStream(&fh->file, pos, pos + enc_len); + Common::SafeSubReadStream *tmp = new Common::SafeSubReadStream(&fh->file, pos, pos + enc_len); return Audio::makeMP3Stream(tmp, DisposeAfterUse::YES); } #endif #ifdef USE_VORBIS case kVorbisMode: { - SafeSubReadStream *tmp = new SafeSubReadStream(&fh->file, pos, pos + enc_len); + Common::SafeSubReadStream *tmp = new Common::SafeSubReadStream(&fh->file, pos, pos + enc_len); return Audio::makeVorbisStream(tmp, DisposeAfterUse::YES); } #endif #ifdef USE_FLAC case kFLACMode: { - SafeSubReadStream *tmp = new SafeSubReadStream(&fh->file, pos, pos + enc_len); + Common::SafeSubReadStream *tmp = new Common::SafeSubReadStream(&fh->file, pos, pos + enc_len); return Audio::makeFLACStream(tmp, DisposeAfterUse::YES); } #endif diff --git a/engines/sword25/gfx/image/pngloader.cpp b/engines/sword25/gfx/image/pngloader.cpp index f6c00b6968..d3c119b1a0 100644 --- a/engines/sword25/gfx/image/pngloader.cpp +++ b/engines/sword25/gfx/image/pngloader.cpp @@ -32,9 +32,6 @@ * */ -// Define to use ScummVM's PNG decoder, instead of libpng -#define USE_INTERNAL_PNG_DECODER - #ifndef USE_INTERNAL_PNG_DECODER // Disable symbol overrides so that we can use png.h #define FORBIDDEN_SYMBOL_ALLOW_ALL @@ -242,8 +239,8 @@ bool PNGLoader::decodeImage(const byte *fileDataPtr, uint fileSize, byte *&uncom return doDecodeImage(fileDataPtr + pngOffset, fileSize - pngOffset, uncompressedDataPtr, width, height, pitch); } -bool PNGLoader::doImageProperties(const byte *fileDataPtr, uint fileSize, int &width, int &height) { #ifndef USE_INTERNAL_PNG_DECODER +bool PNGLoader::doImageProperties(const byte *fileDataPtr, uint fileSize, int &width, int &height) { // Check for valid PNG signature if (!doIsCorrectImageFormat(fileDataPtr, fileSize)) return false; @@ -280,9 +277,7 @@ bool PNGLoader::doImageProperties(const byte *fileDataPtr, uint fileSize, int &w // Destroy libpng structures png_destroy_read_struct(&png_ptr, &info_ptr, NULL); -#else - // We don't need to read the image properties here... -#endif + return true; } @@ -292,5 +287,9 @@ bool PNGLoader::imageProperties(const byte *fileDataPtr, uint fileSize, int &wid return doImageProperties(fileDataPtr + pngOffset, fileSize - pngOffset, width, height); } +#else + // We don't need to read the image properties here... +#endif + } // End of namespace Sword25 diff --git a/engines/sword25/gfx/image/pngloader.h b/engines/sword25/gfx/image/pngloader.h index e0d68ff8b9..fea6ece0e9 100644 --- a/engines/sword25/gfx/image/pngloader.h +++ b/engines/sword25/gfx/image/pngloader.h @@ -40,6 +40,9 @@ namespace Sword25 { +// Define to use ScummVM's PNG decoder, instead of libpng +#define USE_INTERNAL_PNG_DECODER + /** * Class for loading PNG files, and PNG data embedded into savegames. * @@ -50,7 +53,9 @@ protected: PNGLoader() {} // Protected constructor to prevent instances static bool doDecodeImage(const byte *fileDataPtr, uint fileSize, byte *&uncompressedDataPtr, int &width, int &height, int &pitch); +#ifndef USE_INTERNAL_PNG_DECODER static bool doImageProperties(const byte *fileDataPtr, uint fileSize, int &width, int &height); +#endif public: @@ -72,6 +77,8 @@ public: byte *&pUncompressedData, int &width, int &height, int &pitch); + +#ifndef USE_INTERNAL_PNG_DECODER /** * Extract the properties of an image. * @param[in] fileDatePtr pointer to the image data @@ -86,6 +93,8 @@ public: static bool imageProperties(const byte *fileDatePtr, uint fileSize, int &width, int &height); +#endif + }; } // End of namespace Sword25 diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp index 806d9b27ad..132c516c12 100644 --- a/engines/sword25/gfx/image/renderedimage.cpp +++ b/engines/sword25/gfx/image/renderedimage.cpp @@ -36,6 +36,7 @@ // INCLUDES // ----------------------------------------------------------------------------- +#include "common/savefile.h" #include "sword25/package/packagemanager.h" #include "sword25/gfx/image/pngloader.h" #include "sword25/gfx/image/renderedimage.h" @@ -44,6 +45,14 @@ namespace Sword25 { +// Duplicated from kernel/persistenceservice.cpp +static Common::String generateSavegameFilename(uint slotID) { + char buffer[100]; + // NOTE: This is hardcoded to sword25 + snprintf(buffer, 100, "%s.%.3d", "sword25", slotID); + return Common::String(buffer); +} + // ----------------------------------------------------------------------------- // CONSTRUCTION / DESTRUCTION // ----------------------------------------------------------------------------- @@ -62,21 +71,36 @@ RenderedImage::RenderedImage(const Common::String &filename, bool &result) : // Load file byte *pFileData; uint fileSize; - pFileData = pPackage->getFile(filename, &fileSize); + + if (filename.hasPrefix("/saves")) { + // A savegame thumbnail + Common::SaveFileManager *sfm = g_system->getSavefileManager(); + int slotNum = atoi(filename.c_str() + filename.size() - 3); + Common::InSaveFile *file = sfm->openForLoading(generateSavegameFilename(slotNum)); + fileSize = file->size(); + pFileData = new byte[fileSize]; + file->read(pFileData, fileSize); + delete file; + } else { + pFileData = pPackage->getFile(filename, &fileSize); + } + if (!pFileData) { error("File \"%s\" could not be loaded.", filename.c_str()); return; } +#ifndef USE_INTERNAL_PNG_DECODER // Determine image properties - int pitch; if (!PNGLoader::imageProperties(pFileData, fileSize, _width, _height)) { error("Could not read image properties."); delete[] pFileData; return; } +#endif // Uncompress the image + int pitch; if (!PNGLoader::decodeImage(pFileData, fileSize, _data, _width, _height, pitch)) { error("Could not decode image."); delete[] pFileData; diff --git a/engines/sword25/gfx/image/swimage.cpp b/engines/sword25/gfx/image/swimage.cpp index 3b9b939eb3..0f3814eb54 100644 --- a/engines/sword25/gfx/image/swimage.cpp +++ b/engines/sword25/gfx/image/swimage.cpp @@ -56,14 +56,16 @@ SWImage::SWImage(const Common::String &filename, bool &result) : return; } +#ifndef USE_INTERNAL_PNG_DECODER // Determine image properties - int pitch; if (!PNGLoader::imageProperties(pFileData, fileSize, _width, _height)) { error("Could not read image properties."); return; } +#endif // Uncompress the image + int pitch; byte *pUncompressedData; if (!PNGLoader::decodeImage(pFileData, fileSize, pUncompressedData, _width, _height, pitch)) { error("Could not decode image."); diff --git a/engines/sword25/kernel/kernel_script.cpp b/engines/sword25/kernel/kernel_script.cpp index 458f6b2deb..43a144b2c6 100644 --- a/engines/sword25/kernel/kernel_script.cpp +++ b/engines/sword25/kernel/kernel_script.cpp @@ -42,45 +42,9 @@ namespace Sword25 { -static int disconnectService(lua_State *L) { - // This function apparently is not used by the game scripts - lua_pushboolean(L, true); - - return 1; -} - -static int getActiveServiceIdentifier(lua_State *L) { - // This function apparently is not used by the game scripts - lua_pushstring(L, "QUUX"); - - return 1; -} - -static int getSuperclassCount(lua_State *L) { - // This function is only used by a single function in system/kernel.lua which is never called. - lua_pushnumber(L, 0); - - return 1; -} - -static int getSuperclassIdentifier(lua_State *L) { - // This function is only used by a single function in system/kernel.lua which is never called. - lua_pushstring(L, "FOO"); - - return 1; -} - -static int getServiceCount(lua_State *L) { - // This function is only used by a single function in system/kernel.lua which is never called. - lua_pushnumber(L, 0); - - return 1; -} - -static int getServiceIdentifier(lua_State *L) { - // This function is only used by a single function in system/kernel.lua which is never called. - lua_pushstring(L, "BAR"); - +// Marks a function that should never be used +static int dummyFuncError(lua_State *L) { + error("Dummy function invoked by LUA"); return 1; } @@ -177,12 +141,12 @@ static int getUsedMemory(lua_State *L) { static const char *KERNEL_LIBRARY_NAME = "Kernel"; static const luaL_reg KERNEL_FUNCTIONS[] = { - {"DisconnectService", disconnectService}, - {"GetActiveServiceIdentifier", getActiveServiceIdentifier}, - {"GetSuperclassCount", getSuperclassCount}, - {"GetSuperclassIdentifier", getSuperclassIdentifier}, - {"GetServiceCount", getServiceCount}, - {"GetServiceIdentifier", getServiceIdentifier}, + {"DisconnectService", dummyFuncError}, + {"GetActiveServiceIdentifier", dummyFuncError}, + {"GetSuperclassCount", dummyFuncError}, + {"GetSuperclassIdentifier", dummyFuncError}, + {"GetServiceCount", dummyFuncError}, + {"GetServiceIdentifier", dummyFuncError}, {"GetMilliTicks", getMilliTicks}, {"GetTimer", getTimer}, {"StartService", startService}, @@ -241,20 +205,6 @@ static int setY(lua_State *L) { return 0; } -static int getClientX(lua_State *L) { - // This function apparently is not used by the game scripts - lua_pushnumber(L, 0); - - return 1; -} - -static int getClientY(lua_State *L) { - // This function apparently is not used by the game scripts - lua_pushnumber(L, 0); - - return 1; -} - static int getWidth(lua_State *L) { // This function apparently is not used by the game scripts lua_pushnumber(L, 800); @@ -332,20 +282,6 @@ static int closeWanted(lua_State *L) { return 1; } -static int waitForFocus(lua_State *L) { - // This function apparently is not used by the game scripts - lua_pushbooleancpp(L, true); - - return 1; -} - -static int hasFocus(lua_State *L) { - // This function apparently is not used by the game scripts - lua_pushbooleancpp(L, true); - - return 1; -} - static const char *WINDOW_LIBRARY_NAME = "Window"; static const luaL_reg WINDOW_FUNCTIONS[] = { @@ -355,8 +291,8 @@ static const luaL_reg WINDOW_FUNCTIONS[] = { {"SetX", setX}, {"GetY", getY}, {"SetY", setY}, - {"GetClientX", getClientX}, - {"GetClientY", getClientY}, + {"GetClientX", dummyFuncError}, + {"GetClientY", dummyFuncError}, {"GetWidth", getWidth}, {"GetHeight", getHeight}, {"SetWidth", setWidth}, @@ -365,8 +301,8 @@ static const luaL_reg WINDOW_FUNCTIONS[] = { {"SetTitle", setTitle}, {"ProcessMessages", processMessages}, {"CloseWanted", closeWanted}, - {"WaitForFocus", waitForFocus}, - {"HasFocus", hasFocus}, + {"WaitForFocus", dummyFuncError}, + {"HasFocus", dummyFuncError}, {0, 0} }; @@ -436,29 +372,6 @@ static int emptyCache(lua_State *L) { return 0; } -static int isLogCacheMiss(lua_State *L) { - Kernel *pKernel = Kernel::getInstance(); - assert(pKernel); - ResourceManager *pResource = pKernel->getResourceManager(); - assert(pResource); - - // This isn't used in any script - lua_pushbooleancpp(L, false); - - return 1; -} - -static int setLogCacheMiss(lua_State *L) { - Kernel *pKernel = Kernel::getInstance(); - assert(pKernel); - ResourceManager *pResource = pKernel->getResourceManager(); - assert(pResource); - - // This isn't used in any script - - return 0; -} - static int dumpLockedResources(lua_State *L) { Kernel *pKernel = Kernel::getInstance(); assert(pKernel); @@ -478,8 +391,8 @@ static const luaL_reg RESOURCE_FUNCTIONS[] = { {"GetMaxMemoryUsage", getMaxMemoryUsage}, {"SetMaxMemoryUsage", setMaxMemoryUsage}, {"EmptyCache", emptyCache}, - {"IsLogCacheMiss", isLogCacheMiss}, - {"SetLogCacheMiss", setLogCacheMiss}, + {"IsLogCacheMiss", dummyFuncError}, + {"SetLogCacheMiss", dummyFuncError}, {"DumpLockedResources", dumpLockedResources}, {0, 0} }; diff --git a/engines/sword25/package/packagemanager.cpp b/engines/sword25/package/packagemanager.cpp index 7c6343a18f..7a64fe2e29 100644 --- a/engines/sword25/package/packagemanager.cpp +++ b/engines/sword25/package/packagemanager.cpp @@ -141,29 +141,6 @@ bool PackageManager::loadDirectoryAsPackage(const Common::String &directoryName, } } -// Duplicated from kernel/persistenceservice.cpp -static Common::String generateSavegameFilename(uint slotID) { - char buffer[100]; - // NOTE: This is hardcoded to sword25 - snprintf(buffer, 100, "%s.%.3d", "sword25", slotID); - return Common::String(buffer); -} - -// Duplicated from kernel/persistenceservice.cpp -static Common::String loadString(Common::InSaveFile *in, uint maxSize = 999) { - Common::String result; - - char ch = (char)in->readByte(); - while (ch != '\0') { - result += ch; - if (result.size() >= maxSize) - break; - ch = (char)in->readByte(); - } - - return result; -} - byte *PackageManager::getFile(const Common::String &fileName, uint *fileSizePtr) { const Common::String B25S_EXTENSION(".b25s"); Common::SeekableReadStream *in; @@ -188,40 +165,6 @@ byte *PackageManager::getFile(const Common::String &fileName, uint *fileSizePtr) return buffer; } - if (fileName.hasPrefix("/saves")) { - // A savegame thumbnail - Common::SaveFileManager *sfm = g_system->getSavefileManager(); - int slotNum = atoi(fileName.c_str() + fileName.size() - 3); - Common::InSaveFile *file = sfm->openForLoading(generateSavegameFilename(slotNum)); - - if (file) { - loadString(file); // storedMarker - loadString(file); // storedVersionID - loadString(file); // gameDescription - int gameDataLength = atoi(loadString(file).c_str()); - loadString(file); // gamedataUncompressedLength - // Skip the savegame data - file->skip(gameDataLength); - - int thumbnailSize = file->size() - file->pos(); - - if (thumbnailSize <= 0) { - warning("Saved game at slot %d does not contain a thumbnail", slotNum); - delete file; - return 0; - } - - if (fileSizePtr) - *fileSizePtr = thumbnailSize; - - byte *thumbnail = new byte[thumbnailSize]; - file->read(thumbnail, thumbnailSize); - - delete file; - return thumbnail; - } - } - Common::ArchiveMemberPtr fileNode = getArchiveMember(normalizePath(fileName, _currentDirectory)); if (!fileNode) return 0; diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp index 86219a7908..28d6dbfb19 100644 --- a/engines/tsage/core.cpp +++ b/engines/tsage/core.cpp @@ -2622,6 +2622,12 @@ int Visage::getFrameCount() const { /*--------------------------------------------------------------------------*/ +Player::Player(): SceneObject() { + _canWalk = false; + _uiEnabled = false; + _field8C = 0; +} + void Player::postInit(SceneObjectList *OwnerList) { SceneObject::postInit(); diff --git a/engines/tsage/core.h b/engines/tsage/core.h index d1d3411e5a..a4a0ec208a 100644 --- a/engines/tsage/core.h +++ b/engines/tsage/core.h @@ -598,7 +598,7 @@ public: bool _uiEnabled; int _field8C; public: - Player() : SceneObject() {} + Player(); virtual Common::String getClassName() { return "Player"; } virtual void synchronize(Serializer &s); diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp index d5d63da76b..74e957580c 100644 --- a/engines/tsage/globals.cpp +++ b/engines/tsage/globals.cpp @@ -93,6 +93,8 @@ Globals::Globals() : Globals::~Globals() { _globals = NULL; + delete _inventory; + delete _game; } void Globals::reset() { diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp index fbc1e2a359..723e50d338 100644 --- a/engines/tsage/graphics.cpp +++ b/engines/tsage/graphics.cpp @@ -227,6 +227,7 @@ GfxSurface::GfxSurface() : _bounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) { _lockSurfaceCtr = 0; _customSurface = NULL; _screenSurfaceP = NULL; + _transColor = -1; } GfxSurface::GfxSurface(const GfxSurface &s) { @@ -259,6 +260,7 @@ void GfxSurface::create(int width, int height) { _screenSurface = false; _customSurface = new Graphics::Surface(); _customSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); + Common::set_to((byte *)_customSurface->pixels, (byte *)_customSurface->pixels + (width * height), 0); _bounds = Rect(0, 0, width, height); } diff --git a/engines/tsage/ringworld_logic.cpp b/engines/tsage/ringworld_logic.cpp index b22996e916..4321c53c47 100644 --- a/engines/tsage/ringworld_logic.cpp +++ b/engines/tsage/ringworld_logic.cpp @@ -396,18 +396,18 @@ void SpeakerPOR::setText(const Common::String &msg) { _object1.postInit(&_objectList); _object1.setVisage(7223); _object1.setStrip2(2); - _object1.setPosition(Common::Point(191, 166), 0); - _object1.animate(ANIM_MODE_7, 0, 0); + _object1.setPosition(Common::Point(191, 166)); + _object1.animate(ANIM_MODE_7, 0, NULL); _object2.postInit(&_objectList); _object2.setVisage(7223); - _object2.setPosition(Common::Point(159, 86), 0); - _object2.setAction(&_speakerAction, 0); + _object2.setPosition(Common::Point(159, 86)); + _object2.setAction(&_speakerAction, NULL); _object3.postInit(&_objectList); _object3.setVisage(7223); _object3.setStrip(3); - _object3.setPosition(Common::Point(119, 107), 0); + _object3.setPosition(Common::Point(119, 107)); _object3.fixPriority(199); _object3.setAction(&_action2); @@ -431,8 +431,8 @@ void SpeakerOR::setText(const Common::String &msg) { _object1.fixPriority(255); _object1.changeZoom(100); _object1._frame = 1; - _object1.setPosition(Common::Point(202, 147), 0); - _object1.animate(ANIM_MODE_7, 0, 0); + _object1.setPosition(Common::Point(202, 147)); + _object1.animate(ANIM_MODE_7, 0, NULL); _object2.postInit(&_objectList); _object2.setVisage(9431); @@ -440,8 +440,8 @@ void SpeakerOR::setText(const Common::String &msg) { _object2.fixPriority(255); _object2.setZoom(100); _object2._frame = 1; - _object2.setPosition(Common::Point(199, 85), 0); - _object2.setAction(&_speakerAction, 0); + _object2.setPosition(Common::Point(199, 85)); + _object2.setAction(&_speakerAction, NULL); Speaker::setText(msg); } @@ -518,7 +518,7 @@ SpeakerEText::SpeakerEText() { /*--------------------------------------------------------------------------*/ -SpeakerGR::SpeakerGR() { +SpeakerGR::SpeakerGR() : AnimatedSpeaker() { _speakerName = "GR"; _newSceneNumber = 9220; _textWidth = 136; @@ -526,6 +526,19 @@ SpeakerGR::SpeakerGR() { _color1 = 14; } +void SpeakerGR::setText(const Common::String &msg) { + _object1.postInit(&_objectList); + _object1.setVisage(9221); + _object1.setStrip2(2); + _object1.fixPriority(255); + _object1.changeZoom(100); + _object1._frame = 1; + _object1.setPosition(Common::Point(101, 70)); + _object1.animate(ANIM_MODE_7, 0, NULL); + + Speaker::setText(msg); +} + /*--------------------------------------------------------------------------*/ SpeakerHText::SpeakerHText() { @@ -541,7 +554,7 @@ SpeakerSKText::SpeakerSKText() : ScreenSpeaker() { _speakerName = "SKTEXT"; _textWidth = 240; _textMode = ALIGN_CENTER; - _color1 = 5; + _color1 = 9; _hideObjects = false; } @@ -600,16 +613,16 @@ SpeakerSKL::SpeakerSKL() : AnimatedSpeaker() { _speakerName = "SKL"; _newSceneNumber = 7011; _textPos = Common::Point(10, 30); - _color1 = 10; + _color1 = 9; } void SpeakerSKL::setText(const Common::String &msg) { _object1.postInit(&_objectList); _object1.setVisage(7013); _object1.setStrip2(2); - _object1._frame = 1; _object1.fixPriority(255); _object1.changeZoom(100); + _object1._frame = 1; _object1.setPosition(Common::Point(203, 120)); _object1.animate(ANIM_MODE_7, 0, NULL); @@ -780,8 +793,8 @@ void SpeakerQU::setText(const Common::String &msg) { _object1.fixPriority(255); _object1.changeZoom(100); _object1._frame = 1; - _object1.setPosition(Common::Point(116, 120), 0); - _object1.animate(ANIM_MODE_7, 0, 0); + _object1.setPosition(Common::Point(116, 120)); + _object1.animate(ANIM_MODE_7, 0, NULL); _object2.postInit(&_objectList); _object2.setVisage(7021); @@ -789,8 +802,8 @@ void SpeakerQU::setText(const Common::String &msg) { _object2.fixPriority(255); _object2.changeZoom(100); _object2._frame = 1; - _object2.setPosition(Common::Point(111, 84), 0); - _object2.setAction(&_speakerAction, 0); + _object2.setPosition(Common::Point(111, 84)); + _object2.setAction(&_speakerAction, NULL); Speaker::setText(msg); } @@ -877,6 +890,7 @@ void SpeakerSAL::setText(const Common::String &msg) { _object2.setVisage(2853); _object2.setStrip2(1); _object2.fixPriority(255); + _object2.changeZoom(100); _object2._frame = 1; _object2.setPosition(Common::Point(170, 92)); _object2.setAction(&_speakerAction, NULL); @@ -980,7 +994,6 @@ void SpeakerCHFR::setText(const Common::String &msg) { /*--------------------------------------------------------------------------*/ SpeakerPL::SpeakerPL() { - // TODO: check initialization of object3 and action2 _speakerName = "PL"; _newSceneNumber = 4060; _textPos = Common::Point(160, 40); diff --git a/engines/tsage/ringworld_logic.h b/engines/tsage/ringworld_logic.h index d790631f2f..e84779e6ad 100644 --- a/engines/tsage/ringworld_logic.h +++ b/engines/tsage/ringworld_logic.h @@ -192,6 +192,7 @@ public: SpeakerGR(); virtual Common::String getClassName() { return "SpeakerGR"; } + virtual void setText(const Common::String &msg); }; class SpeakerHText : public ScreenSpeaker { diff --git a/engines/tsage/ringworld_scenes8.cpp b/engines/tsage/ringworld_scenes8.cpp index 487aaeea53..0969ba8a4e 100644 --- a/engines/tsage/ringworld_scenes8.cpp +++ b/engines/tsage/ringworld_scenes8.cpp @@ -349,8 +349,8 @@ void Scene7000::Action7::signal() { void Scene7000::SceneItem1::doAction(int action) { if (action == CURSOR_LOOK) SceneItem::display2(7000, 2); - - SceneItem::doAction(action); + else + SceneHotspot::doAction(action); } /*--------------------------------------------------------------------------*/ @@ -1602,7 +1602,7 @@ void Scene7600::postInit(SceneObjectList *OwnerList) { *--------------------------------------------------------------------------*/ void Scene7700::Action1::signal() { - SceneObject *fmtObj = (SceneObject *) _endHandler; + SceneObjectExt *fmtObj = (SceneObjectExt *) _endHandler; switch (_actionIndex++) { case 0: { PlayerMover *mover1 = new PlayerMover(); @@ -1612,7 +1612,7 @@ void Scene7700::Action1::signal() { } case 1: _globals->_player.checkAngle(fmtObj); - if (_globals->_player._field8C == 0) + if (fmtObj->_state == 0) fmtObj->animate(ANIM_MODE_5, this); else fmtObj->animate(ANIM_MODE_6, this); diff --git a/engines/tsage/ringworld_scenes8.h b/engines/tsage/ringworld_scenes8.h index a88a01b5a2..c40a43eba6 100644 --- a/engines/tsage/ringworld_scenes8.h +++ b/engines/tsage/ringworld_scenes8.h @@ -95,7 +95,7 @@ class Scene7000 : public Scene { }; /* Items */ - class SceneItem1 : public SceneItem { + class SceneItem1 : public SceneHotspot { public: virtual void doAction(int action); }; diff --git a/graphics/maccursor.cpp b/graphics/maccursor.cpp new file mode 100644 index 0000000000..e086e22fca --- /dev/null +++ b/graphics/maccursor.cpp @@ -0,0 +1,185 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "common/textconsole.h" + +#include "graphics/maccursor.h" + +namespace Graphics { + +MacCursor::MacCursor() { + _surface = 0; + memset(_palette, 0, 256 * 3); + + _hotspotX = 0; + _hotspotY = 0; +} + +MacCursor::~MacCursor() { + clear(); +} + +void MacCursor::clear() { + delete[] _surface; _surface = 0; + memset(_palette, 0, 256 * 3); +} + +bool MacCursor::readFromStream(Common::SeekableReadStream &stream, bool forceMonochrome) { + clear(); + + // Older Mac CURS monochrome cursors had a set size + // All crsr cursors are larger than this + if (stream.size() == 32 * 2 + 4) + return readFromCURS(stream); + + return readFromCRSR(stream, forceMonochrome); +} + +bool MacCursor::readFromCURS(Common::SeekableReadStream &stream) { + // Grab B/W icon data + _surface = new byte[16 * 16]; + for (int i = 0; i < 32; i++) { + byte imageByte = stream.readByte(); + for (int b = 0; b < 8; b++) + _surface[i * 8 + b] = (byte)((imageByte & (0x80 >> b)) > 0 ? 0 : 1); + } + + // Apply mask data + for (int i = 0; i < 32; i++) { + byte imageByte = stream.readByte(); + for (int b = 0; b < 8; b++) + if ((imageByte & (0x80 >> b)) == 0) + _surface[i * 8 + b] = 0xff; + } + + _hotspotY = stream.readUint16BE(); + _hotspotX = stream.readUint16BE(); + + // Setup a basic palette + _palette[1 * 3 + 0] = 0xff; + _palette[1 * 3 + 1] = 0xff; + _palette[1 * 3 + 2] = 0xff; + + return !stream.eos(); +} + +bool MacCursor::readFromCRSR(Common::SeekableReadStream &stream, bool forceMonochrome) { + stream.readUint16BE(); // type + stream.readUint32BE(); // offset to pixel map + stream.readUint32BE(); // offset to pixel data + stream.readUint32BE(); // expanded cursor data + stream.readUint16BE(); // expanded data depth + stream.readUint32BE(); // reserved + + // Read the B/W data first + if (!readFromCURS(stream)) + return false; + + // Use b/w cursor on backends which don't support cursor palettes + if (forceMonochrome) + return true; + + stream.readUint32BE(); // reserved + stream.readUint32BE(); // cursorID + + // Color version of cursor + stream.readUint32BE(); // baseAddr + + // Keep only lowbyte for now + stream.readByte(); + int iconRowBytes = stream.readByte(); + + if (!iconRowBytes) + return false; + + int iconBounds[4]; + iconBounds[0] = stream.readUint16BE(); + iconBounds[1] = stream.readUint16BE(); + iconBounds[2] = stream.readUint16BE(); + iconBounds[3] = stream.readUint16BE(); + + stream.readUint16BE(); // pmVersion + stream.readUint16BE(); // packType + stream.readUint32BE(); // packSize + + stream.readUint32BE(); // hRes + stream.readUint32BE(); // vRes + + stream.readUint16BE(); // pixelType + stream.readUint16BE(); // pixelSize + stream.readUint16BE(); // cmpCount + stream.readUint16BE(); // cmpSize + + stream.readUint32BE(); // planeByte + stream.readUint32BE(); // pmTable + stream.readUint32BE(); // reserved + + // Pixel data for cursor + int iconDataSize = iconRowBytes * (iconBounds[3] - iconBounds[1]); + byte *iconData = new byte[iconDataSize]; + + if (!iconData) + error("Cannot allocate Mac color cursor iconData"); + + stream.read(iconData, iconDataSize); + + // Color table + stream.readUint32BE(); // ctSeed + stream.readUint16BE(); // ctFlag + uint16 ctSize = stream.readUint16BE() + 1; + + // Read just high byte of 16-bit color + for (int c = 0; c < ctSize; c++) { + stream.readUint16BE(); + _palette[c * 3 + 0] = stream.readUint16BE() >> 8; + _palette[c * 3 + 1] = stream.readUint16BE() >> 8; + _palette[c * 3 + 2] = stream.readUint16BE() >> 8; + } + + int pixelsPerByte = (iconBounds[2] - iconBounds[0]) / iconRowBytes; + int bpp = 8 / pixelsPerByte; + + // build a mask to make sure the pixels are properly shifted out + int bitmask = 0; + for (int m = 0; m < bpp; m++) { + bitmask <<= 1; + bitmask |= 1; + } + + // Extract pixels from bytes + for (int j = 0; j < iconDataSize; j++) { + for (int b = 0; b < pixelsPerByte; b++) { + int idx = j * pixelsPerByte + (pixelsPerByte - 1 - b); + + if (_surface[idx] != 0xff) // if mask is not there + _surface[idx] = (byte)((iconData[j] >> (b * bpp)) & bitmask); + } + } + + delete[] iconData; + return stream.pos() == stream.size(); +} + +} // End of namespace Common diff --git a/graphics/maccursor.h b/graphics/maccursor.h new file mode 100644 index 0000000000..fac78d97a4 --- /dev/null +++ b/graphics/maccursor.h @@ -0,0 +1,83 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +/** + * @file + * Macintosh cursor decoding used in engines: + * - mohawk + * - sci + * - scumm + */ + +#include "common/stream.h" + +#ifndef GRAPHICS_MACCURSOR_H +#define GRAPHICS_MACCURSOR_H + +namespace Graphics { + +/** + * A Mac crsr or CURS cursor + * TODO: Think about making a base class with WinCursor + */ +class MacCursor { +public: + MacCursor(); + ~MacCursor(); + + /** Return the cursor's width. */ + uint16 getWidth() const { return 16; } + /** Return the cursor's height. */ + uint16 getHeight() const { return 16; } + /** Return the cursor's hotspot's x coordinate. */ + uint16 getHotspotX() const { return _hotspotX; } + /** Return the cursor's hotspot's y coordinate. */ + uint16 getHotspotY() const { return _hotspotY; } + /** Return the cursor's transparent key. */ + byte getKeyColor() const { return 0xFF; } + + const byte *getSurface() const { return _surface; } + const byte *getPalette() const { return _palette; } + + /** Read the cursor's data out of a stream. */ + bool readFromStream(Common::SeekableReadStream &stream, bool forceMonochrome = false); + +private: + bool readFromCURS(Common::SeekableReadStream &stream); + bool readFromCRSR(Common::SeekableReadStream &stream, bool forceMonochrome); + + byte *_surface; + byte _palette[256 * 3]; + + uint16 _hotspotX; ///< The cursor's hotspot's x coordinate. + uint16 _hotspotY; ///< The cursor's hotspot's y coordinate. + + /** Clear the cursor. */ + void clear(); +}; + +} // End of namespace Graphics + +#endif diff --git a/graphics/module.mk b/graphics/module.mk index cb3a07e691..59621dc525 100644 --- a/graphics/module.mk +++ b/graphics/module.mk @@ -14,6 +14,7 @@ MODULE_OBJS := \ iff.o \ imagedec.o \ jpeg.o \ + maccursor.o \ pict.o \ png.o \ primitives.o \ @@ -182,7 +182,20 @@ endif cp /usr/local/bin/SDL.dll $(WIN32PATH) cp $(srcdir)/icons/scummvm.ico $(WIN32PATH) cp $(srcdir)/dists/win32/ScummVM.iss $(WIN32PATH) - u2d $(WIN32PATH)/*.txt + unix2dos $(WIN32PATH)/*.txt + +# Special target to create a win32 installer +# (extensions for text files are removed, as they are read +# as-is by the setup script and renamed there) +win32setup: win32dist + mv $(WIN32PATH)/AUTHORS.txt $(WIN32PATH)/AUTHORS + mv $(WIN32PATH)/COPYING.txt $(WIN32PATH)/COPYING + mv $(WIN32PATH)/COPYING.LGPL.txt $(WIN32PATH)/COPYING.LGPL + mv $(WIN32PATH)/COPYRIGHT.txt $(WIN32PATH)/COPYRIGHT + mv $(WIN32PATH)/NEWS.txt $(WIN32PATH)/NEWS + mv $(WIN32PATH)/README.txt $(WIN32PATH)/README + mv $(WIN32PATH)/README-SDL.txt $(WIN32PATH)/README-SDL + makensis -V2 -Dtop_srcdir="../../$(srcdir)" -Dtext_dir="../../$(WIN32PATH)" -Dbuild_dir="../../$(WIN32PATH)" $(srcdir)/dists/nsis/scummvm.nsi # # AmigaOS specific |