mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2026-01-29 17:38:16 +03:00
Hello WWWWWWorld!
This commit is contained in:
33
.github/pull_request_template.md
vendored
Normal file
33
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
## The Basics
|
||||||
|
|
||||||
|
Thanks for making a pull request! Before making a pull request, we have some
|
||||||
|
things for you to read through first:
|
||||||
|
|
||||||
|
- We generally do not accept patches for formatting fixes, unless the formatting
|
||||||
|
fixes are part of a functional patch (for example, when fixing a bug in a
|
||||||
|
function you can fix up the lines surrounding it if needed).
|
||||||
|
- Patches that break compatibility with the original game data or save data will
|
||||||
|
not be accepted.
|
||||||
|
- New features and user interface changes will most likely not be accepted
|
||||||
|
unless they are for improving user accessibility.
|
||||||
|
- New platforms are acceptable if they use SDL + PhysicsFS and don't mess with
|
||||||
|
the game source too much.
|
||||||
|
- (No homebrew console targets, sorry! Maybe do the work in SDL instead?)
|
||||||
|
- Pull requests that do not fill out the Legal Stuff will be closed
|
||||||
|
automatically.
|
||||||
|
|
||||||
|
If you understand these notes, you can delete the text in this section. Pull
|
||||||
|
requests that still have this text will be closed automatically.
|
||||||
|
|
||||||
|
## Legal Stuff:
|
||||||
|
|
||||||
|
By submitting this pull request, I confirm that...
|
||||||
|
|
||||||
|
- [ ] My changes may be used in a future commercial release of VVVVVV (for
|
||||||
|
example, a 2.3 update on Steam for Windows/macOS/Linux)
|
||||||
|
- [ ] I will be credited in a `CONTRIBUTORS` file for all of said releases, but
|
||||||
|
will NOT be compensated for these changes
|
||||||
|
|
||||||
|
## Changes:
|
||||||
|
|
||||||
|
Describe your patch here!
|
||||||
17
LICENSE.md
Normal file
17
LICENSE.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
VVVVVV Source Code License v1.0
|
||||||
|
-------
|
||||||
|
Last updated on January 7th, 2020.
|
||||||
|
|
||||||
|
This repo contains the source code for VVVVVV, including all level content and text from the game. It does not, however, contain any of the icons, art, graphics or music for the game, which are still under a proprietary license. For personal use, you can find these assets for free in the [Make and Play Edition](http://distractionware.com/blog/category/vvvvvv-make-and-play/).
|
||||||
|
|
||||||
|
If you are interested in distributing work that falls outside the terms in the licence below, or if you are interested in distributing work that includes using any part of VVVVVV not included in this repo then please get in touch - we can discuss granting a licence for that on a case by case basis. The purpose of making the contents of this repo available is for others to learn from, to inspire new work, and to allow the creation of new tools and modifications for VVVVVV.
|
||||||
|
|
||||||
|
This software available from here is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any claim, damages or other liability arising from the use or in connection with this software. All materials in the repo are copyright of Terry Cavanagh © 2010-2020.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software and to alter it and redistribute it freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
- You may not alter or redistribute this software in any manner that is primarily intended for or directed toward commercial advantage or private monetary compensation. This includes, but is not limited to, selling altered or unaltered versions of this software, or including advertisements of any kind in altered or unaltered versions of this software.
|
||||||
|
- The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, you are required to include an acknowledgement in the product that this software is the copyright of Terry Cavanagh and is based on the VVVVVV source code.
|
||||||
|
- Altered source/binary versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||||
|
- You must not distribute any materials from the game which are not included in this repo unless approved by us in writing.
|
||||||
|
- This notice may not be removed or altered from any source/binary distribution.
|
||||||
22
README.md
Normal file
22
README.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
This is the source code to VVVVVV, version 2.0+.
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
VVVVVV's source code is made available under a custom license. See [LICENSE.md](LICENSE.md) for more details.
|
||||||
|
|
||||||
|
In general, if you're interested in creating something that falls outside the license terms, get in touch with Terry and we'll talk about it!
|
||||||
|
|
||||||
|
Authors
|
||||||
|
-------
|
||||||
|
- Created by [Terry Cavanagh](http://distractionware.com/)
|
||||||
|
- Room Names by [Bennett Foddy](http://www.foddy.net)
|
||||||
|
- Music by [Magnus Pålsson](http://souleye.madtracker.net/)
|
||||||
|
- Metal Soundtrack by [FamilyJules](http://familyjules7x.com/)
|
||||||
|
- 2.0 Update (C++ Port) by [Simon Roth](http://www.machinestudios.co.uk)
|
||||||
|
- 2.2 Update (SDL2/PhysicsFS/Steamworks port) by [Ethan Lee](http://www.flibitijibibo.com/)
|
||||||
|
- Beta Testing by Sam Kaplan and Pauli Kohberger
|
||||||
|
- Ending Picture by Pauli Kohberger
|
||||||
|
|
||||||
|
Versions
|
||||||
|
------------
|
||||||
|
There are two versions of the VVVVVV source code available - the [desktop version](https://github.com/TerryCavanagh/VVVVVV/tree/master/desktop_version) (based on the C++ port, and currently live on Steam), and the [mobile version](https://github.com/TerryCavanagh/VVVVVV/tree/master/mobile_version) (based on a fork of the original flash source code, and currently live on iOS and Android).
|
||||||
131
desktop_version/CMakeLists.txt
Normal file
131
desktop_version/CMakeLists.txt
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
# CMake File for VVVVVV
|
||||||
|
# Written by Ethan "flibitijibibo" Lee
|
||||||
|
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)
|
||||||
|
PROJECT(VVVVVV)
|
||||||
|
|
||||||
|
# Architecture Flags
|
||||||
|
IF(APPLE)
|
||||||
|
# Wow, Apple is a huge jerk these days huh?
|
||||||
|
SET(CMAKE_OSX_SYSROOT /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk)
|
||||||
|
SET(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)
|
||||||
|
LINK_DIRECTORIES(/usr/local/lib)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Compiler Flags
|
||||||
|
ADD_DEFINITIONS(-DPHYSFS_SUPPORTS_DEFAULT=0 -DPHYSFS_SUPPORTS_ZIP=1)
|
||||||
|
|
||||||
|
# Executable Suffix
|
||||||
|
IF(APPLE)
|
||||||
|
SET(CMAKE_EXECUTABLE_SUFFIX ".osx")
|
||||||
|
ELSEIF(WIN32)
|
||||||
|
# Nothing!
|
||||||
|
ELSEIF(CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||||
|
SET(CMAKE_EXECUTABLE_SUFFIX ".x86_64")
|
||||||
|
ELSE()
|
||||||
|
SET(CMAKE_EXECUTABLE_SUFFIX ".x86")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Include Directories
|
||||||
|
INCLUDE_DIRECTORIES(src tinyxml physfs lodepng)
|
||||||
|
|
||||||
|
# Source Lists
|
||||||
|
SET(VVV_SRC
|
||||||
|
src/BinaryBlob.cpp
|
||||||
|
src/BlockV.cpp
|
||||||
|
src/editor.cpp
|
||||||
|
src/Ent.cpp
|
||||||
|
src/Entity.cpp
|
||||||
|
src/FileSystemUtils.cpp
|
||||||
|
src/Finalclass.cpp
|
||||||
|
src/Game.cpp
|
||||||
|
src/Graphics.cpp
|
||||||
|
src/GraphicsResources.cpp
|
||||||
|
src/GraphicsUtil.cpp
|
||||||
|
src/Input.cpp
|
||||||
|
src/KeyPoll.cpp
|
||||||
|
src/Labclass.cpp
|
||||||
|
src/Logic.cpp
|
||||||
|
src/Map.cpp
|
||||||
|
src/Music.cpp
|
||||||
|
src/Otherlevel.cpp
|
||||||
|
src/preloader.cpp
|
||||||
|
src/Screen.cpp
|
||||||
|
src/Script.cpp
|
||||||
|
src/Scripts.cpp
|
||||||
|
src/SoundSystem.cpp
|
||||||
|
src/Spacestation2.cpp
|
||||||
|
src/TerminalScripts.cpp
|
||||||
|
src/Textbox.cpp
|
||||||
|
src/titlerender.cpp
|
||||||
|
src/Tower.cpp
|
||||||
|
src/UtilityClass.cpp
|
||||||
|
src/WarpClass.cpp
|
||||||
|
src/main.cpp
|
||||||
|
src/SteamNetwork.c
|
||||||
|
)
|
||||||
|
SET(XML_SRC
|
||||||
|
tinyxml/tinystr.cpp
|
||||||
|
tinyxml/tinyxml.cpp
|
||||||
|
tinyxml/tinyxmlerror.cpp
|
||||||
|
tinyxml/tinyxmlparser.cpp
|
||||||
|
)
|
||||||
|
SET(PFS_SRC
|
||||||
|
physfs/physfs.c
|
||||||
|
physfs/physfs_archiver_dir.c
|
||||||
|
physfs/physfs_archiver_unpacked.c
|
||||||
|
physfs/physfs_archiver_zip.c
|
||||||
|
physfs/physfs_byteorder.c
|
||||||
|
physfs/physfs_unicode.c
|
||||||
|
physfs/physfs_platform_posix.c
|
||||||
|
physfs/physfs_platform_unix.c
|
||||||
|
physfs/physfs_platform_windows.c
|
||||||
|
)
|
||||||
|
IF(APPLE)
|
||||||
|
# Are you noticing a pattern with this Apple crap yet?
|
||||||
|
SET(PFS_SRC ${PFS_SRC} physfs/physfs_platform_apple.m)
|
||||||
|
ENDIF()
|
||||||
|
SET(PNG_SRC lodepng/lodepng.c)
|
||||||
|
|
||||||
|
# Executable information
|
||||||
|
IF(WIN32)
|
||||||
|
ADD_EXECUTABLE(vvvvvv WIN32 ${VVV_SRC})
|
||||||
|
ELSE()
|
||||||
|
ADD_EXECUTABLE(vvvvvv ${VVV_SRC})
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Library information
|
||||||
|
ADD_LIBRARY(tinyxml-static STATIC ${XML_SRC})
|
||||||
|
ADD_LIBRARY(physfs-static STATIC ${PFS_SRC} ${PFSP_SRC})
|
||||||
|
ADD_LIBRARY(lodepng-static STATIC ${PNG_SRC})
|
||||||
|
|
||||||
|
# Static Dependencies
|
||||||
|
TARGET_LINK_LIBRARIES(vvvvvv physfs-static tinyxml-static lodepng-static)
|
||||||
|
|
||||||
|
# SDL2 Dependency (Detection pulled from FAudio)
|
||||||
|
if (DEFINED SDL2_INCLUDE_DIRS AND DEFINED SDL2_LIBRARIES)
|
||||||
|
message(STATUS "Using pre-defined SDL2 variables SDL2_INCLUDE_DIRS and SDL2_LIBRARIES")
|
||||||
|
target_include_directories(vvvvvv PUBLIC "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
|
||||||
|
target_link_libraries(vvvvvv ${SDL2_LIBRARIES})
|
||||||
|
else()
|
||||||
|
# Only try to autodetect if both SDL2 variables aren't explicitly set
|
||||||
|
find_package(SDL2 CONFIG)
|
||||||
|
if (TARGET SDL2::SDL2)
|
||||||
|
message(STATUS "Using TARGET SDL2::SDL2")
|
||||||
|
target_link_libraries(vvvvvv SDL2::SDL2 SDL2_mixer)
|
||||||
|
elseif (TARGET SDL2)
|
||||||
|
message(STATUS "Using TARGET SDL2")
|
||||||
|
target_link_libraries(vvvvvv SDL2 SDL2_mixer)
|
||||||
|
else()
|
||||||
|
message(STATUS "No TARGET SDL2::SDL2, or SDL2, using variables")
|
||||||
|
target_include_directories(vvvvvv PUBLIC "$<BUILD_INTERFACE:${SDL2_INCLUDE_DIRS}>")
|
||||||
|
target_link_libraries(vvvvvv ${SDL2_LIBRARIES} SDL2_mixer)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Yes, more Apple Crap
|
||||||
|
IF(APPLE)
|
||||||
|
FIND_LIBRARY(FOUNDATION NAMES Foundation)
|
||||||
|
FIND_LIBRARY(IOKIT NAMES IOKit)
|
||||||
|
TARGET_LINK_LIBRARIES(vvvvvv objc ${IOKIT} ${FOUNDATION})
|
||||||
|
ENDIF()
|
||||||
52
desktop_version/README.md
Normal file
52
desktop_version/README.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
How to Build
|
||||||
|
------------
|
||||||
|
VVVVVV's official desktop versions are built with the following environments:
|
||||||
|
|
||||||
|
- Windows: Visual Studio 2010
|
||||||
|
- macOS: Xcode CLT, currently targeting 10.9 SDK
|
||||||
|
- GNU/Linux: CentOS 7
|
||||||
|
|
||||||
|
The engine depends solely on SDL2 and SDL2_mixer. All other dependencies are
|
||||||
|
statically linked into the engine. The libs for Windows are in this repository,
|
||||||
|
all other platforms should install them either from the OS package manager or
|
||||||
|
from self-compiled source.
|
||||||
|
|
||||||
|
Steamworks support is included and the DLL is loaded dynamically, you do not
|
||||||
|
need the SDK headers and there is no special Steam or non-Steam version. The
|
||||||
|
current implementation has been tested with Steamworks SDK v1.46.
|
||||||
|
|
||||||
|
To generate the projects on Windows:
|
||||||
|
```
|
||||||
|
# Put the SDL2/SDL2_mixer VC development libraries next to the VVVVVV folder!
|
||||||
|
mkdir flibitBuild
|
||||||
|
cd flibitBuild
|
||||||
|
cmake -G "Visual Studio 10 2010" .. -DSDL2_INCLUDE_DIRS="../../SDL2-2.0.10/include;../../SDL2_mixer-2.0.4/include" -DSDL2_LIBRARIES="../../SDL2-2.0.10/lib/x86/SDL2;../../SDL2-2.0.10/lib/x86/SDL2main;../../SDL2_mixer-2.0.4/lib/x86/SDL2_mixer"
|
||||||
|
```
|
||||||
|
|
||||||
|
To generate everywhere else:
|
||||||
|
```
|
||||||
|
mkdir flibitBuild
|
||||||
|
cd flibitBuild
|
||||||
|
cmake ..
|
||||||
|
```
|
||||||
|
|
||||||
|
macOS may be fussy about the SDK version. How to fix this is up to the whims of
|
||||||
|
however Apple wants to make CMAKE_OSX_SYSROOT annoying to configure and retain
|
||||||
|
each time Xcode updates.
|
||||||
|
|
||||||
|
A Word About Compiler Quirks
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
This engine is _super_ fussy about optimization levels and runtime checks. In
|
||||||
|
particular, the Windows version _absolutely positively must_ be compiled in
|
||||||
|
Debug mode, with /RTC enabled. If you build in Release mode, or have /RTC
|
||||||
|
disabled, the game behaves dramatically different in ways that were never fully
|
||||||
|
documented (bizarre softlocks, out-of-bounds issues that don't show up in tools
|
||||||
|
like Valgrind, stuff like that). There are lots of things about this old code
|
||||||
|
that could be cleaned up, polished, rewritten, and so on, but this is the one
|
||||||
|
that will probably bite you the hardest when setting up your own build,
|
||||||
|
regardless of platform.
|
||||||
|
|
||||||
|
We hope you'll enjoy messing with the source anyway!
|
||||||
|
|
||||||
|
Love, flibit
|
||||||
6369
desktop_version/lodepng/lodepng.c
Normal file
6369
desktop_version/lodepng/lodepng.c
Normal file
File diff suppressed because it is too large
Load Diff
1941
desktop_version/lodepng/lodepng.h
Normal file
1941
desktop_version/lodepng/lodepng.h
Normal file
File diff suppressed because it is too large
Load Diff
23
desktop_version/physfs/LICENSE.txt
Normal file
23
desktop_version/physfs/LICENSE.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
Copyright (c) 2001-2019 Ryan C. Gordon and others.
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
In no event will the authors be held liable for any damages arising from
|
||||||
|
the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software in a
|
||||||
|
product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
Ryan C. Gordon <icculus@icculus.org>
|
||||||
|
|
||||||
9
desktop_version/physfs/README.txt
Normal file
9
desktop_version/physfs/README.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
PhysicsFS; a portable, flexible file i/o abstraction.
|
||||||
|
|
||||||
|
https://icculus.org/physfs/
|
||||||
|
|
||||||
|
Please see the docs directory for documentation.
|
||||||
|
|
||||||
|
Please see LICENSE.txt for licensing information.
|
||||||
|
|
||||||
3318
desktop_version/physfs/physfs.c
Normal file
3318
desktop_version/physfs/physfs.c
Normal file
File diff suppressed because it is too large
Load Diff
3854
desktop_version/physfs/physfs.h
Normal file
3854
desktop_version/physfs/physfs.h
Normal file
File diff suppressed because it is too large
Load Diff
196
desktop_version/physfs/physfs_archiver_dir.c
Normal file
196
desktop_version/physfs/physfs_archiver_dir.c
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* Standard directory I/O support routines for PhysicsFS.
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE.txt in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
/* There's no PHYSFS_Io interface here. Use __PHYSFS_createNativeIo(). */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static char *cvtToDependent(const char *prepend, const char *path,
|
||||||
|
char *buf, const size_t buflen)
|
||||||
|
{
|
||||||
|
BAIL_IF(buf == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
snprintf(buf, buflen, "%s%s", prepend ? prepend : "", path);
|
||||||
|
|
||||||
|
#if !__PHYSFS_STANDARD_DIRSEP
|
||||||
|
assert(__PHYSFS_platformDirSeparator != '/');
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
for (p = strchr(buf, '/'); p != NULL; p = strchr(p + 1, '/'))
|
||||||
|
*p = __PHYSFS_platformDirSeparator;
|
||||||
|
} /* if */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
} /* cvtToDependent */
|
||||||
|
|
||||||
|
|
||||||
|
#define CVT_TO_DEPENDENT(buf, pre, dir) { \
|
||||||
|
const size_t len = ((pre) ? strlen((char *) pre) : 0) + strlen(dir) + 1; \
|
||||||
|
buf = cvtToDependent((char*)pre,dir,(char*)__PHYSFS_smallAlloc(len),len); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void *DIR_openArchive(PHYSFS_Io *io, const char *name,
|
||||||
|
int forWriting, int *claimed)
|
||||||
|
{
|
||||||
|
PHYSFS_Stat st;
|
||||||
|
const char dirsep = __PHYSFS_platformDirSeparator;
|
||||||
|
char *retval = NULL;
|
||||||
|
const size_t namelen = strlen(name);
|
||||||
|
const size_t seplen = 1;
|
||||||
|
|
||||||
|
assert(io == NULL); /* shouldn't create an Io for these. */
|
||||||
|
BAIL_IF_ERRPASS(!__PHYSFS_platformStat(name, &st, 1), NULL);
|
||||||
|
|
||||||
|
if (st.filetype != PHYSFS_FILETYPE_DIRECTORY)
|
||||||
|
BAIL(PHYSFS_ERR_UNSUPPORTED, NULL);
|
||||||
|
|
||||||
|
*claimed = 1;
|
||||||
|
retval = allocator.Malloc(namelen + seplen + 1);
|
||||||
|
BAIL_IF(retval == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
|
||||||
|
strcpy(retval, name);
|
||||||
|
|
||||||
|
/* make sure there's a dir separator at the end of the string */
|
||||||
|
if (retval[namelen - 1] != dirsep)
|
||||||
|
{
|
||||||
|
retval[namelen] = dirsep;
|
||||||
|
retval[namelen + 1] = '\0';
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
} /* DIR_openArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_EnumerateCallbackResult DIR_enumerate(void *opaque,
|
||||||
|
const char *dname, PHYSFS_EnumerateCallback cb,
|
||||||
|
const char *origdir, void *callbackdata)
|
||||||
|
{
|
||||||
|
char *d;
|
||||||
|
PHYSFS_EnumerateCallbackResult retval;
|
||||||
|
CVT_TO_DEPENDENT(d, opaque, dname);
|
||||||
|
BAIL_IF_ERRPASS(!d, PHYSFS_ENUM_ERROR);
|
||||||
|
retval = __PHYSFS_platformEnumerate(d, cb, origdir, callbackdata);
|
||||||
|
__PHYSFS_smallFree(d);
|
||||||
|
return retval;
|
||||||
|
} /* DIR_enumerate */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_Io *doOpen(void *opaque, const char *name, const int mode)
|
||||||
|
{
|
||||||
|
PHYSFS_Io *io = NULL;
|
||||||
|
char *f = NULL;
|
||||||
|
|
||||||
|
CVT_TO_DEPENDENT(f, opaque, name);
|
||||||
|
BAIL_IF_ERRPASS(!f, NULL);
|
||||||
|
|
||||||
|
io = __PHYSFS_createNativeIo(f, mode);
|
||||||
|
if (io == NULL)
|
||||||
|
{
|
||||||
|
const PHYSFS_ErrorCode err = PHYSFS_getLastErrorCode();
|
||||||
|
PHYSFS_Stat statbuf;
|
||||||
|
__PHYSFS_platformStat(f, &statbuf, 0); /* !!! FIXME: why are we stating here? */
|
||||||
|
PHYSFS_setErrorCode(err);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
__PHYSFS_smallFree(f);
|
||||||
|
|
||||||
|
return io;
|
||||||
|
} /* doOpen */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_Io *DIR_openRead(void *opaque, const char *filename)
|
||||||
|
{
|
||||||
|
return doOpen(opaque, filename, 'r');
|
||||||
|
} /* DIR_openRead */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_Io *DIR_openWrite(void *opaque, const char *filename)
|
||||||
|
{
|
||||||
|
return doOpen(opaque, filename, 'w');
|
||||||
|
} /* DIR_openWrite */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_Io *DIR_openAppend(void *opaque, const char *filename)
|
||||||
|
{
|
||||||
|
return doOpen(opaque, filename, 'a');
|
||||||
|
} /* DIR_openAppend */
|
||||||
|
|
||||||
|
|
||||||
|
static int DIR_remove(void *opaque, const char *name)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char *f;
|
||||||
|
|
||||||
|
CVT_TO_DEPENDENT(f, opaque, name);
|
||||||
|
BAIL_IF_ERRPASS(!f, 0);
|
||||||
|
retval = __PHYSFS_platformDelete(f);
|
||||||
|
__PHYSFS_smallFree(f);
|
||||||
|
return retval;
|
||||||
|
} /* DIR_remove */
|
||||||
|
|
||||||
|
|
||||||
|
static int DIR_mkdir(void *opaque, const char *name)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
char *f;
|
||||||
|
|
||||||
|
CVT_TO_DEPENDENT(f, opaque, name);
|
||||||
|
BAIL_IF_ERRPASS(!f, 0);
|
||||||
|
retval = __PHYSFS_platformMkDir(f);
|
||||||
|
__PHYSFS_smallFree(f);
|
||||||
|
return retval;
|
||||||
|
} /* DIR_mkdir */
|
||||||
|
|
||||||
|
|
||||||
|
static void DIR_closeArchive(void *opaque)
|
||||||
|
{
|
||||||
|
allocator.Free(opaque);
|
||||||
|
} /* DIR_closeArchive */
|
||||||
|
|
||||||
|
|
||||||
|
static int DIR_stat(void *opaque, const char *name, PHYSFS_Stat *stat)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
char *d;
|
||||||
|
|
||||||
|
CVT_TO_DEPENDENT(d, opaque, name);
|
||||||
|
BAIL_IF_ERRPASS(!d, 0);
|
||||||
|
retval = __PHYSFS_platformStat(d, stat, 0);
|
||||||
|
__PHYSFS_smallFree(d);
|
||||||
|
return retval;
|
||||||
|
} /* DIR_stat */
|
||||||
|
|
||||||
|
|
||||||
|
const PHYSFS_Archiver __PHYSFS_Archiver_DIR =
|
||||||
|
{
|
||||||
|
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
|
||||||
|
{
|
||||||
|
"",
|
||||||
|
"Non-archive, direct filesystem I/O",
|
||||||
|
"Ryan C. Gordon <icculus@icculus.org>",
|
||||||
|
"https://icculus.org/physfs/",
|
||||||
|
1, /* supportsSymlinks */
|
||||||
|
},
|
||||||
|
DIR_openArchive,
|
||||||
|
DIR_enumerate,
|
||||||
|
DIR_openRead,
|
||||||
|
DIR_openWrite,
|
||||||
|
DIR_openAppend,
|
||||||
|
DIR_remove,
|
||||||
|
DIR_mkdir,
|
||||||
|
DIR_stat,
|
||||||
|
DIR_closeArchive
|
||||||
|
};
|
||||||
|
|
||||||
|
/* end of physfs_archiver_dir.c ... */
|
||||||
|
|
||||||
305
desktop_version/physfs/physfs_archiver_unpacked.c
Normal file
305
desktop_version/physfs/physfs_archiver_unpacked.c
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
/*
|
||||||
|
* High-level PhysicsFS archiver for simple unpacked file formats.
|
||||||
|
*
|
||||||
|
* This is a framework that basic archivers build on top of. It's for simple
|
||||||
|
* formats that can just hand back a list of files and the offsets of their
|
||||||
|
* uncompressed data. There are an alarming number of formats like this.
|
||||||
|
*
|
||||||
|
* RULES: Archive entries must be uncompressed. Dirs and files allowed, but no
|
||||||
|
* symlinks, etc. We can relax some of these rules as necessary.
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE.txt in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__PHYSFS_DirTree tree;
|
||||||
|
PHYSFS_Io *io;
|
||||||
|
} UNPKinfo;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__PHYSFS_DirTreeEntry tree;
|
||||||
|
PHYSFS_uint64 startPos;
|
||||||
|
PHYSFS_uint64 size;
|
||||||
|
PHYSFS_sint64 ctime;
|
||||||
|
PHYSFS_sint64 mtime;
|
||||||
|
} UNPKentry;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PHYSFS_Io *io;
|
||||||
|
UNPKentry *entry;
|
||||||
|
PHYSFS_uint32 curPos;
|
||||||
|
} UNPKfileinfo;
|
||||||
|
|
||||||
|
|
||||||
|
void UNPK_closeArchive(void *opaque)
|
||||||
|
{
|
||||||
|
UNPKinfo *info = ((UNPKinfo *) opaque);
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
__PHYSFS_DirTreeDeinit(&info->tree);
|
||||||
|
|
||||||
|
if (info->io)
|
||||||
|
info->io->destroy(info->io);
|
||||||
|
|
||||||
|
allocator.Free(info);
|
||||||
|
} /* if */
|
||||||
|
} /* UNPK_closeArchive */
|
||||||
|
|
||||||
|
void UNPK_abandonArchive(void *opaque)
|
||||||
|
{
|
||||||
|
UNPKinfo *info = ((UNPKinfo *) opaque);
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
info->io = NULL;
|
||||||
|
UNPK_closeArchive(info);
|
||||||
|
} /* if */
|
||||||
|
} /* UNPK_abandonArchive */
|
||||||
|
|
||||||
|
static PHYSFS_sint64 UNPK_read(PHYSFS_Io *io, void *buffer, PHYSFS_uint64 len)
|
||||||
|
{
|
||||||
|
UNPKfileinfo *finfo = (UNPKfileinfo *) io->opaque;
|
||||||
|
const UNPKentry *entry = finfo->entry;
|
||||||
|
const PHYSFS_uint64 bytesLeft = (PHYSFS_uint64)(entry->size-finfo->curPos);
|
||||||
|
PHYSFS_sint64 rc;
|
||||||
|
|
||||||
|
if (bytesLeft < len)
|
||||||
|
len = bytesLeft;
|
||||||
|
|
||||||
|
rc = finfo->io->read(finfo->io, buffer, len);
|
||||||
|
if (rc > 0)
|
||||||
|
finfo->curPos += (PHYSFS_uint32) rc;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
} /* UNPK_read */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 UNPK_write(PHYSFS_Io *io, const void *b, PHYSFS_uint64 len)
|
||||||
|
{
|
||||||
|
BAIL(PHYSFS_ERR_READ_ONLY, -1);
|
||||||
|
} /* UNPK_write */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 UNPK_tell(PHYSFS_Io *io)
|
||||||
|
{
|
||||||
|
return ((UNPKfileinfo *) io->opaque)->curPos;
|
||||||
|
} /* UNPK_tell */
|
||||||
|
|
||||||
|
|
||||||
|
static int UNPK_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
|
||||||
|
{
|
||||||
|
UNPKfileinfo *finfo = (UNPKfileinfo *) io->opaque;
|
||||||
|
const UNPKentry *entry = finfo->entry;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
BAIL_IF(offset >= entry->size, PHYSFS_ERR_PAST_EOF, 0);
|
||||||
|
rc = finfo->io->seek(finfo->io, entry->startPos + offset);
|
||||||
|
if (rc)
|
||||||
|
finfo->curPos = (PHYSFS_uint32) offset;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
} /* UNPK_seek */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_sint64 UNPK_length(PHYSFS_Io *io)
|
||||||
|
{
|
||||||
|
const UNPKfileinfo *finfo = (UNPKfileinfo *) io->opaque;
|
||||||
|
return ((PHYSFS_sint64) finfo->entry->size);
|
||||||
|
} /* UNPK_length */
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_Io *UNPK_duplicate(PHYSFS_Io *_io)
|
||||||
|
{
|
||||||
|
UNPKfileinfo *origfinfo = (UNPKfileinfo *) _io->opaque;
|
||||||
|
PHYSFS_Io *io = NULL;
|
||||||
|
PHYSFS_Io *retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
|
||||||
|
UNPKfileinfo *finfo = (UNPKfileinfo *) allocator.Malloc(sizeof (UNPKfileinfo));
|
||||||
|
GOTO_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_duplicate_failed);
|
||||||
|
GOTO_IF(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_duplicate_failed);
|
||||||
|
|
||||||
|
io = origfinfo->io->duplicate(origfinfo->io);
|
||||||
|
if (!io) goto UNPK_duplicate_failed;
|
||||||
|
finfo->io = io;
|
||||||
|
finfo->entry = origfinfo->entry;
|
||||||
|
finfo->curPos = 0;
|
||||||
|
memcpy(retval, _io, sizeof (PHYSFS_Io));
|
||||||
|
retval->opaque = finfo;
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
UNPK_duplicate_failed:
|
||||||
|
if (finfo != NULL) allocator.Free(finfo);
|
||||||
|
if (retval != NULL) allocator.Free(retval);
|
||||||
|
if (io != NULL) io->destroy(io);
|
||||||
|
return NULL;
|
||||||
|
} /* UNPK_duplicate */
|
||||||
|
|
||||||
|
static int UNPK_flush(PHYSFS_Io *io) { return 1; /* no write support. */ }
|
||||||
|
|
||||||
|
static void UNPK_destroy(PHYSFS_Io *io)
|
||||||
|
{
|
||||||
|
UNPKfileinfo *finfo = (UNPKfileinfo *) io->opaque;
|
||||||
|
finfo->io->destroy(finfo->io);
|
||||||
|
allocator.Free(finfo);
|
||||||
|
allocator.Free(io);
|
||||||
|
} /* UNPK_destroy */
|
||||||
|
|
||||||
|
|
||||||
|
static const PHYSFS_Io UNPK_Io =
|
||||||
|
{
|
||||||
|
CURRENT_PHYSFS_IO_API_VERSION, NULL,
|
||||||
|
UNPK_read,
|
||||||
|
UNPK_write,
|
||||||
|
UNPK_seek,
|
||||||
|
UNPK_tell,
|
||||||
|
UNPK_length,
|
||||||
|
UNPK_duplicate,
|
||||||
|
UNPK_flush,
|
||||||
|
UNPK_destroy
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static inline UNPKentry *findEntry(UNPKinfo *info, const char *path)
|
||||||
|
{
|
||||||
|
return (UNPKentry *) __PHYSFS_DirTreeFind(&info->tree, path);
|
||||||
|
} /* findEntry */
|
||||||
|
|
||||||
|
|
||||||
|
PHYSFS_Io *UNPK_openRead(void *opaque, const char *name)
|
||||||
|
{
|
||||||
|
PHYSFS_Io *retval = NULL;
|
||||||
|
UNPKinfo *info = (UNPKinfo *) opaque;
|
||||||
|
UNPKfileinfo *finfo = NULL;
|
||||||
|
UNPKentry *entry = findEntry(info, name);
|
||||||
|
|
||||||
|
BAIL_IF_ERRPASS(!entry, NULL);
|
||||||
|
BAIL_IF(entry->tree.isdir, PHYSFS_ERR_NOT_A_FILE, NULL);
|
||||||
|
|
||||||
|
retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
|
||||||
|
GOTO_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_openRead_failed);
|
||||||
|
|
||||||
|
finfo = (UNPKfileinfo *) allocator.Malloc(sizeof (UNPKfileinfo));
|
||||||
|
GOTO_IF(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_openRead_failed);
|
||||||
|
|
||||||
|
finfo->io = info->io->duplicate(info->io);
|
||||||
|
GOTO_IF_ERRPASS(!finfo->io, UNPK_openRead_failed);
|
||||||
|
|
||||||
|
if (!finfo->io->seek(finfo->io, entry->startPos))
|
||||||
|
goto UNPK_openRead_failed;
|
||||||
|
|
||||||
|
finfo->curPos = 0;
|
||||||
|
finfo->entry = entry;
|
||||||
|
|
||||||
|
memcpy(retval, &UNPK_Io, sizeof (*retval));
|
||||||
|
retval->opaque = finfo;
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
UNPK_openRead_failed:
|
||||||
|
if (finfo != NULL)
|
||||||
|
{
|
||||||
|
if (finfo->io != NULL)
|
||||||
|
finfo->io->destroy(finfo->io);
|
||||||
|
allocator.Free(finfo);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (retval != NULL)
|
||||||
|
allocator.Free(retval);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
} /* UNPK_openRead */
|
||||||
|
|
||||||
|
|
||||||
|
PHYSFS_Io *UNPK_openWrite(void *opaque, const char *name)
|
||||||
|
{
|
||||||
|
BAIL(PHYSFS_ERR_READ_ONLY, NULL);
|
||||||
|
} /* UNPK_openWrite */
|
||||||
|
|
||||||
|
|
||||||
|
PHYSFS_Io *UNPK_openAppend(void *opaque, const char *name)
|
||||||
|
{
|
||||||
|
BAIL(PHYSFS_ERR_READ_ONLY, NULL);
|
||||||
|
} /* UNPK_openAppend */
|
||||||
|
|
||||||
|
|
||||||
|
int UNPK_remove(void *opaque, const char *name)
|
||||||
|
{
|
||||||
|
BAIL(PHYSFS_ERR_READ_ONLY, 0);
|
||||||
|
} /* UNPK_remove */
|
||||||
|
|
||||||
|
|
||||||
|
int UNPK_mkdir(void *opaque, const char *name)
|
||||||
|
{
|
||||||
|
BAIL(PHYSFS_ERR_READ_ONLY, 0);
|
||||||
|
} /* UNPK_mkdir */
|
||||||
|
|
||||||
|
|
||||||
|
int UNPK_stat(void *opaque, const char *path, PHYSFS_Stat *stat)
|
||||||
|
{
|
||||||
|
UNPKinfo *info = (UNPKinfo *) opaque;
|
||||||
|
const UNPKentry *entry = findEntry(info, path);
|
||||||
|
|
||||||
|
BAIL_IF_ERRPASS(!entry, 0);
|
||||||
|
|
||||||
|
if (entry->tree.isdir)
|
||||||
|
{
|
||||||
|
stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
|
||||||
|
stat->filesize = 0;
|
||||||
|
} /* if */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stat->filetype = PHYSFS_FILETYPE_REGULAR;
|
||||||
|
stat->filesize = entry->size;
|
||||||
|
} /* else */
|
||||||
|
|
||||||
|
stat->modtime = entry->mtime;
|
||||||
|
stat->createtime = entry->ctime;
|
||||||
|
stat->accesstime = -1;
|
||||||
|
stat->readonly = 1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
} /* UNPK_stat */
|
||||||
|
|
||||||
|
|
||||||
|
void *UNPK_addEntry(void *opaque, char *name, const int isdir,
|
||||||
|
const PHYSFS_sint64 ctime, const PHYSFS_sint64 mtime,
|
||||||
|
const PHYSFS_uint64 pos, const PHYSFS_uint64 len)
|
||||||
|
{
|
||||||
|
UNPKinfo *info = (UNPKinfo *) opaque;
|
||||||
|
UNPKentry *entry;
|
||||||
|
|
||||||
|
entry = (UNPKentry *) __PHYSFS_DirTreeAdd(&info->tree, name, isdir);
|
||||||
|
BAIL_IF_ERRPASS(!entry, NULL);
|
||||||
|
|
||||||
|
entry->startPos = isdir ? 0 : pos;
|
||||||
|
entry->size = isdir ? 0 : len;
|
||||||
|
entry->ctime = ctime;
|
||||||
|
entry->mtime = mtime;
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
} /* UNPK_addEntry */
|
||||||
|
|
||||||
|
|
||||||
|
void *UNPK_openArchive(PHYSFS_Io *io)
|
||||||
|
{
|
||||||
|
UNPKinfo *info = (UNPKinfo *) allocator.Malloc(sizeof (UNPKinfo));
|
||||||
|
BAIL_IF(!info, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
|
||||||
|
if (!__PHYSFS_DirTreeInit(&info->tree, sizeof (UNPKentry)))
|
||||||
|
{
|
||||||
|
allocator.Free(info);
|
||||||
|
return NULL;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
info->io = io;
|
||||||
|
|
||||||
|
return info;
|
||||||
|
} /* UNPK_openArchive */
|
||||||
|
|
||||||
|
/* end of physfs_archiver_unpacked.c ... */
|
||||||
|
|
||||||
1710
desktop_version/physfs/physfs_archiver_zip.c
Normal file
1710
desktop_version/physfs/physfs_archiver_zip.c
Normal file
File diff suppressed because it is too large
Load Diff
137
desktop_version/physfs/physfs_byteorder.c
Normal file
137
desktop_version/physfs/physfs_byteorder.c
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
* PhysicsFS; a portable, flexible file i/o abstraction.
|
||||||
|
*
|
||||||
|
* Documentation is in physfs.h. It's verbose, honest. :)
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE.txt in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
#ifndef PHYSFS_Swap16
|
||||||
|
static inline PHYSFS_uint16 PHYSFS_Swap16(PHYSFS_uint16 D)
|
||||||
|
{
|
||||||
|
return ((D<<8)|(D>>8));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifndef PHYSFS_Swap32
|
||||||
|
static inline PHYSFS_uint32 PHYSFS_Swap32(PHYSFS_uint32 D)
|
||||||
|
{
|
||||||
|
return ((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifndef PHYSFS_NO_64BIT_SUPPORT
|
||||||
|
#ifndef PHYSFS_Swap64
|
||||||
|
static inline PHYSFS_uint64 PHYSFS_Swap64(PHYSFS_uint64 val) {
|
||||||
|
PHYSFS_uint32 hi, lo;
|
||||||
|
|
||||||
|
/* Separate into high and low 32-bit values and swap them */
|
||||||
|
lo = (PHYSFS_uint32)(val&0xFFFFFFFF);
|
||||||
|
val >>= 32;
|
||||||
|
hi = (PHYSFS_uint32)(val&0xFFFFFFFF);
|
||||||
|
val = PHYSFS_Swap32(lo);
|
||||||
|
val <<= 32;
|
||||||
|
val |= PHYSFS_Swap32(hi);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifndef PHYSFS_Swap64
|
||||||
|
/* This is mainly to keep compilers from complaining in PHYSFS code.
|
||||||
|
If there is no real 64-bit datatype, then compilers will complain about
|
||||||
|
the fake 64-bit datatype that PHYSFS provides when it compiles user code.
|
||||||
|
*/
|
||||||
|
#define PHYSFS_Swap64(X) (X)
|
||||||
|
#endif
|
||||||
|
#endif /* PHYSFS_NO_64BIT_SUPPORT */
|
||||||
|
|
||||||
|
|
||||||
|
/* Byteswap item from the specified endianness to the native endianness */
|
||||||
|
#if PHYSFS_BYTEORDER == PHYSFS_LIL_ENDIAN
|
||||||
|
PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 x) { return x; }
|
||||||
|
PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 x) { return x; }
|
||||||
|
PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 x) { return x; }
|
||||||
|
PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 x) { return x; }
|
||||||
|
PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 x) { return x; }
|
||||||
|
PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 x) { return x; }
|
||||||
|
|
||||||
|
PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 x) { return PHYSFS_Swap16(x); }
|
||||||
|
PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 x) { return PHYSFS_Swap16(x); }
|
||||||
|
PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 x) { return PHYSFS_Swap32(x); }
|
||||||
|
PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 x) { return PHYSFS_Swap32(x); }
|
||||||
|
PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 x) { return PHYSFS_Swap64(x); }
|
||||||
|
PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 x) { return PHYSFS_Swap64(x); }
|
||||||
|
#else
|
||||||
|
PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 x) { return PHYSFS_Swap16(x); }
|
||||||
|
PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 x) { return PHYSFS_Swap16(x); }
|
||||||
|
PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 x) { return PHYSFS_Swap32(x); }
|
||||||
|
PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 x) { return PHYSFS_Swap32(x); }
|
||||||
|
PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 x) { return PHYSFS_Swap64(x); }
|
||||||
|
PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 x) { return PHYSFS_Swap64(x); }
|
||||||
|
|
||||||
|
PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 x) { return x; }
|
||||||
|
PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 x) { return x; }
|
||||||
|
PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 x) { return x; }
|
||||||
|
PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 x) { return x; }
|
||||||
|
PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 x) { return x; }
|
||||||
|
PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 x) { return x; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline int readAll(PHYSFS_File *file, void *val, const size_t len)
|
||||||
|
{
|
||||||
|
return (PHYSFS_readBytes(file, val, len) == len);
|
||||||
|
} /* readAll */
|
||||||
|
|
||||||
|
#define PHYSFS_BYTEORDER_READ(datatype, swaptype) \
|
||||||
|
int PHYSFS_read##swaptype(PHYSFS_File *file, PHYSFS_##datatype *val) { \
|
||||||
|
PHYSFS_##datatype in; \
|
||||||
|
BAIL_IF(val == NULL, PHYSFS_ERR_INVALID_ARGUMENT, 0); \
|
||||||
|
BAIL_IF_ERRPASS(!readAll(file, &in, sizeof (in)), 0); \
|
||||||
|
*val = PHYSFS_swap##swaptype(in); \
|
||||||
|
return 1; \
|
||||||
|
}
|
||||||
|
|
||||||
|
PHYSFS_BYTEORDER_READ(sint16, SLE16)
|
||||||
|
PHYSFS_BYTEORDER_READ(uint16, ULE16)
|
||||||
|
PHYSFS_BYTEORDER_READ(sint16, SBE16)
|
||||||
|
PHYSFS_BYTEORDER_READ(uint16, UBE16)
|
||||||
|
PHYSFS_BYTEORDER_READ(sint32, SLE32)
|
||||||
|
PHYSFS_BYTEORDER_READ(uint32, ULE32)
|
||||||
|
PHYSFS_BYTEORDER_READ(sint32, SBE32)
|
||||||
|
PHYSFS_BYTEORDER_READ(uint32, UBE32)
|
||||||
|
PHYSFS_BYTEORDER_READ(sint64, SLE64)
|
||||||
|
PHYSFS_BYTEORDER_READ(uint64, ULE64)
|
||||||
|
PHYSFS_BYTEORDER_READ(sint64, SBE64)
|
||||||
|
PHYSFS_BYTEORDER_READ(uint64, UBE64)
|
||||||
|
|
||||||
|
|
||||||
|
static inline int writeAll(PHYSFS_File *f, const void *val, const size_t len)
|
||||||
|
{
|
||||||
|
return (PHYSFS_writeBytes(f, val, len) == len);
|
||||||
|
} /* writeAll */
|
||||||
|
|
||||||
|
#define PHYSFS_BYTEORDER_WRITE(datatype, swaptype) \
|
||||||
|
int PHYSFS_write##swaptype(PHYSFS_File *file, PHYSFS_##datatype val) { \
|
||||||
|
const PHYSFS_##datatype out = PHYSFS_swap##swaptype(val); \
|
||||||
|
BAIL_IF_ERRPASS(!writeAll(file, &out, sizeof (out)), 0); \
|
||||||
|
return 1; \
|
||||||
|
}
|
||||||
|
|
||||||
|
PHYSFS_BYTEORDER_WRITE(sint16, SLE16)
|
||||||
|
PHYSFS_BYTEORDER_WRITE(uint16, ULE16)
|
||||||
|
PHYSFS_BYTEORDER_WRITE(sint16, SBE16)
|
||||||
|
PHYSFS_BYTEORDER_WRITE(uint16, UBE16)
|
||||||
|
PHYSFS_BYTEORDER_WRITE(sint32, SLE32)
|
||||||
|
PHYSFS_BYTEORDER_WRITE(uint32, ULE32)
|
||||||
|
PHYSFS_BYTEORDER_WRITE(sint32, SBE32)
|
||||||
|
PHYSFS_BYTEORDER_WRITE(uint32, UBE32)
|
||||||
|
PHYSFS_BYTEORDER_WRITE(sint64, SLE64)
|
||||||
|
PHYSFS_BYTEORDER_WRITE(uint64, ULE64)
|
||||||
|
PHYSFS_BYTEORDER_WRITE(sint64, SBE64)
|
||||||
|
PHYSFS_BYTEORDER_WRITE(uint64, UBE64)
|
||||||
|
|
||||||
|
/* end of physfs_byteorder.c ... */
|
||||||
|
|
||||||
2572
desktop_version/physfs/physfs_casefolding.h
Normal file
2572
desktop_version/physfs/physfs_casefolding.h
Normal file
File diff suppressed because it is too large
Load Diff
729
desktop_version/physfs/physfs_internal.h
Normal file
729
desktop_version/physfs/physfs_internal.h
Normal file
@@ -0,0 +1,729 @@
|
|||||||
|
/*
|
||||||
|
* Internal function/structure declaration. Do NOT include in your
|
||||||
|
* application.
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE.txt in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_PHYSFS_INTERNAL_H_
|
||||||
|
#define _INCLUDE_PHYSFS_INTERNAL_H_
|
||||||
|
|
||||||
|
#ifndef __PHYSICSFS_INTERNAL__
|
||||||
|
#error Do not include this header from your applications.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Turn off MSVC warnings that are aggressively anti-portability. */
|
||||||
|
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "physfs.h"
|
||||||
|
|
||||||
|
/* The holy trinity. */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "physfs_platforms.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define __PHYSFS_COMPILE_TIME_ASSERT(name, x) \
|
||||||
|
typedef int __PHYSFS_compile_time_assert_##name[(x) * 2 - 1]
|
||||||
|
|
||||||
|
/* !!! FIXME: remove this when revamping stack allocation code... */
|
||||||
|
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__WATCOMC__)
|
||||||
|
#include <malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PHYSFS_PLATFORM_SOLARIS
|
||||||
|
#include <alloca.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define PHYSFS_MINIMUM_GCC_VERSION(major, minor) \
|
||||||
|
( ((__GNUC__ << 16) + __GNUC_MINOR__) >= (((major) << 16) + (minor)) )
|
||||||
|
#else
|
||||||
|
#define PHYSFS_MINIMUM_GCC_VERSION(major, minor) (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* C++ always has a real inline keyword. */
|
||||||
|
#elif (defined macintosh) && !(defined __MWERKS__)
|
||||||
|
# define inline
|
||||||
|
#elif (defined _MSC_VER)
|
||||||
|
# define inline __inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PHYSFS_PLATFORM_LINUX) && !defined(_FILE_OFFSET_BITS)
|
||||||
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* All public APIs need to be in physfs.h with a PHYSFS_DECL.
|
||||||
|
All file-private symbols need to be marked "static".
|
||||||
|
Everything shared between PhysicsFS sources needs to be in this
|
||||||
|
file between the visibility pragma blocks. */
|
||||||
|
#if PHYSFS_MINIMUM_GCC_VERSION(4,0) || defined(__clang__)
|
||||||
|
#define PHYSFS_HAVE_PRAGMA_VISIBILITY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PHYSFS_HAVE_PRAGMA_VISIBILITY
|
||||||
|
#pragma GCC visibility push(hidden)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* These are the build-in archivers. We list them all as "extern" here without
|
||||||
|
#ifdefs to keep it tidy, but obviously you need to make sure these are
|
||||||
|
wrapped in PHYSFS_SUPPORTS_* checks before actually referencing them. */
|
||||||
|
extern const PHYSFS_Archiver __PHYSFS_Archiver_DIR;
|
||||||
|
extern const PHYSFS_Archiver __PHYSFS_Archiver_ZIP;
|
||||||
|
extern const PHYSFS_Archiver __PHYSFS_Archiver_7Z;
|
||||||
|
extern const PHYSFS_Archiver __PHYSFS_Archiver_GRP;
|
||||||
|
extern const PHYSFS_Archiver __PHYSFS_Archiver_QPAK;
|
||||||
|
extern const PHYSFS_Archiver __PHYSFS_Archiver_HOG;
|
||||||
|
extern const PHYSFS_Archiver __PHYSFS_Archiver_MVL;
|
||||||
|
extern const PHYSFS_Archiver __PHYSFS_Archiver_WAD;
|
||||||
|
extern const PHYSFS_Archiver __PHYSFS_Archiver_SLB;
|
||||||
|
extern const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660;
|
||||||
|
extern const PHYSFS_Archiver __PHYSFS_Archiver_VDF;
|
||||||
|
|
||||||
|
/* a real C99-compliant snprintf() is in Visual Studio 2015,
|
||||||
|
but just use this everywhere for binary compatibility. */
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
int __PHYSFS_msvc_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap);
|
||||||
|
int __PHYSFS_msvc_snprintf(char *outBuf, size_t size, const char *format, ...);
|
||||||
|
#define vsnprintf __PHYSFS_msvc_vsnprintf
|
||||||
|
#define snprintf __PHYSFS_msvc_snprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Some simple wrappers around WinRT C++ interfaces we can call from C. */
|
||||||
|
#ifdef PHYSFS_PLATFORM_WINRT
|
||||||
|
const void *__PHYSFS_winrtCalcBaseDir(void);
|
||||||
|
const void *__PHYSFS_winrtCalcPrefDir(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* atomic operations. */
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
|
||||||
|
#include <intrin.h>
|
||||||
|
__PHYSFS_COMPILE_TIME_ASSERT(LongEqualsInt, sizeof (int) == sizeof (long));
|
||||||
|
#define __PHYSFS_ATOMIC_INCR(ptrval) _InterlockedIncrement((long*)(ptrval))
|
||||||
|
#define __PHYSFS_ATOMIC_DECR(ptrval) _InterlockedDecrement((long*)(ptrval))
|
||||||
|
#elif defined(__clang__) || (defined(__GNUC__) && (((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100)) >= 40100))
|
||||||
|
#define __PHYSFS_ATOMIC_INCR(ptrval) __sync_fetch_and_add(ptrval, 1)
|
||||||
|
#define __PHYSFS_ATOMIC_DECR(ptrval) __sync_fetch_and_add(ptrval, -1)
|
||||||
|
#else
|
||||||
|
#define PHYSFS_NEED_ATOMIC_OP_FALLBACK 1
|
||||||
|
int __PHYSFS_ATOMIC_INCR(int *ptrval);
|
||||||
|
int __PHYSFS_ATOMIC_DECR(int *ptrval);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interface for small allocations. If you need a little scratch space for
|
||||||
|
* a throwaway buffer or string, use this. It will make small allocations
|
||||||
|
* on the stack if possible, and use allocator.Malloc() if they are too
|
||||||
|
* large. This helps reduce malloc pressure.
|
||||||
|
* There are some rules, though:
|
||||||
|
* NEVER return a pointer from this, as stack-allocated buffers go away
|
||||||
|
* when your function returns.
|
||||||
|
* NEVER allocate in a loop, as stack-allocated pointers will pile up. Call
|
||||||
|
* a function that uses smallAlloc from your loop, so the allocation can
|
||||||
|
* free each time.
|
||||||
|
* NEVER call smallAlloc with any complex expression (it's a macro that WILL
|
||||||
|
* have side effects...it references the argument multiple times). Use a
|
||||||
|
* variable or a literal.
|
||||||
|
* NEVER free a pointer from this with anything but smallFree. It will not
|
||||||
|
* be a valid pointer to the allocator, regardless of where the memory came
|
||||||
|
* from.
|
||||||
|
* NEVER realloc a pointer from this.
|
||||||
|
* NEVER forget to use smallFree: it may not be a pointer from the stack.
|
||||||
|
* NEVER forget to check for NULL...allocation can fail here, of course!
|
||||||
|
*/
|
||||||
|
#define __PHYSFS_SMALLALLOCTHRESHOLD 256
|
||||||
|
void *__PHYSFS_initSmallAlloc(void *ptr, const size_t len);
|
||||||
|
|
||||||
|
#define __PHYSFS_smallAlloc(bytes) ( \
|
||||||
|
__PHYSFS_initSmallAlloc( \
|
||||||
|
(((bytes) < __PHYSFS_SMALLALLOCTHRESHOLD) ? \
|
||||||
|
alloca((size_t)((bytes)+sizeof(void*))) : NULL), (bytes)) \
|
||||||
|
)
|
||||||
|
|
||||||
|
void __PHYSFS_smallFree(void *ptr);
|
||||||
|
|
||||||
|
|
||||||
|
/* Use the allocation hooks. */
|
||||||
|
#define malloc(x) Do not use malloc() directly.
|
||||||
|
#define realloc(x, y) Do not use realloc() directly.
|
||||||
|
#define free(x) Do not use free() directly.
|
||||||
|
/* !!! FIXME: add alloca check here. */
|
||||||
|
|
||||||
|
|
||||||
|
/* by default, enable things, so builds can opt out of a few things they
|
||||||
|
want to avoid. But you can build with this #defined to 0 if you would
|
||||||
|
like to turn off everything except a handful of things you opt into. */
|
||||||
|
#ifndef PHYSFS_SUPPORTS_DEFAULT
|
||||||
|
#define PHYSFS_SUPPORTS_DEFAULT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PHYSFS_SUPPORTS_ZIP
|
||||||
|
#define PHYSFS_SUPPORTS_ZIP PHYSFS_SUPPORTS_DEFAULT
|
||||||
|
#endif
|
||||||
|
#ifndef PHYSFS_SUPPORTS_7Z
|
||||||
|
#define PHYSFS_SUPPORTS_7Z PHYSFS_SUPPORTS_DEFAULT
|
||||||
|
#endif
|
||||||
|
#ifndef PHYSFS_SUPPORTS_GRP
|
||||||
|
#define PHYSFS_SUPPORTS_GRP PHYSFS_SUPPORTS_DEFAULT
|
||||||
|
#endif
|
||||||
|
#ifndef PHYSFS_SUPPORTS_HOG
|
||||||
|
#define PHYSFS_SUPPORTS_HOG PHYSFS_SUPPORTS_DEFAULT
|
||||||
|
#endif
|
||||||
|
#ifndef PHYSFS_SUPPORTS_MVL
|
||||||
|
#define PHYSFS_SUPPORTS_MVL PHYSFS_SUPPORTS_DEFAULT
|
||||||
|
#endif
|
||||||
|
#ifndef PHYSFS_SUPPORTS_WAD
|
||||||
|
#define PHYSFS_SUPPORTS_WAD PHYSFS_SUPPORTS_DEFAULT
|
||||||
|
#endif
|
||||||
|
#ifndef PHYSFS_SUPPORTS_QPAK
|
||||||
|
#define PHYSFS_SUPPORTS_QPAK PHYSFS_SUPPORTS_DEFAULT
|
||||||
|
#endif
|
||||||
|
#ifndef PHYSFS_SUPPORTS_SLB
|
||||||
|
#define PHYSFS_SUPPORTS_SLB PHYSFS_SUPPORTS_DEFAULT
|
||||||
|
#endif
|
||||||
|
#ifndef PHYSFS_SUPPORTS_ISO9660
|
||||||
|
#define PHYSFS_SUPPORTS_ISO9660 PHYSFS_SUPPORTS_DEFAULT
|
||||||
|
#endif
|
||||||
|
#ifndef PHYSFS_SUPPORTS_VDF
|
||||||
|
#define PHYSFS_SUPPORTS_VDF PHYSFS_SUPPORTS_DEFAULT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PHYSFS_SUPPORTS_7Z
|
||||||
|
/* 7zip support needs a global init function called at startup (no deinit). */
|
||||||
|
extern void SZIP_global_init(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The latest supported PHYSFS_Io::version value. */
|
||||||
|
#define CURRENT_PHYSFS_IO_API_VERSION 0
|
||||||
|
|
||||||
|
/* The latest supported PHYSFS_Archiver::version value. */
|
||||||
|
#define CURRENT_PHYSFS_ARCHIVER_API_VERSION 0
|
||||||
|
|
||||||
|
/* This byteorder stuff was lifted from SDL. https://www.libsdl.org/ */
|
||||||
|
#define PHYSFS_LIL_ENDIAN 1234
|
||||||
|
#define PHYSFS_BIG_ENDIAN 4321
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <endian.h>
|
||||||
|
#define PHYSFS_BYTEORDER __BYTE_ORDER
|
||||||
|
#else /* __linux__ */
|
||||||
|
#if defined(__hppa__) || \
|
||||||
|
defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
|
||||||
|
(defined(__MIPS__) && defined(__MISPEB__)) || \
|
||||||
|
defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
|
||||||
|
defined(__sparc__)
|
||||||
|
#define PHYSFS_BYTEORDER PHYSFS_BIG_ENDIAN
|
||||||
|
#else
|
||||||
|
#define PHYSFS_BYTEORDER PHYSFS_LIL_ENDIAN
|
||||||
|
#endif
|
||||||
|
#endif /* __linux__ */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When sorting the entries in an archive, we use a modified QuickSort.
|
||||||
|
* When there are less then PHYSFS_QUICKSORT_THRESHOLD entries left to sort,
|
||||||
|
* we switch over to a BubbleSort for the remainder. Tweak to taste.
|
||||||
|
*
|
||||||
|
* You can override this setting by defining PHYSFS_QUICKSORT_THRESHOLD
|
||||||
|
* before #including "physfs_internal.h".
|
||||||
|
*/
|
||||||
|
#ifndef PHYSFS_QUICKSORT_THRESHOLD
|
||||||
|
#define PHYSFS_QUICKSORT_THRESHOLD 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sort an array (or whatever) of (max) elements. This uses a mixture of
|
||||||
|
* a QuickSort and BubbleSort internally.
|
||||||
|
* (cmpfn) is used to determine ordering, and (swapfn) does the actual
|
||||||
|
* swapping of elements in the list.
|
||||||
|
*/
|
||||||
|
void __PHYSFS_sort(void *entries, size_t max,
|
||||||
|
int (*cmpfn)(void *, size_t, size_t),
|
||||||
|
void (*swapfn)(void *, size_t, size_t));
|
||||||
|
|
||||||
|
/* These get used all over for lessening code clutter. */
|
||||||
|
/* "ERRPASS" means "something else just set the error state for us" and is
|
||||||
|
just to make it clear where the responsibility for the error state lays. */
|
||||||
|
#define BAIL(e, r) do { if (e) PHYSFS_setErrorCode(e); return r; } while (0)
|
||||||
|
#define BAIL_ERRPASS(r) do { return r; } while (0)
|
||||||
|
#define BAIL_IF(c, e, r) do { if (c) { if (e) PHYSFS_setErrorCode(e); return r; } } while (0)
|
||||||
|
#define BAIL_IF_ERRPASS(c, r) do { if (c) { return r; } } while (0)
|
||||||
|
#define BAIL_MUTEX(e, m, r) do { if (e) PHYSFS_setErrorCode(e); __PHYSFS_platformReleaseMutex(m); return r; } while (0)
|
||||||
|
#define BAIL_MUTEX_ERRPASS(m, r) do { __PHYSFS_platformReleaseMutex(m); return r; } while (0)
|
||||||
|
#define BAIL_IF_MUTEX(c, e, m, r) do { if (c) { if (e) PHYSFS_setErrorCode(e); __PHYSFS_platformReleaseMutex(m); return r; } } while (0)
|
||||||
|
#define BAIL_IF_MUTEX_ERRPASS(c, m, r) do { if (c) { __PHYSFS_platformReleaseMutex(m); return r; } } while (0)
|
||||||
|
#define GOTO(e, g) do { if (e) PHYSFS_setErrorCode(e); goto g; } while (0)
|
||||||
|
#define GOTO_ERRPASS(g) do { goto g; } while (0)
|
||||||
|
#define GOTO_IF(c, e, g) do { if (c) { if (e) PHYSFS_setErrorCode(e); goto g; } } while (0)
|
||||||
|
#define GOTO_IF_ERRPASS(c, g) do { if (c) { goto g; } } while (0)
|
||||||
|
#define GOTO_MUTEX(e, m, g) do { if (e) PHYSFS_setErrorCode(e); __PHYSFS_platformReleaseMutex(m); goto g; } while (0)
|
||||||
|
#define GOTO_MUTEX_ERRPASS(m, g) do { __PHYSFS_platformReleaseMutex(m); goto g; } while (0)
|
||||||
|
#define GOTO_IF_MUTEX(c, e, m, g) do { if (c) { if (e) PHYSFS_setErrorCode(e); __PHYSFS_platformReleaseMutex(m); goto g; } } while (0)
|
||||||
|
#define GOTO_IF_MUTEX_ERRPASS(c, m, g) do { if (c) { __PHYSFS_platformReleaseMutex(m); goto g; } } while (0)
|
||||||
|
|
||||||
|
#define __PHYSFS_ARRAYLEN(x) ( (sizeof (x)) / (sizeof (x[0])) )
|
||||||
|
|
||||||
|
#ifdef PHYSFS_NO_64BIT_SUPPORT
|
||||||
|
#define __PHYSFS_SI64(x) ((PHYSFS_sint64) (x))
|
||||||
|
#define __PHYSFS_UI64(x) ((PHYSFS_uint64) (x))
|
||||||
|
#elif (defined __GNUC__)
|
||||||
|
#define __PHYSFS_SI64(x) x##LL
|
||||||
|
#define __PHYSFS_UI64(x) x##ULL
|
||||||
|
#elif (defined _MSC_VER)
|
||||||
|
#define __PHYSFS_SI64(x) x##i64
|
||||||
|
#define __PHYSFS_UI64(x) x##ui64
|
||||||
|
#else
|
||||||
|
#define __PHYSFS_SI64(x) ((PHYSFS_sint64) (x))
|
||||||
|
#define __PHYSFS_UI64(x) ((PHYSFS_uint64) (x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if a ui64 will fit in the platform's address space.
|
||||||
|
* The initial sizeof check will optimize this macro out entirely on
|
||||||
|
* 64-bit (and larger?!) platforms, and the other condition will
|
||||||
|
* return zero or non-zero if the variable will fit in the platform's
|
||||||
|
* size_t, suitable to pass to malloc. This is kinda messy, but effective.
|
||||||
|
*/
|
||||||
|
#define __PHYSFS_ui64FitsAddressSpace(s) ( \
|
||||||
|
(sizeof (PHYSFS_uint64) <= sizeof (size_t)) || \
|
||||||
|
((s) < (__PHYSFS_UI64(0xFFFFFFFFFFFFFFFF) >> (64-(sizeof(size_t)*8)))) \
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like strdup(), but uses the current PhysicsFS allocator.
|
||||||
|
*/
|
||||||
|
char *__PHYSFS_strdup(const char *str);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Give a hash value for a C string (uses djb's xor hashing algorithm).
|
||||||
|
*/
|
||||||
|
PHYSFS_uint32 __PHYSFS_hashString(const char *str, size_t len);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The current allocator. Not valid before PHYSFS_init is called!
|
||||||
|
*/
|
||||||
|
extern PHYSFS_Allocator __PHYSFS_AllocatorHooks;
|
||||||
|
|
||||||
|
/* convenience macro to make this less cumbersome internally... */
|
||||||
|
#define allocator __PHYSFS_AllocatorHooks
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a PHYSFS_Io for a file in the physical filesystem.
|
||||||
|
* This path is in platform-dependent notation. (mode) must be 'r', 'w', or
|
||||||
|
* 'a' for Read, Write, or Append.
|
||||||
|
*/
|
||||||
|
PHYSFS_Io *__PHYSFS_createNativeIo(const char *path, const int mode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a PHYSFS_Io for a buffer of memory (READ-ONLY). If you already
|
||||||
|
* have one of these, just use its duplicate() method, and it'll increment
|
||||||
|
* its refcount without allocating a copy of the buffer.
|
||||||
|
*/
|
||||||
|
PHYSFS_Io *__PHYSFS_createMemoryIo(const void *buf, PHYSFS_uint64 len,
|
||||||
|
void (*destruct)(void *));
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read (len) bytes from (io) into (buf). Returns non-zero on success,
|
||||||
|
* zero on i/o error. Literally: "return (io->read(io, buf, len) == len);"
|
||||||
|
*/
|
||||||
|
int __PHYSFS_readAll(PHYSFS_Io *io, void *buf, const size_t len);
|
||||||
|
|
||||||
|
|
||||||
|
/* These are shared between some archivers. */
|
||||||
|
|
||||||
|
void UNPK_abandonArchive(void *opaque);
|
||||||
|
void UNPK_closeArchive(void *opaque);
|
||||||
|
void *UNPK_openArchive(PHYSFS_Io *io);
|
||||||
|
void *UNPK_addEntry(void *opaque, char *name, const int isdir,
|
||||||
|
const PHYSFS_sint64 ctime, const PHYSFS_sint64 mtime,
|
||||||
|
const PHYSFS_uint64 pos, const PHYSFS_uint64 len);
|
||||||
|
PHYSFS_Io *UNPK_openRead(void *opaque, const char *name);
|
||||||
|
PHYSFS_Io *UNPK_openWrite(void *opaque, const char *name);
|
||||||
|
PHYSFS_Io *UNPK_openAppend(void *opaque, const char *name);
|
||||||
|
int UNPK_remove(void *opaque, const char *name);
|
||||||
|
int UNPK_mkdir(void *opaque, const char *name);
|
||||||
|
int UNPK_stat(void *opaque, const char *fn, PHYSFS_Stat *st);
|
||||||
|
#define UNPK_enumerate __PHYSFS_DirTreeEnumerate
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Optional API many archivers use this to manage their directory tree. */
|
||||||
|
/* !!! FIXME: document this better. */
|
||||||
|
|
||||||
|
typedef struct __PHYSFS_DirTreeEntry
|
||||||
|
{
|
||||||
|
char *name; /* Full path in archive. */
|
||||||
|
struct __PHYSFS_DirTreeEntry *hashnext; /* next item in hash bucket. */
|
||||||
|
struct __PHYSFS_DirTreeEntry *children; /* linked list of kids, if dir. */
|
||||||
|
struct __PHYSFS_DirTreeEntry *sibling; /* next item in same dir. */
|
||||||
|
int isdir;
|
||||||
|
} __PHYSFS_DirTreeEntry;
|
||||||
|
|
||||||
|
typedef struct __PHYSFS_DirTree
|
||||||
|
{
|
||||||
|
__PHYSFS_DirTreeEntry *root; /* root of directory tree. */
|
||||||
|
__PHYSFS_DirTreeEntry **hash; /* all entries hashed for fast lookup. */
|
||||||
|
size_t hashBuckets; /* number of buckets in hash. */
|
||||||
|
size_t entrylen; /* size in bytes of entries (including subclass). */
|
||||||
|
} __PHYSFS_DirTree;
|
||||||
|
|
||||||
|
|
||||||
|
int __PHYSFS_DirTreeInit(__PHYSFS_DirTree *dt, const size_t entrylen);
|
||||||
|
void *__PHYSFS_DirTreeAdd(__PHYSFS_DirTree *dt, char *name, const int isdir);
|
||||||
|
void *__PHYSFS_DirTreeFind(__PHYSFS_DirTree *dt, const char *path);
|
||||||
|
PHYSFS_EnumerateCallbackResult __PHYSFS_DirTreeEnumerate(void *opaque,
|
||||||
|
const char *dname, PHYSFS_EnumerateCallback cb,
|
||||||
|
const char *origdir, void *callbackdata);
|
||||||
|
void __PHYSFS_DirTreeDeinit(__PHYSFS_DirTree *dt);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/*------------ ----------------*/
|
||||||
|
/*------------ You MUST implement the following functions ----------------*/
|
||||||
|
/*------------ if porting to a new platform. ----------------*/
|
||||||
|
/*------------ (see platform/unix.c for an example) ----------------*/
|
||||||
|
/*------------ ----------------*/
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The dir separator; '/' on unix, '\\' on win32, ":" on MacOS, etc...
|
||||||
|
* Obviously, this isn't a function. If you need more than one char for this,
|
||||||
|
* you'll need to pull some old pieces of PhysicsFS out of revision control.
|
||||||
|
*/
|
||||||
|
#if defined(PHYSFS_PLATFORM_WINDOWS) || defined(PHYSFS_PLATFORM_OS2)
|
||||||
|
#define __PHYSFS_platformDirSeparator '\\'
|
||||||
|
#else
|
||||||
|
#define __PHYSFS_STANDARD_DIRSEP 1
|
||||||
|
#define __PHYSFS_platformDirSeparator '/'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the platform. This is called when PHYSFS_init() is called from
|
||||||
|
* the application.
|
||||||
|
*
|
||||||
|
* Return zero if there was a catastrophic failure (which prevents you from
|
||||||
|
* functioning at all), and non-zero otherwise.
|
||||||
|
*/
|
||||||
|
int __PHYSFS_platformInit(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deinitialize the platform. This is called when PHYSFS_deinit() is called
|
||||||
|
* from the application. You can use this to clean up anything you've
|
||||||
|
* allocated in your platform driver.
|
||||||
|
*/
|
||||||
|
void __PHYSFS_platformDeinit(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open a file for reading. (filename) is in platform-dependent notation. The
|
||||||
|
* file pointer should be positioned on the first byte of the file.
|
||||||
|
*
|
||||||
|
* The return value will be some platform-specific datatype that is opaque to
|
||||||
|
* the caller; it could be a (FILE *) under Unix, or a (HANDLE *) under win32.
|
||||||
|
*
|
||||||
|
* The same file can be opened for read multiple times, and each should have
|
||||||
|
* a unique file handle; this is frequently employed to prevent race
|
||||||
|
* conditions in the archivers.
|
||||||
|
*
|
||||||
|
* Call PHYSFS_setErrorCode() and return (NULL) if the file can't be opened.
|
||||||
|
*/
|
||||||
|
void *__PHYSFS_platformOpenRead(const char *filename);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open a file for writing. (filename) is in platform-dependent notation. If
|
||||||
|
* the file exists, it should be truncated to zero bytes, and if it doesn't
|
||||||
|
* exist, it should be created as a zero-byte file. The file pointer should
|
||||||
|
* be positioned on the first byte of the file.
|
||||||
|
*
|
||||||
|
* The return value will be some platform-specific datatype that is opaque to
|
||||||
|
* the caller; it could be a (FILE *) under Unix, or a (HANDLE *) under win32,
|
||||||
|
* etc.
|
||||||
|
*
|
||||||
|
* Opening a file for write multiple times has undefined results.
|
||||||
|
*
|
||||||
|
* Call PHYSFS_setErrorCode() and return (NULL) if the file can't be opened.
|
||||||
|
*/
|
||||||
|
void *__PHYSFS_platformOpenWrite(const char *filename);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open a file for appending. (filename) is in platform-dependent notation. If
|
||||||
|
* the file exists, the file pointer should be place just past the end of the
|
||||||
|
* file, so that the first write will be one byte after the current end of
|
||||||
|
* the file. If the file doesn't exist, it should be created as a zero-byte
|
||||||
|
* file. The file pointer should be positioned on the first byte of the file.
|
||||||
|
*
|
||||||
|
* The return value will be some platform-specific datatype that is opaque to
|
||||||
|
* the caller; it could be a (FILE *) under Unix, or a (HANDLE *) under win32,
|
||||||
|
* etc.
|
||||||
|
*
|
||||||
|
* Opening a file for append multiple times has undefined results.
|
||||||
|
*
|
||||||
|
* Call PHYSFS_setErrorCode() and return (NULL) if the file can't be opened.
|
||||||
|
*/
|
||||||
|
void *__PHYSFS_platformOpenAppend(const char *filename);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read more data from a platform-specific file handle. (opaque) should be
|
||||||
|
* cast to whatever data type your platform uses. Read a maximum of (len)
|
||||||
|
* 8-bit bytes to the area pointed to by (buf). If there isn't enough data
|
||||||
|
* available, return the number of bytes read, and position the file pointer
|
||||||
|
* immediately after those bytes.
|
||||||
|
* On success, return (len) and position the file pointer immediately past
|
||||||
|
* the end of the last read byte. Return (-1) if there is a catastrophic
|
||||||
|
* error, and call PHYSFS_setErrorCode() to describe the problem; the file
|
||||||
|
* pointer should not move in such a case. A partial read is success; only
|
||||||
|
* return (-1) on total failure; presumably, the next read call after a
|
||||||
|
* partial read will fail as such.
|
||||||
|
*/
|
||||||
|
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buf, PHYSFS_uint64 len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write more data to a platform-specific file handle. (opaque) should be
|
||||||
|
* cast to whatever data type your platform uses. Write a maximum of (len)
|
||||||
|
* 8-bit bytes from the area pointed to by (buffer). If there is a problem,
|
||||||
|
* return the number of bytes written, and position the file pointer
|
||||||
|
* immediately after those bytes. Return (-1) if there is a catastrophic
|
||||||
|
* error, and call PHYSFS_setErrorCode() to describe the problem; the file
|
||||||
|
* pointer should not move in such a case. A partial write is success; only
|
||||||
|
* return (-1) on total failure; presumably, the next write call after a
|
||||||
|
* partial write will fail as such.
|
||||||
|
*/
|
||||||
|
PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
|
||||||
|
PHYSFS_uint64 len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the file pointer to a new position. (opaque) should be cast to
|
||||||
|
* whatever data type your platform uses. (pos) specifies the number
|
||||||
|
* of 8-bit bytes to seek to from the start of the file. Seeking past the
|
||||||
|
* end of the file is an error condition, and you should check for it.
|
||||||
|
*
|
||||||
|
* Not all file types can seek; this is to be expected by the caller.
|
||||||
|
*
|
||||||
|
* On error, call PHYSFS_setErrorCode() and return zero. On success, return
|
||||||
|
* a non-zero value.
|
||||||
|
*/
|
||||||
|
int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the file pointer's position, in an 8-bit byte offset from the start of
|
||||||
|
* the file. (opaque) should be cast to whatever data type your platform
|
||||||
|
* uses.
|
||||||
|
*
|
||||||
|
* Not all file types can "tell"; this is to be expected by the caller.
|
||||||
|
*
|
||||||
|
* On error, call PHYSFS_setErrorCode() and return -1. On success, return >= 0.
|
||||||
|
*/
|
||||||
|
PHYSFS_sint64 __PHYSFS_platformTell(void *opaque);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine the current size of a file, in 8-bit bytes, from an open file.
|
||||||
|
*
|
||||||
|
* The caller expects that this information may not be available for all
|
||||||
|
* file types on all platforms.
|
||||||
|
*
|
||||||
|
* Return -1 if you can't do it, and call PHYSFS_setErrorCode(). Otherwise,
|
||||||
|
* return the file length in 8-bit bytes.
|
||||||
|
*/
|
||||||
|
PHYSFS_sint64 __PHYSFS_platformFileLength(void *handle);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read filesystem metadata for a specific path.
|
||||||
|
*
|
||||||
|
* This needs to fill in all the fields of (stat). For fields that might not
|
||||||
|
* mean anything on a platform (access time, perhaps), choose a reasonable
|
||||||
|
* default. if (follow), we want to follow symlinks and stat what they
|
||||||
|
* link to and not the link itself.
|
||||||
|
*
|
||||||
|
* Return zero on failure, non-zero on success.
|
||||||
|
*/
|
||||||
|
int __PHYSFS_platformStat(const char *fn, PHYSFS_Stat *stat, const int follow);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flush any pending writes to disk. (opaque) should be cast to whatever data
|
||||||
|
* type your platform uses. Be sure to check for errors; the caller expects
|
||||||
|
* that this function can fail if there was a flushing error, etc.
|
||||||
|
*
|
||||||
|
* Return zero on failure, non-zero on success.
|
||||||
|
*/
|
||||||
|
int __PHYSFS_platformFlush(void *opaque);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close file and deallocate resources. (opaque) should be cast to whatever
|
||||||
|
* data type your platform uses. This should close the file in any scenario:
|
||||||
|
* flushing is a separate function call, and this function should never fail.
|
||||||
|
*
|
||||||
|
* You should clean up all resources associated with (opaque); the pointer
|
||||||
|
* will be considered invalid after this call.
|
||||||
|
*/
|
||||||
|
void __PHYSFS_platformClose(void *opaque);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Platform implementation of PHYSFS_getCdRomDirsCallback()...
|
||||||
|
* CD directories are discovered and reported to the callback one at a time.
|
||||||
|
* Pointers passed to the callback are assumed to be invalid to the
|
||||||
|
* application after the callback returns, so you can free them or whatever.
|
||||||
|
* Callback does not assume results will be sorted in any meaningful way.
|
||||||
|
*/
|
||||||
|
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the base dir, if your platform needs special consideration.
|
||||||
|
* Just return NULL if the standard routines will suffice. (see
|
||||||
|
* calculateBaseDir() in physfs.c ...)
|
||||||
|
* Your string must end with a dir separator if you don't return NULL.
|
||||||
|
* Caller will allocator.Free() the retval if it's not NULL.
|
||||||
|
*/
|
||||||
|
char *__PHYSFS_platformCalcBaseDir(const char *argv0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the platform-specific user dir.
|
||||||
|
* As of PhysicsFS 2.1, returning NULL means fatal error.
|
||||||
|
* Your string must end with a dir separator if you don't return NULL.
|
||||||
|
* Caller will allocator.Free() the retval if it's not NULL.
|
||||||
|
*/
|
||||||
|
char *__PHYSFS_platformCalcUserDir(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the cached version from PHYSFS_init(). This is a fast call. */
|
||||||
|
const char *__PHYSFS_getUserDir(void); /* not deprecated internal version. */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the platform-specific pref dir.
|
||||||
|
* Returning NULL means fatal error.
|
||||||
|
* Your string must end with a dir separator if you don't return NULL.
|
||||||
|
* Caller will allocator.Free() the retval if it's not NULL.
|
||||||
|
* Caller will make missing directories if necessary; this just reports
|
||||||
|
* the final path.
|
||||||
|
*/
|
||||||
|
char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a pointer that uniquely identifies the current thread.
|
||||||
|
* On a platform without threading, (0x1) will suffice. These numbers are
|
||||||
|
* arbitrary; the only requirement is that no two threads have the same
|
||||||
|
* pointer.
|
||||||
|
*/
|
||||||
|
void *__PHYSFS_platformGetThreadID(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enumerate a directory of files. This follows the rules for the
|
||||||
|
* PHYSFS_Archiver::enumerate() method, except that the (dirName) that is
|
||||||
|
* passed to this function is converted to platform-DEPENDENT notation by
|
||||||
|
* the caller. The PHYSFS_Archiver version uses platform-independent
|
||||||
|
* notation. Note that ".", "..", and other meta-entries should always
|
||||||
|
* be ignored.
|
||||||
|
*/
|
||||||
|
PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname,
|
||||||
|
PHYSFS_EnumerateCallback callback,
|
||||||
|
const char *origdir, void *callbackdata);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make a directory in the actual filesystem. (path) is specified in
|
||||||
|
* platform-dependent notation. On error, return zero and set the error
|
||||||
|
* message. Return non-zero on success.
|
||||||
|
*/
|
||||||
|
int __PHYSFS_platformMkDir(const char *path);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove a file or directory entry in the actual filesystem. (path) is
|
||||||
|
* specified in platform-dependent notation. Note that this deletes files
|
||||||
|
* _and_ directories, so you might need to do some determination.
|
||||||
|
* Non-empty directories should report an error and not delete themselves
|
||||||
|
* or their contents.
|
||||||
|
*
|
||||||
|
* Deleting a symlink should remove the link, not what it points to.
|
||||||
|
*
|
||||||
|
* On error, return zero and set the error message. Return non-zero on success.
|
||||||
|
*/
|
||||||
|
int __PHYSFS_platformDelete(const char *path);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a platform-specific mutex. This can be whatever datatype your
|
||||||
|
* platform uses for mutexes, but it is cast to a (void *) for abstractness.
|
||||||
|
*
|
||||||
|
* Return (NULL) if you couldn't create one. Systems without threads can
|
||||||
|
* return any arbitrary non-NULL value.
|
||||||
|
*/
|
||||||
|
void *__PHYSFS_platformCreateMutex(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destroy a platform-specific mutex, and clean up any resources associated
|
||||||
|
* with it. (mutex) is a value previously returned by
|
||||||
|
* __PHYSFS_platformCreateMutex(). This can be a no-op on single-threaded
|
||||||
|
* platforms.
|
||||||
|
*/
|
||||||
|
void __PHYSFS_platformDestroyMutex(void *mutex);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Grab possession of a platform-specific mutex. Mutexes should be recursive;
|
||||||
|
* that is, the same thread should be able to call this function multiple
|
||||||
|
* times in a row without causing a deadlock. This function should block
|
||||||
|
* until a thread can gain possession of the mutex.
|
||||||
|
*
|
||||||
|
* Return non-zero if the mutex was grabbed, zero if there was an
|
||||||
|
* unrecoverable problem grabbing it (this should not be a matter of
|
||||||
|
* timing out! We're talking major system errors; block until the mutex
|
||||||
|
* is available otherwise.)
|
||||||
|
*
|
||||||
|
* _DO NOT_ call PHYSFS_setErrorCode() in here! Since setErrorCode calls this
|
||||||
|
* function, you'll cause an infinite recursion. This means you can't
|
||||||
|
* use the BAIL_*MACRO* macros, either.
|
||||||
|
*/
|
||||||
|
int __PHYSFS_platformGrabMutex(void *mutex);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Relinquish possession of the mutex when this method has been called
|
||||||
|
* once for each time that platformGrabMutex was called. Once possession has
|
||||||
|
* been released, the next thread in line to grab the mutex (if any) may
|
||||||
|
* proceed.
|
||||||
|
*
|
||||||
|
* _DO NOT_ call PHYSFS_setErrorCode() in here! Since setErrorCode calls this
|
||||||
|
* function, you'll cause an infinite recursion. This means you can't
|
||||||
|
* use the BAIL_*MACRO* macros, either.
|
||||||
|
*/
|
||||||
|
void __PHYSFS_platformReleaseMutex(void *mutex);
|
||||||
|
|
||||||
|
#if PHYSFS_HAVE_PRAGMA_VISIBILITY
|
||||||
|
#pragma GCC visibility pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* end of physfs_internal.h ... */
|
||||||
|
|
||||||
701
desktop_version/physfs/physfs_miniz.h
Normal file
701
desktop_version/physfs/physfs_miniz.h
Normal file
@@ -0,0 +1,701 @@
|
|||||||
|
/* tinfl.c v1.11 - public domain inflate with zlib header parsing/adler32 checking (inflate-only subset of miniz.c)
|
||||||
|
See "unlicense" statement at the end of this file.
|
||||||
|
Rich Geldreich <richgel99@gmail.com>, last updated May 20, 2011
|
||||||
|
Implements RFC 1950: https://www.ietf.org/rfc/rfc1950.txt and RFC 1951: https://www.ietf.org/rfc/rfc1951.txt
|
||||||
|
|
||||||
|
The entire decompressor coroutine is implemented in tinfl_decompress(). The other functions are optional high-level helpers.
|
||||||
|
*/
|
||||||
|
#ifndef TINFL_HEADER_INCLUDED
|
||||||
|
#define TINFL_HEADER_INCLUDED
|
||||||
|
|
||||||
|
typedef PHYSFS_uint8 mz_uint8;
|
||||||
|
typedef PHYSFS_sint16 mz_int16;
|
||||||
|
typedef PHYSFS_uint16 mz_uint16;
|
||||||
|
typedef PHYSFS_uint32 mz_uint32;
|
||||||
|
typedef unsigned int mz_uint;
|
||||||
|
typedef PHYSFS_uint64 mz_uint64;
|
||||||
|
|
||||||
|
/* For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. */
|
||||||
|
typedef unsigned long mz_ulong;
|
||||||
|
|
||||||
|
/* Heap allocation callbacks. */
|
||||||
|
typedef void *(*mz_alloc_func)(void *opaque, unsigned int items, unsigned int size);
|
||||||
|
typedef void (*mz_free_func)(void *opaque, void *address);
|
||||||
|
|
||||||
|
#if defined(_M_IX86) || defined(_M_X64)
|
||||||
|
/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 if integer loads and stores to unaligned addresses are acceptable on the target platform (slightly faster). */
|
||||||
|
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
|
||||||
|
/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */
|
||||||
|
#define MINIZ_LITTLE_ENDIAN 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__)
|
||||||
|
/* Set MINIZ_HAS_64BIT_REGISTERS to 1 if the processor has 64-bit general purpose registers (enables 64-bit bitbuffer in inflator) */
|
||||||
|
#define MINIZ_HAS_64BIT_REGISTERS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Works around MSVC's spammy "warning C4127: conditional expression is constant" message. */
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define MZ_MACRO_END while (0, 0)
|
||||||
|
#else
|
||||||
|
#define MZ_MACRO_END while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Decompression flags. */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
|
||||||
|
TINFL_FLAG_HAS_MORE_INPUT = 2,
|
||||||
|
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
|
||||||
|
TINFL_FLAG_COMPUTE_ADLER32 = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor;
|
||||||
|
|
||||||
|
/* Max size of LZ dictionary. */
|
||||||
|
#define TINFL_LZ_DICT_SIZE 32768
|
||||||
|
|
||||||
|
/* Return status. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TINFL_STATUS_BAD_PARAM = -3,
|
||||||
|
TINFL_STATUS_ADLER32_MISMATCH = -2,
|
||||||
|
TINFL_STATUS_FAILED = -1,
|
||||||
|
TINFL_STATUS_DONE = 0,
|
||||||
|
TINFL_STATUS_NEEDS_MORE_INPUT = 1,
|
||||||
|
TINFL_STATUS_HAS_MORE_OUTPUT = 2
|
||||||
|
} tinfl_status;
|
||||||
|
|
||||||
|
/* Initializes the decompressor to its initial state. */
|
||||||
|
#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
|
||||||
|
#define tinfl_get_adler32(r) (r)->m_check_adler32
|
||||||
|
|
||||||
|
/* Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. */
|
||||||
|
/* This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. */
|
||||||
|
static tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
|
||||||
|
|
||||||
|
/* Internal/private bits follow. */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19,
|
||||||
|
TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
|
||||||
|
mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
|
||||||
|
} tinfl_huff_table;
|
||||||
|
|
||||||
|
#if MINIZ_HAS_64BIT_REGISTERS
|
||||||
|
#define TINFL_USE_64BIT_BITBUF 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TINFL_USE_64BIT_BITBUF
|
||||||
|
typedef mz_uint64 tinfl_bit_buf_t;
|
||||||
|
#define TINFL_BITBUF_SIZE (64)
|
||||||
|
#else
|
||||||
|
typedef mz_uint32 tinfl_bit_buf_t;
|
||||||
|
#define TINFL_BITBUF_SIZE (32)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct tinfl_decompressor_tag
|
||||||
|
{
|
||||||
|
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
|
||||||
|
tinfl_bit_buf_t m_bit_buf;
|
||||||
|
size_t m_dist_from_out_buf_start;
|
||||||
|
tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
|
||||||
|
mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* #ifdef TINFL_HEADER_INCLUDED */
|
||||||
|
|
||||||
|
/* ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.) */
|
||||||
|
|
||||||
|
#ifndef TINFL_HEADER_FILE_ONLY
|
||||||
|
|
||||||
|
#define MZ_MAX(a,b) (((a)>(b))?(a):(b))
|
||||||
|
#define MZ_MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
|
#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
|
||||||
|
|
||||||
|
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
|
||||||
|
#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
|
||||||
|
#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
|
||||||
|
#else
|
||||||
|
#define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
|
||||||
|
#define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
|
||||||
|
#define TINFL_MEMSET(p, c, l) memset(p, c, l)
|
||||||
|
|
||||||
|
#define TINFL_CR_BEGIN switch(r->m_state) { case 0:
|
||||||
|
#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
|
||||||
|
#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
|
||||||
|
#define TINFL_CR_FINISH }
|
||||||
|
|
||||||
|
/* TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never */
|
||||||
|
/* reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario. */
|
||||||
|
#define TINFL_GET_BYTE(state_index, c) do { \
|
||||||
|
if (pIn_buf_cur >= pIn_buf_end) { \
|
||||||
|
for ( ; ; ) { \
|
||||||
|
if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
|
||||||
|
TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
|
||||||
|
if (pIn_buf_cur < pIn_buf_end) { \
|
||||||
|
c = *pIn_buf_cur++; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} else { \
|
||||||
|
c = 0; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} else c = *pIn_buf_cur++; } MZ_MACRO_END
|
||||||
|
|
||||||
|
#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n))
|
||||||
|
#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
|
||||||
|
#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
|
||||||
|
|
||||||
|
/* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */
|
||||||
|
/* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */
|
||||||
|
/* Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the */
|
||||||
|
/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
|
||||||
|
#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
|
||||||
|
do { \
|
||||||
|
temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
|
||||||
|
if (temp >= 0) { \
|
||||||
|
code_len = temp >> 9; \
|
||||||
|
if ((code_len) && (num_bits >= code_len)) \
|
||||||
|
break; \
|
||||||
|
} else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
|
||||||
|
code_len = TINFL_FAST_LOOKUP_BITS; \
|
||||||
|
do { \
|
||||||
|
temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
|
||||||
|
} while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
|
||||||
|
} TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
|
||||||
|
} while (num_bits < 15);
|
||||||
|
|
||||||
|
/* TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read */
|
||||||
|
/* beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully */
|
||||||
|
/* decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. */
|
||||||
|
/* The slow path is only executed at the very end of the input buffer. */
|
||||||
|
#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
|
||||||
|
int temp; mz_uint code_len, c; \
|
||||||
|
if (num_bits < 15) { \
|
||||||
|
if ((pIn_buf_end - pIn_buf_cur) < 2) { \
|
||||||
|
TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
|
||||||
|
} else { \
|
||||||
|
bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
|
||||||
|
code_len = temp >> 9, temp &= 511; \
|
||||||
|
else { \
|
||||||
|
code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
|
||||||
|
} sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
|
||||||
|
|
||||||
|
static tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags)
|
||||||
|
{
|
||||||
|
static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 };
|
||||||
|
static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 };
|
||||||
|
static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0};
|
||||||
|
static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
|
||||||
|
static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
|
||||||
|
static const int s_min_table_sizes[3] = { 257, 1, 4 };
|
||||||
|
|
||||||
|
tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf;
|
||||||
|
const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
|
||||||
|
mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
|
||||||
|
size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start;
|
||||||
|
|
||||||
|
/* Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). */
|
||||||
|
if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; }
|
||||||
|
|
||||||
|
num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start;
|
||||||
|
TINFL_CR_BEGIN
|
||||||
|
|
||||||
|
bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1;
|
||||||
|
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
|
||||||
|
{
|
||||||
|
TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1);
|
||||||
|
counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
|
||||||
|
if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
|
||||||
|
if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); }
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1;
|
||||||
|
if (r->m_type == 0)
|
||||||
|
{
|
||||||
|
TINFL_SKIP_BITS(5, num_bits & 7);
|
||||||
|
for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); }
|
||||||
|
if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); }
|
||||||
|
while ((counter) && (num_bits))
|
||||||
|
{
|
||||||
|
TINFL_GET_BITS(51, dist, 8);
|
||||||
|
while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); }
|
||||||
|
*pOut_buf_cur++ = (mz_uint8)dist;
|
||||||
|
counter--;
|
||||||
|
}
|
||||||
|
while (counter)
|
||||||
|
{
|
||||||
|
size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
|
||||||
|
while (pIn_buf_cur >= pIn_buf_end)
|
||||||
|
{
|
||||||
|
if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
|
||||||
|
TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (r->m_type == 3)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (r->m_type == 1)
|
||||||
|
{
|
||||||
|
mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i;
|
||||||
|
r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
|
||||||
|
for ( i = 0; i <= 143; ++i) *p++ = 8;
|
||||||
|
for ( ; i <= 255; ++i) *p++ = 9;
|
||||||
|
for ( ; i <= 279; ++i) *p++ = 7;
|
||||||
|
for ( ; i <= 287; ++i) *p++ = 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; }
|
||||||
|
MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; }
|
||||||
|
r->m_table_sizes[2] = 19;
|
||||||
|
}
|
||||||
|
for ( ; (int)r->m_type >= 0; r->m_type--)
|
||||||
|
{
|
||||||
|
int tree_next, tree_cur; tinfl_huff_table *pTable;
|
||||||
|
mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree);
|
||||||
|
for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++;
|
||||||
|
used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
|
||||||
|
for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }
|
||||||
|
if ((65536 != total) && (used_syms > 1))
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
|
||||||
|
{
|
||||||
|
mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue;
|
||||||
|
cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1);
|
||||||
|
if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; }
|
||||||
|
if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; }
|
||||||
|
rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
|
||||||
|
for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
|
||||||
|
{
|
||||||
|
tree_cur -= ((rev_code >>= 1) & 1);
|
||||||
|
if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1];
|
||||||
|
}
|
||||||
|
tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
|
||||||
|
}
|
||||||
|
if (r->m_type == 2)
|
||||||
|
{
|
||||||
|
for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); )
|
||||||
|
{
|
||||||
|
mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; }
|
||||||
|
if ((dist == 16) && (!counter))
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16];
|
||||||
|
TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s;
|
||||||
|
}
|
||||||
|
if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( ; ; )
|
||||||
|
{
|
||||||
|
mz_uint8 *pSrc;
|
||||||
|
for ( ; ; )
|
||||||
|
{
|
||||||
|
if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
|
||||||
|
{
|
||||||
|
TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
|
||||||
|
if (counter >= 256)
|
||||||
|
break;
|
||||||
|
while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); }
|
||||||
|
*pOut_buf_cur++ = (mz_uint8)counter;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int sym2; mz_uint code_len;
|
||||||
|
#if TINFL_USE_64BIT_BITBUF
|
||||||
|
if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; }
|
||||||
|
#else
|
||||||
|
if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
|
||||||
|
#endif
|
||||||
|
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
|
||||||
|
code_len = sym2 >> 9;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
|
||||||
|
}
|
||||||
|
counter = sym2; bit_buf >>= code_len; num_bits -= code_len;
|
||||||
|
if (counter & 256)
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if !TINFL_USE_64BIT_BITBUF
|
||||||
|
if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
|
||||||
|
#endif
|
||||||
|
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
|
||||||
|
code_len = sym2 >> 9;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
|
||||||
|
}
|
||||||
|
bit_buf >>= code_len; num_bits -= code_len;
|
||||||
|
|
||||||
|
pOut_buf_cur[0] = (mz_uint8)counter;
|
||||||
|
if (sym2 & 256)
|
||||||
|
{
|
||||||
|
pOut_buf_cur++;
|
||||||
|
counter = sym2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pOut_buf_cur[1] = (mz_uint8)sym2;
|
||||||
|
pOut_buf_cur += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((counter &= 511) == 256) break;
|
||||||
|
|
||||||
|
num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257];
|
||||||
|
if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; }
|
||||||
|
|
||||||
|
TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
|
||||||
|
num_extra = s_dist_extra[dist]; dist = s_dist_base[dist];
|
||||||
|
if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; }
|
||||||
|
|
||||||
|
dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
|
||||||
|
if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
|
||||||
|
|
||||||
|
if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
|
||||||
|
{
|
||||||
|
while (counter--)
|
||||||
|
{
|
||||||
|
while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); }
|
||||||
|
*pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
|
||||||
|
else if ((counter >= 9) && (counter <= dist))
|
||||||
|
{
|
||||||
|
const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
|
||||||
|
((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
|
||||||
|
pOut_buf_cur += 8;
|
||||||
|
} while ((pSrc += 8) < pSrc_end);
|
||||||
|
if ((counter &= 7) < 3)
|
||||||
|
{
|
||||||
|
if (counter)
|
||||||
|
{
|
||||||
|
pOut_buf_cur[0] = pSrc[0];
|
||||||
|
if (counter > 1)
|
||||||
|
pOut_buf_cur[1] = pSrc[1];
|
||||||
|
pOut_buf_cur += counter;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pOut_buf_cur[0] = pSrc[0];
|
||||||
|
pOut_buf_cur[1] = pSrc[1];
|
||||||
|
pOut_buf_cur[2] = pSrc[2];
|
||||||
|
pOut_buf_cur += 3; pSrc += 3;
|
||||||
|
} while ((int)(counter -= 3) > 2);
|
||||||
|
if ((int)counter > 0)
|
||||||
|
{
|
||||||
|
pOut_buf_cur[0] = pSrc[0];
|
||||||
|
if ((int)counter > 1)
|
||||||
|
pOut_buf_cur[1] = pSrc[1];
|
||||||
|
pOut_buf_cur += counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (!(r->m_final & 1));
|
||||||
|
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
|
||||||
|
{
|
||||||
|
TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; }
|
||||||
|
}
|
||||||
|
TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
|
||||||
|
TINFL_CR_FINISH
|
||||||
|
|
||||||
|
common_exit:
|
||||||
|
r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start;
|
||||||
|
*pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
|
||||||
|
if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
|
||||||
|
{
|
||||||
|
const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
|
||||||
|
mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
|
||||||
|
while (buf_len)
|
||||||
|
{
|
||||||
|
for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
|
||||||
|
{
|
||||||
|
s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
|
||||||
|
s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
|
||||||
|
}
|
||||||
|
for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
|
||||||
|
s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
|
||||||
|
}
|
||||||
|
r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other stuff is for advanced use. */
|
||||||
|
enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 };
|
||||||
|
|
||||||
|
/* Return status codes. MZ_PARAM_ERROR is non-standard. */
|
||||||
|
enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 };
|
||||||
|
|
||||||
|
/* Compression levels. */
|
||||||
|
enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_DEFAULT_COMPRESSION = -1 };
|
||||||
|
|
||||||
|
/* Window bits */
|
||||||
|
#define MZ_DEFAULT_WINDOW_BITS 15
|
||||||
|
|
||||||
|
struct mz_internal_state;
|
||||||
|
|
||||||
|
/* Compression/decompression stream struct. */
|
||||||
|
typedef struct mz_stream_s
|
||||||
|
{
|
||||||
|
const unsigned char *next_in; /* pointer to next byte to read */
|
||||||
|
unsigned int avail_in; /* number of bytes available at next_in */
|
||||||
|
mz_ulong total_in; /* total number of bytes consumed so far */
|
||||||
|
|
||||||
|
unsigned char *next_out; /* pointer to next byte to write */
|
||||||
|
unsigned int avail_out; /* number of bytes that can be written to next_out */
|
||||||
|
mz_ulong total_out; /* total number of bytes produced so far */
|
||||||
|
|
||||||
|
char *msg; /* error msg (unused) */
|
||||||
|
struct mz_internal_state *state; /* internal state, allocated by zalloc/zfree */
|
||||||
|
|
||||||
|
mz_alloc_func zalloc; /* optional heap allocation function (defaults to malloc) */
|
||||||
|
mz_free_func zfree; /* optional heap free function (defaults to free) */
|
||||||
|
void *opaque; /* heap alloc function user pointer */
|
||||||
|
|
||||||
|
int data_type; /* data_type (unused) */
|
||||||
|
mz_ulong adler; /* adler32 of the source or uncompressed data */
|
||||||
|
mz_ulong reserved; /* not used */
|
||||||
|
} mz_stream;
|
||||||
|
|
||||||
|
typedef mz_stream *mz_streamp;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
tinfl_decompressor m_decomp;
|
||||||
|
mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits;
|
||||||
|
mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
|
||||||
|
tinfl_status m_last_status;
|
||||||
|
} inflate_state;
|
||||||
|
|
||||||
|
static int mz_inflateInit2(mz_streamp pStream, int window_bits)
|
||||||
|
{
|
||||||
|
inflate_state *pDecomp;
|
||||||
|
if (!pStream) return MZ_STREAM_ERROR;
|
||||||
|
if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR;
|
||||||
|
|
||||||
|
pStream->data_type = 0;
|
||||||
|
pStream->adler = 0;
|
||||||
|
pStream->msg = NULL;
|
||||||
|
pStream->total_in = 0;
|
||||||
|
pStream->total_out = 0;
|
||||||
|
pStream->reserved = 0;
|
||||||
|
/* if (!pStream->zalloc) pStream->zalloc = def_alloc_func; */
|
||||||
|
/* if (!pStream->zfree) pStream->zfree = def_free_func; */
|
||||||
|
|
||||||
|
pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
|
||||||
|
if (!pDecomp) return MZ_MEM_ERROR;
|
||||||
|
|
||||||
|
pStream->state = (struct mz_internal_state *)pDecomp;
|
||||||
|
|
||||||
|
tinfl_init(&pDecomp->m_decomp);
|
||||||
|
pDecomp->m_dict_ofs = 0;
|
||||||
|
pDecomp->m_dict_avail = 0;
|
||||||
|
pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
|
||||||
|
pDecomp->m_first_call = 1;
|
||||||
|
pDecomp->m_has_flushed = 0;
|
||||||
|
pDecomp->m_window_bits = window_bits;
|
||||||
|
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mz_inflate(mz_streamp pStream, int flush)
|
||||||
|
{
|
||||||
|
inflate_state* pState;
|
||||||
|
mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
|
||||||
|
size_t in_bytes, out_bytes, orig_avail_in;
|
||||||
|
tinfl_status status;
|
||||||
|
|
||||||
|
if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR;
|
||||||
|
if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
|
||||||
|
if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
|
||||||
|
|
||||||
|
pState = (inflate_state*)pStream->state;
|
||||||
|
if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
|
||||||
|
orig_avail_in = pStream->avail_in;
|
||||||
|
|
||||||
|
first_call = pState->m_first_call; pState->m_first_call = 0;
|
||||||
|
if (pState->m_last_status < 0) return MZ_DATA_ERROR;
|
||||||
|
|
||||||
|
if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
|
||||||
|
pState->m_has_flushed |= (flush == MZ_FINISH);
|
||||||
|
|
||||||
|
if ((flush == MZ_FINISH) && (first_call))
|
||||||
|
{
|
||||||
|
/* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */
|
||||||
|
decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
|
||||||
|
in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
|
||||||
|
status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
|
||||||
|
pState->m_last_status = status;
|
||||||
|
pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes;
|
||||||
|
pStream->adler = tinfl_get_adler32(&pState->m_decomp);
|
||||||
|
pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes;
|
||||||
|
|
||||||
|
if (status < 0)
|
||||||
|
return MZ_DATA_ERROR;
|
||||||
|
else if (status != TINFL_STATUS_DONE)
|
||||||
|
{
|
||||||
|
pState->m_last_status = TINFL_STATUS_FAILED;
|
||||||
|
return MZ_BUF_ERROR;
|
||||||
|
}
|
||||||
|
return MZ_STREAM_END;
|
||||||
|
}
|
||||||
|
/* flush != MZ_FINISH then we must assume there's more input. */
|
||||||
|
if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
|
||||||
|
|
||||||
|
if (pState->m_dict_avail)
|
||||||
|
{
|
||||||
|
n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
|
||||||
|
memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
|
||||||
|
pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
|
||||||
|
pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
|
||||||
|
return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( ; ; )
|
||||||
|
{
|
||||||
|
in_bytes = pStream->avail_in;
|
||||||
|
out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
|
||||||
|
|
||||||
|
status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
|
||||||
|
pState->m_last_status = status;
|
||||||
|
|
||||||
|
pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
|
||||||
|
pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp);
|
||||||
|
|
||||||
|
pState->m_dict_avail = (mz_uint)out_bytes;
|
||||||
|
|
||||||
|
n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
|
||||||
|
memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
|
||||||
|
pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
|
||||||
|
pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
|
||||||
|
|
||||||
|
if (status < 0)
|
||||||
|
return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */
|
||||||
|
else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
|
||||||
|
return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */
|
||||||
|
else if (flush == MZ_FINISH)
|
||||||
|
{
|
||||||
|
/* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */
|
||||||
|
if (status == TINFL_STATUS_DONE)
|
||||||
|
return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
|
||||||
|
/* status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. */
|
||||||
|
else if (!pStream->avail_out)
|
||||||
|
return MZ_BUF_ERROR;
|
||||||
|
}
|
||||||
|
else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mz_inflateEnd(mz_streamp pStream)
|
||||||
|
{
|
||||||
|
if (!pStream)
|
||||||
|
return MZ_STREAM_ERROR;
|
||||||
|
if (pStream->state)
|
||||||
|
{
|
||||||
|
pStream->zfree(pStream->opaque, pStream->state);
|
||||||
|
pStream->state = NULL;
|
||||||
|
}
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make this a drop-in replacement for zlib... */
|
||||||
|
#define voidpf void*
|
||||||
|
#define uInt unsigned int
|
||||||
|
#define z_stream mz_stream
|
||||||
|
#define inflateInit2 mz_inflateInit2
|
||||||
|
#define inflate mz_inflate
|
||||||
|
#define inflateEnd mz_inflateEnd
|
||||||
|
#define Z_SYNC_FLUSH MZ_SYNC_FLUSH
|
||||||
|
#define Z_FINISH MZ_FINISH
|
||||||
|
#define Z_OK MZ_OK
|
||||||
|
#define Z_STREAM_END MZ_STREAM_END
|
||||||
|
#define Z_NEED_DICT MZ_NEED_DICT
|
||||||
|
#define Z_ERRNO MZ_ERRNO
|
||||||
|
#define Z_STREAM_ERROR MZ_STREAM_ERROR
|
||||||
|
#define Z_DATA_ERROR MZ_DATA_ERROR
|
||||||
|
#define Z_MEM_ERROR MZ_MEM_ERROR
|
||||||
|
#define Z_BUF_ERROR MZ_BUF_ERROR
|
||||||
|
#define Z_VERSION_ERROR MZ_VERSION_ERROR
|
||||||
|
#define MAX_WBITS 15
|
||||||
|
|
||||||
|
#endif /* #ifndef TINFL_HEADER_FILE_ONLY */
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
of this software dedicate any and all copyright interest in the
|
||||||
|
software to the public domain. We make this dedication for the benefit
|
||||||
|
of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of
|
||||||
|
relinquishment in perpetuity of all present and future rights to this
|
||||||
|
software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <https://unlicense.org/>
|
||||||
|
*/
|
||||||
188
desktop_version/physfs/physfs_platform_apple.m
Normal file
188
desktop_version/physfs/physfs_platform_apple.m
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
* Apple platform (macOS, iOS, watchOS, etc) support routines for PhysicsFS.
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE.txt in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_platforms.h"
|
||||||
|
|
||||||
|
#ifdef PHYSFS_PLATFORM_APPLE
|
||||||
|
|
||||||
|
#include <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
int __PHYSFS_platformInit(void)
|
||||||
|
{
|
||||||
|
return 1; /* success. */
|
||||||
|
} /* __PHYSFS_platformInit */
|
||||||
|
|
||||||
|
|
||||||
|
void __PHYSFS_platformDeinit(void)
|
||||||
|
{
|
||||||
|
/* no-op */
|
||||||
|
} /* __PHYSFS_platformDeinit */
|
||||||
|
|
||||||
|
|
||||||
|
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
|
||||||
|
{
|
||||||
|
@autoreleasepool
|
||||||
|
{
|
||||||
|
NSString *path = [[NSBundle mainBundle] bundlePath];
|
||||||
|
BAIL_IF(!path, PHYSFS_ERR_OS_ERROR, NULL);
|
||||||
|
size_t len = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
char *retval = (char *) allocator.Malloc(len + 2);
|
||||||
|
BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
[path getCString:retval maxLength:len+1 encoding:NSUTF8StringEncoding];
|
||||||
|
retval[len] = '/';
|
||||||
|
retval[len+1] = '\0';
|
||||||
|
return retval; /* whew. */
|
||||||
|
} /* @autoreleasepool */
|
||||||
|
} /* __PHYSFS_platformCalcBaseDir */
|
||||||
|
|
||||||
|
|
||||||
|
char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
|
||||||
|
{
|
||||||
|
@autoreleasepool
|
||||||
|
{
|
||||||
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, TRUE);
|
||||||
|
BAIL_IF(!paths, PHYSFS_ERR_OS_ERROR, NULL);
|
||||||
|
NSString *path = (NSString *) [paths objectAtIndex:0];
|
||||||
|
BAIL_IF(!path, PHYSFS_ERR_OS_ERROR, NULL);
|
||||||
|
size_t len = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
const size_t applen = strlen(app);
|
||||||
|
char *retval = (char *) allocator.Malloc(len + applen + 3);
|
||||||
|
BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
[path getCString:retval maxLength:len+1 encoding:NSUTF8StringEncoding];
|
||||||
|
snprintf(retval + len, applen + 3, "/%s/", app);
|
||||||
|
return retval; /* whew. */
|
||||||
|
} /* @autoreleasepool */
|
||||||
|
} /* __PHYSFS_platformCalcPrefDir */
|
||||||
|
|
||||||
|
|
||||||
|
/* CD-ROM detection code... */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Code based on sample from Apple Developer Connection:
|
||||||
|
* https://developer.apple.com/samplecode/Sample_Code/Devices_and_Hardware/Disks/VolumeToBSDNode/VolumeToBSDNode.c.htm
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(PHYSFS_NO_CDROM_SUPPORT)
|
||||||
|
|
||||||
|
#include <IOKit/IOKitLib.h>
|
||||||
|
#include <IOKit/storage/IOMedia.h>
|
||||||
|
#include <IOKit/storage/IOCDMedia.h>
|
||||||
|
#include <IOKit/storage/IODVDMedia.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
|
||||||
|
static int darwinIsWholeMedia(io_service_t service)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
CFTypeRef wholeMedia;
|
||||||
|
|
||||||
|
if (!IOObjectConformsTo(service, kIOMediaClass))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wholeMedia = IORegistryEntryCreateCFProperty(service,
|
||||||
|
CFSTR(kIOMediaWholeKey),
|
||||||
|
NULL, 0);
|
||||||
|
if (wholeMedia == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
retval = CFBooleanGetValue(wholeMedia);
|
||||||
|
CFRelease(wholeMedia);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
} /* darwinIsWholeMedia */
|
||||||
|
|
||||||
|
|
||||||
|
static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
CFMutableDictionaryRef matchingDict;
|
||||||
|
kern_return_t rc;
|
||||||
|
io_iterator_t iter;
|
||||||
|
io_service_t service;
|
||||||
|
|
||||||
|
if ((matchingDict = IOBSDNameMatching(masterPort, 0, bsdName)) == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rc = IOServiceGetMatchingServices(masterPort, matchingDict, &iter);
|
||||||
|
if ((rc != KERN_SUCCESS) || (!iter))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
service = IOIteratorNext(iter);
|
||||||
|
IOObjectRelease(iter);
|
||||||
|
if (!service)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rc = IORegistryEntryCreateIterator(service, kIOServicePlane,
|
||||||
|
kIORegistryIterateRecursively | kIORegistryIterateParents, &iter);
|
||||||
|
|
||||||
|
if (!iter)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (rc != KERN_SUCCESS)
|
||||||
|
{
|
||||||
|
IOObjectRelease(iter);
|
||||||
|
return 0;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
IOObjectRetain(service); /* add an extra object reference... */
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (darwinIsWholeMedia(service))
|
||||||
|
{
|
||||||
|
if ( (IOObjectConformsTo(service, kIOCDMediaClass)) ||
|
||||||
|
(IOObjectConformsTo(service, kIODVDMediaClass)) )
|
||||||
|
{
|
||||||
|
retval = 1;
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
IOObjectRelease(service);
|
||||||
|
} while ((service = IOIteratorNext(iter)) && (!retval));
|
||||||
|
|
||||||
|
IOObjectRelease(iter);
|
||||||
|
IOObjectRelease(service);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
} /* darwinIsMountedDisc */
|
||||||
|
|
||||||
|
#endif /* !defined(PHYSFS_NO_CDROM_SUPPORT) */
|
||||||
|
|
||||||
|
|
||||||
|
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
|
||||||
|
{
|
||||||
|
#if !defined(PHYSFS_NO_CDROM_SUPPORT)
|
||||||
|
const char *devPrefix = "/dev/";
|
||||||
|
const int prefixLen = strlen(devPrefix);
|
||||||
|
mach_port_t masterPort = 0;
|
||||||
|
struct statfs *mntbufp;
|
||||||
|
int i, mounts;
|
||||||
|
|
||||||
|
if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS)
|
||||||
|
BAIL(PHYSFS_ERR_OS_ERROR, ) /*return void*/;
|
||||||
|
|
||||||
|
mounts = getmntinfo(&mntbufp, MNT_WAIT); /* NOT THREAD SAFE! */
|
||||||
|
for (i = 0; i < mounts; i++)
|
||||||
|
{
|
||||||
|
char *dev = mntbufp[i].f_mntfromname;
|
||||||
|
char *mnt = mntbufp[i].f_mntonname;
|
||||||
|
if (strncmp(dev, devPrefix, prefixLen) != 0) /* a virtual device? */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dev += prefixLen;
|
||||||
|
if (darwinIsMountedDisc(dev, masterPort))
|
||||||
|
cb(data, mnt);
|
||||||
|
} /* for */
|
||||||
|
#endif /* !defined(PHYSFS_NO_CDROM_SUPPORT) */
|
||||||
|
} /* __PHYSFS_platformDetectAvailableCDs */
|
||||||
|
|
||||||
|
#endif /* PHYSFS_PLATFORM_APPLE */
|
||||||
|
|
||||||
|
/* end of physfs_platform_apple.m ... */
|
||||||
|
|
||||||
417
desktop_version/physfs/physfs_platform_posix.c
Normal file
417
desktop_version/physfs/physfs_platform_posix.c
Normal file
@@ -0,0 +1,417 @@
|
|||||||
|
/*
|
||||||
|
* Posix-esque support routines for PhysicsFS.
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE.txt in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* !!! FIXME: check for EINTR? */
|
||||||
|
|
||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_platforms.h"
|
||||||
|
|
||||||
|
#ifdef PHYSFS_PLATFORM_POSIX
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
static PHYSFS_ErrorCode errcodeFromErrnoError(const int err)
|
||||||
|
{
|
||||||
|
switch (err)
|
||||||
|
{
|
||||||
|
case 0: return PHYSFS_ERR_OK;
|
||||||
|
case EACCES: return PHYSFS_ERR_PERMISSION;
|
||||||
|
case EPERM: return PHYSFS_ERR_PERMISSION;
|
||||||
|
case EDQUOT: return PHYSFS_ERR_NO_SPACE;
|
||||||
|
case EIO: return PHYSFS_ERR_IO;
|
||||||
|
case ELOOP: return PHYSFS_ERR_SYMLINK_LOOP;
|
||||||
|
case EMLINK: return PHYSFS_ERR_NO_SPACE;
|
||||||
|
case ENAMETOOLONG: return PHYSFS_ERR_BAD_FILENAME;
|
||||||
|
case ENOENT: return PHYSFS_ERR_NOT_FOUND;
|
||||||
|
case ENOSPC: return PHYSFS_ERR_NO_SPACE;
|
||||||
|
case ENOTDIR: return PHYSFS_ERR_NOT_FOUND;
|
||||||
|
case EISDIR: return PHYSFS_ERR_NOT_A_FILE;
|
||||||
|
case EROFS: return PHYSFS_ERR_READ_ONLY;
|
||||||
|
case ETXTBSY: return PHYSFS_ERR_BUSY;
|
||||||
|
case EBUSY: return PHYSFS_ERR_BUSY;
|
||||||
|
case ENOMEM: return PHYSFS_ERR_OUT_OF_MEMORY;
|
||||||
|
case ENOTEMPTY: return PHYSFS_ERR_DIR_NOT_EMPTY;
|
||||||
|
default: return PHYSFS_ERR_OS_ERROR;
|
||||||
|
} /* switch */
|
||||||
|
} /* errcodeFromErrnoError */
|
||||||
|
|
||||||
|
|
||||||
|
static inline PHYSFS_ErrorCode errcodeFromErrno(void)
|
||||||
|
{
|
||||||
|
return errcodeFromErrnoError(errno);
|
||||||
|
} /* errcodeFromErrno */
|
||||||
|
|
||||||
|
|
||||||
|
static char *getUserDirByUID(void)
|
||||||
|
{
|
||||||
|
uid_t uid = getuid();
|
||||||
|
struct passwd *pw;
|
||||||
|
char *retval = NULL;
|
||||||
|
|
||||||
|
pw = getpwuid(uid);
|
||||||
|
if ((pw != NULL) && (pw->pw_dir != NULL) && (*pw->pw_dir != '\0'))
|
||||||
|
{
|
||||||
|
const size_t dlen = strlen(pw->pw_dir);
|
||||||
|
const size_t add_dirsep = (pw->pw_dir[dlen-1] != '/') ? 1 : 0;
|
||||||
|
retval = (char *) allocator.Malloc(dlen + 1 + add_dirsep);
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
strcpy(retval, pw->pw_dir);
|
||||||
|
if (add_dirsep)
|
||||||
|
{
|
||||||
|
retval[dlen] = '/';
|
||||||
|
retval[dlen+1] = '\0';
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
} /* getUserDirByUID */
|
||||||
|
|
||||||
|
|
||||||
|
char *__PHYSFS_platformCalcUserDir(void)
|
||||||
|
{
|
||||||
|
char *retval = NULL;
|
||||||
|
char *envr = getenv("HOME");
|
||||||
|
|
||||||
|
/* if the environment variable was set, make sure it's really a dir. */
|
||||||
|
if (envr != NULL)
|
||||||
|
{
|
||||||
|
struct stat statbuf;
|
||||||
|
if ((stat(envr, &statbuf) != -1) && (S_ISDIR(statbuf.st_mode)))
|
||||||
|
{
|
||||||
|
const size_t envrlen = strlen(envr);
|
||||||
|
const size_t add_dirsep = (envr[envrlen-1] != '/') ? 1 : 0;
|
||||||
|
retval = allocator.Malloc(envrlen + 1 + add_dirsep);
|
||||||
|
if (retval)
|
||||||
|
{
|
||||||
|
strcpy(retval, envr);
|
||||||
|
if (add_dirsep)
|
||||||
|
{
|
||||||
|
retval[envrlen] = '/';
|
||||||
|
retval[envrlen+1] = '\0';
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (retval == NULL)
|
||||||
|
retval = getUserDirByUID();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
} /* __PHYSFS_platformCalcUserDir */
|
||||||
|
|
||||||
|
|
||||||
|
PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname,
|
||||||
|
PHYSFS_EnumerateCallback callback,
|
||||||
|
const char *origdir, void *callbackdata)
|
||||||
|
{
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *ent;
|
||||||
|
PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK;
|
||||||
|
|
||||||
|
dir = opendir(dirname);
|
||||||
|
BAIL_IF(dir == NULL, errcodeFromErrno(), PHYSFS_ENUM_ERROR);
|
||||||
|
|
||||||
|
while ((retval == PHYSFS_ENUM_OK) && ((ent = readdir(dir)) != NULL))
|
||||||
|
{
|
||||||
|
const char *name = ent->d_name;
|
||||||
|
if (name[0] == '.') /* ignore "." and ".." */
|
||||||
|
{
|
||||||
|
if ((name[1] == '\0') || ((name[1] == '.') && (name[2] == '\0')))
|
||||||
|
continue;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
retval = callback(callbackdata, origdir, name);
|
||||||
|
if (retval == PHYSFS_ENUM_ERROR)
|
||||||
|
PHYSFS_setErrorCode(PHYSFS_ERR_APP_CALLBACK);
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
} /* __PHYSFS_platformEnumerate */
|
||||||
|
|
||||||
|
|
||||||
|
int __PHYSFS_platformMkDir(const char *path)
|
||||||
|
{
|
||||||
|
const int rc = mkdir(path, S_IRWXU);
|
||||||
|
BAIL_IF(rc == -1, errcodeFromErrno(), 0);
|
||||||
|
return 1;
|
||||||
|
} /* __PHYSFS_platformMkDir */
|
||||||
|
|
||||||
|
|
||||||
|
static void *doOpen(const char *filename, int mode)
|
||||||
|
{
|
||||||
|
const int appending = (mode & O_APPEND);
|
||||||
|
int fd;
|
||||||
|
int *retval;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
/* O_APPEND doesn't actually behave as we'd like. */
|
||||||
|
mode &= ~O_APPEND;
|
||||||
|
|
||||||
|
fd = open(filename, mode, S_IRUSR | S_IWUSR);
|
||||||
|
BAIL_IF(fd < 0, errcodeFromErrno(), NULL);
|
||||||
|
|
||||||
|
if (appending)
|
||||||
|
{
|
||||||
|
if (lseek(fd, 0, SEEK_END) < 0)
|
||||||
|
{
|
||||||
|
const int err = errno;
|
||||||
|
close(fd);
|
||||||
|
BAIL(errcodeFromErrnoError(err), NULL);
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
retval = (int *) allocator.Malloc(sizeof (int));
|
||||||
|
if (!retval)
|
||||||
|
{
|
||||||
|
close(fd);
|
||||||
|
BAIL(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
*retval = fd;
|
||||||
|
return ((void *) retval);
|
||||||
|
} /* doOpen */
|
||||||
|
|
||||||
|
|
||||||
|
void *__PHYSFS_platformOpenRead(const char *filename)
|
||||||
|
{
|
||||||
|
return doOpen(filename, O_RDONLY);
|
||||||
|
} /* __PHYSFS_platformOpenRead */
|
||||||
|
|
||||||
|
|
||||||
|
void *__PHYSFS_platformOpenWrite(const char *filename)
|
||||||
|
{
|
||||||
|
return doOpen(filename, O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
|
} /* __PHYSFS_platformOpenWrite */
|
||||||
|
|
||||||
|
|
||||||
|
void *__PHYSFS_platformOpenAppend(const char *filename)
|
||||||
|
{
|
||||||
|
return doOpen(filename, O_WRONLY | O_CREAT | O_APPEND);
|
||||||
|
} /* __PHYSFS_platformOpenAppend */
|
||||||
|
|
||||||
|
|
||||||
|
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
|
||||||
|
PHYSFS_uint64 len)
|
||||||
|
{
|
||||||
|
const int fd = *((int *) opaque);
|
||||||
|
ssize_t rc = 0;
|
||||||
|
|
||||||
|
if (!__PHYSFS_ui64FitsAddressSpace(len))
|
||||||
|
BAIL(PHYSFS_ERR_INVALID_ARGUMENT, -1);
|
||||||
|
|
||||||
|
rc = read(fd, buffer, (size_t) len);
|
||||||
|
BAIL_IF(rc == -1, errcodeFromErrno(), -1);
|
||||||
|
assert(rc >= 0);
|
||||||
|
assert(rc <= len);
|
||||||
|
return (PHYSFS_sint64) rc;
|
||||||
|
} /* __PHYSFS_platformRead */
|
||||||
|
|
||||||
|
|
||||||
|
PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
|
||||||
|
PHYSFS_uint64 len)
|
||||||
|
{
|
||||||
|
const int fd = *((int *) opaque);
|
||||||
|
ssize_t rc = 0;
|
||||||
|
|
||||||
|
if (!__PHYSFS_ui64FitsAddressSpace(len))
|
||||||
|
BAIL(PHYSFS_ERR_INVALID_ARGUMENT, -1);
|
||||||
|
|
||||||
|
rc = write(fd, (void *) buffer, (size_t) len);
|
||||||
|
BAIL_IF(rc == -1, errcodeFromErrno(), rc);
|
||||||
|
assert(rc >= 0);
|
||||||
|
assert(rc <= len);
|
||||||
|
return (PHYSFS_sint64) rc;
|
||||||
|
} /* __PHYSFS_platformWrite */
|
||||||
|
|
||||||
|
|
||||||
|
int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
|
||||||
|
{
|
||||||
|
const int fd = *((int *) opaque);
|
||||||
|
const off_t rc = lseek(fd, (off_t) pos, SEEK_SET);
|
||||||
|
BAIL_IF(rc == -1, errcodeFromErrno(), 0);
|
||||||
|
return 1;
|
||||||
|
} /* __PHYSFS_platformSeek */
|
||||||
|
|
||||||
|
|
||||||
|
PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
|
||||||
|
{
|
||||||
|
const int fd = *((int *) opaque);
|
||||||
|
PHYSFS_sint64 retval;
|
||||||
|
retval = (PHYSFS_sint64) lseek(fd, 0, SEEK_CUR);
|
||||||
|
BAIL_IF(retval == -1, errcodeFromErrno(), -1);
|
||||||
|
return retval;
|
||||||
|
} /* __PHYSFS_platformTell */
|
||||||
|
|
||||||
|
|
||||||
|
PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
|
||||||
|
{
|
||||||
|
const int fd = *((int *) opaque);
|
||||||
|
struct stat statbuf;
|
||||||
|
BAIL_IF(fstat(fd, &statbuf) == -1, errcodeFromErrno(), -1);
|
||||||
|
return ((PHYSFS_sint64) statbuf.st_size);
|
||||||
|
} /* __PHYSFS_platformFileLength */
|
||||||
|
|
||||||
|
|
||||||
|
int __PHYSFS_platformFlush(void *opaque)
|
||||||
|
{
|
||||||
|
const int fd = *((int *) opaque);
|
||||||
|
if ((fcntl(fd, F_GETFL) & O_ACCMODE) != O_RDONLY)
|
||||||
|
BAIL_IF(fsync(fd) == -1, errcodeFromErrno(), 0);
|
||||||
|
return 1;
|
||||||
|
} /* __PHYSFS_platformFlush */
|
||||||
|
|
||||||
|
|
||||||
|
void __PHYSFS_platformClose(void *opaque)
|
||||||
|
{
|
||||||
|
const int fd = *((int *) opaque);
|
||||||
|
(void) close(fd); /* we don't check this. You should have used flush! */
|
||||||
|
allocator.Free(opaque);
|
||||||
|
} /* __PHYSFS_platformClose */
|
||||||
|
|
||||||
|
|
||||||
|
int __PHYSFS_platformDelete(const char *path)
|
||||||
|
{
|
||||||
|
BAIL_IF(remove(path) == -1, errcodeFromErrno(), 0);
|
||||||
|
return 1;
|
||||||
|
} /* __PHYSFS_platformDelete */
|
||||||
|
|
||||||
|
|
||||||
|
int __PHYSFS_platformStat(const char *fname, PHYSFS_Stat *st, const int follow)
|
||||||
|
{
|
||||||
|
struct stat statbuf;
|
||||||
|
const int rc = follow ? stat(fname, &statbuf) : lstat(fname, &statbuf);
|
||||||
|
BAIL_IF(rc == -1, errcodeFromErrno(), 0);
|
||||||
|
|
||||||
|
if (S_ISREG(statbuf.st_mode))
|
||||||
|
{
|
||||||
|
st->filetype = PHYSFS_FILETYPE_REGULAR;
|
||||||
|
st->filesize = statbuf.st_size;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
else if(S_ISDIR(statbuf.st_mode))
|
||||||
|
{
|
||||||
|
st->filetype = PHYSFS_FILETYPE_DIRECTORY;
|
||||||
|
st->filesize = 0;
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else if(S_ISLNK(statbuf.st_mode))
|
||||||
|
{
|
||||||
|
st->filetype = PHYSFS_FILETYPE_SYMLINK;
|
||||||
|
st->filesize = 0;
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
st->filetype = PHYSFS_FILETYPE_OTHER;
|
||||||
|
st->filesize = statbuf.st_size;
|
||||||
|
} /* else */
|
||||||
|
|
||||||
|
st->modtime = statbuf.st_mtime;
|
||||||
|
st->createtime = statbuf.st_ctime;
|
||||||
|
st->accesstime = statbuf.st_atime;
|
||||||
|
|
||||||
|
st->readonly = (access(fname, W_OK) == -1);
|
||||||
|
return 1;
|
||||||
|
} /* __PHYSFS_platformStat */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
pthread_t owner;
|
||||||
|
PHYSFS_uint32 count;
|
||||||
|
} PthreadMutex;
|
||||||
|
|
||||||
|
|
||||||
|
void *__PHYSFS_platformGetThreadID(void)
|
||||||
|
{
|
||||||
|
return ( (void *) ((size_t) pthread_self()) );
|
||||||
|
} /* __PHYSFS_platformGetThreadID */
|
||||||
|
|
||||||
|
|
||||||
|
void *__PHYSFS_platformCreateMutex(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
PthreadMutex *m = (PthreadMutex *) allocator.Malloc(sizeof (PthreadMutex));
|
||||||
|
BAIL_IF(!m, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
rc = pthread_mutex_init(&m->mutex, NULL);
|
||||||
|
if (rc != 0)
|
||||||
|
{
|
||||||
|
allocator.Free(m);
|
||||||
|
BAIL(PHYSFS_ERR_OS_ERROR, NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
m->count = 0;
|
||||||
|
m->owner = (pthread_t) 0xDEADBEEF;
|
||||||
|
return ((void *) m);
|
||||||
|
} /* __PHYSFS_platformCreateMutex */
|
||||||
|
|
||||||
|
|
||||||
|
void __PHYSFS_platformDestroyMutex(void *mutex)
|
||||||
|
{
|
||||||
|
PthreadMutex *m = (PthreadMutex *) mutex;
|
||||||
|
|
||||||
|
/* Destroying a locked mutex is a bug, but we'll try to be helpful. */
|
||||||
|
if ((m->owner == pthread_self()) && (m->count > 0))
|
||||||
|
pthread_mutex_unlock(&m->mutex);
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&m->mutex);
|
||||||
|
allocator.Free(m);
|
||||||
|
} /* __PHYSFS_platformDestroyMutex */
|
||||||
|
|
||||||
|
|
||||||
|
int __PHYSFS_platformGrabMutex(void *mutex)
|
||||||
|
{
|
||||||
|
PthreadMutex *m = (PthreadMutex *) mutex;
|
||||||
|
pthread_t tid = pthread_self();
|
||||||
|
if (m->owner != tid)
|
||||||
|
{
|
||||||
|
if (pthread_mutex_lock(&m->mutex) != 0)
|
||||||
|
return 0;
|
||||||
|
m->owner = tid;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
m->count++;
|
||||||
|
return 1;
|
||||||
|
} /* __PHYSFS_platformGrabMutex */
|
||||||
|
|
||||||
|
|
||||||
|
void __PHYSFS_platformReleaseMutex(void *mutex)
|
||||||
|
{
|
||||||
|
PthreadMutex *m = (PthreadMutex *) mutex;
|
||||||
|
assert(m->owner == pthread_self()); /* catch programming errors. */
|
||||||
|
assert(m->count > 0); /* catch programming errors. */
|
||||||
|
if (m->owner == pthread_self())
|
||||||
|
{
|
||||||
|
if (--m->count == 0)
|
||||||
|
{
|
||||||
|
m->owner = (pthread_t) 0xDEADBEEF;
|
||||||
|
pthread_mutex_unlock(&m->mutex);
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
} /* __PHYSFS_platformReleaseMutex */
|
||||||
|
|
||||||
|
#endif /* PHYSFS_PLATFORM_POSIX */
|
||||||
|
|
||||||
|
/* end of physfs_platform_posix.c ... */
|
||||||
|
|
||||||
367
desktop_version/physfs/physfs_platform_unix.c
Normal file
367
desktop_version/physfs/physfs_platform_unix.c
Normal file
@@ -0,0 +1,367 @@
|
|||||||
|
/*
|
||||||
|
* Unix support routines for PhysicsFS.
|
||||||
|
*
|
||||||
|
* Please see the file LICENSE.txt in the source's root directory.
|
||||||
|
*
|
||||||
|
* This file written by Ryan C. Gordon.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_platforms.h"
|
||||||
|
|
||||||
|
#ifdef PHYSFS_PLATFORM_UNIX
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#if PHYSFS_NO_CDROM_SUPPORT
|
||||||
|
#elif PHYSFS_PLATFORM_LINUX
|
||||||
|
# define PHYSFS_HAVE_MNTENT_H 1
|
||||||
|
#elif defined __CYGWIN__
|
||||||
|
# define PHYSFS_HAVE_MNTENT_H 1
|
||||||
|
#elif PHYSFS_PLATFORM_SOLARIS
|
||||||
|
# define PHYSFS_HAVE_SYS_MNTTAB_H 1
|
||||||
|
#elif PHYSFS_PLATFORM_BSD
|
||||||
|
# define PHYSFS_HAVE_SYS_UCRED_H 1
|
||||||
|
#else
|
||||||
|
# warning No CD-ROM support included. Either define your platform here,
|
||||||
|
# warning or define PHYSFS_NO_CDROM_SUPPORT=1 to confirm this is intentional.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PHYSFS_HAVE_SYS_UCRED_H
|
||||||
|
# ifdef PHYSFS_HAVE_MNTENT_H
|
||||||
|
# undef PHYSFS_HAVE_MNTENT_H /* don't do both... */
|
||||||
|
# endif
|
||||||
|
# include <sys/mount.h>
|
||||||
|
# include <sys/ucred.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PHYSFS_HAVE_MNTENT_H
|
||||||
|
#include <mntent.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PHYSFS_HAVE_SYS_MNTTAB_H
|
||||||
|
#include <sys/mnttab.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PHYSFS_PLATFORM_FREEBSD
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
int __PHYSFS_platformInit(void)
|
||||||
|
{
|
||||||
|
return 1; /* always succeed. */
|
||||||
|
} /* __PHYSFS_platformInit */
|
||||||
|
|
||||||
|
|
||||||
|
void __PHYSFS_platformDeinit(void)
|
||||||
|
{
|
||||||
|
/* no-op */
|
||||||
|
} /* __PHYSFS_platformDeinit */
|
||||||
|
|
||||||
|
|
||||||
|
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
|
||||||
|
{
|
||||||
|
#if (defined PHYSFS_NO_CDROM_SUPPORT)
|
||||||
|
/* no-op. */
|
||||||
|
|
||||||
|
#elif (defined PHYSFS_HAVE_SYS_UCRED_H)
|
||||||
|
int i;
|
||||||
|
struct statfs *mntbufp = NULL;
|
||||||
|
int mounts = getmntinfo(&mntbufp, MNT_NOWAIT);
|
||||||
|
|
||||||
|
for (i = 0; i < mounts; i++)
|
||||||
|
{
|
||||||
|
int add_it = 0;
|
||||||
|
|
||||||
|
if (strcmp(mntbufp[i].f_fstypename, "iso9660") == 0)
|
||||||
|
add_it = 1;
|
||||||
|
else if (strcmp( mntbufp[i].f_fstypename, "cd9660") == 0)
|
||||||
|
add_it = 1;
|
||||||
|
|
||||||
|
/* add other mount types here */
|
||||||
|
|
||||||
|
if (add_it)
|
||||||
|
cb(data, mntbufp[i].f_mntonname);
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
#elif (defined PHYSFS_HAVE_MNTENT_H)
|
||||||
|
FILE *mounts = NULL;
|
||||||
|
struct mntent *ent = NULL;
|
||||||
|
|
||||||
|
mounts = setmntent("/etc/mtab", "r");
|
||||||
|
BAIL_IF(mounts == NULL, PHYSFS_ERR_IO, /*return void*/);
|
||||||
|
|
||||||
|
while ( (ent = getmntent(mounts)) != NULL )
|
||||||
|
{
|
||||||
|
int add_it = 0;
|
||||||
|
if (strcmp(ent->mnt_type, "iso9660") == 0)
|
||||||
|
add_it = 1;
|
||||||
|
else if (strcmp(ent->mnt_type, "udf") == 0)
|
||||||
|
add_it = 1;
|
||||||
|
|
||||||
|
/* !!! FIXME: these might pick up floppy drives, right? */
|
||||||
|
else if (strcmp(ent->mnt_type, "auto") == 0)
|
||||||
|
add_it = 1;
|
||||||
|
else if (strcmp(ent->mnt_type, "supermount") == 0)
|
||||||
|
add_it = 1;
|
||||||
|
|
||||||
|
/* add other mount types here */
|
||||||
|
|
||||||
|
if (add_it)
|
||||||
|
cb(data, ent->mnt_dir);
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
endmntent(mounts);
|
||||||
|
|
||||||
|
#elif (defined PHYSFS_HAVE_SYS_MNTTAB_H)
|
||||||
|
FILE *mounts = fopen(MNTTAB, "r");
|
||||||
|
struct mnttab ent;
|
||||||
|
|
||||||
|
BAIL_IF(mounts == NULL, PHYSFS_ERR_IO, /*return void*/);
|
||||||
|
while (getmntent(mounts, &ent) == 0)
|
||||||
|
{
|
||||||
|
int add_it = 0;
|
||||||
|
if (strcmp(ent.mnt_fstype, "hsfs") == 0)
|
||||||
|
add_it = 1;
|
||||||
|
|
||||||
|
/* add other mount types here */
|
||||||
|
|
||||||
|
if (add_it)
|
||||||
|
cb(data, ent.mnt_mountp);
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
fclose(mounts);
|
||||||
|
#endif
|
||||||
|
} /* __PHYSFS_platformDetectAvailableCDs */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See where program (bin) resides in the $PATH specified by (envr).
|
||||||
|
* returns a copy of the first element in envr that contains it, or NULL
|
||||||
|
* if it doesn't exist or there were other problems. PHYSFS_SetError() is
|
||||||
|
* called if we have a problem.
|
||||||
|
*
|
||||||
|
* (envr) will be scribbled over, and you are expected to allocator.Free() the
|
||||||
|
* return value when you're done with it.
|
||||||
|
*/
|
||||||
|
static char *findBinaryInPath(const char *bin, char *envr)
|
||||||
|
{
|
||||||
|
size_t alloc_size = 0;
|
||||||
|
char *exe = NULL;
|
||||||
|
char *start = envr;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
assert(bin != NULL);
|
||||||
|
assert(envr != NULL);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
size_t binlen;
|
||||||
|
|
||||||
|
ptr = strchr(start, ':'); /* find next $PATH separator. */
|
||||||
|
if (ptr)
|
||||||
|
*ptr = '\0';
|
||||||
|
|
||||||
|
binlen = strlen(bin);
|
||||||
|
size = strlen(start) + binlen + 2;
|
||||||
|
if (size >= alloc_size)
|
||||||
|
{
|
||||||
|
char *x = (char *) allocator.Realloc(exe, size);
|
||||||
|
if (!x)
|
||||||
|
{
|
||||||
|
if (exe != NULL)
|
||||||
|
allocator.Free(exe);
|
||||||
|
BAIL(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
alloc_size = size;
|
||||||
|
exe = x;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
/* build full binary path... */
|
||||||
|
strcpy(exe, start);
|
||||||
|
if ((exe[0] == '\0') || (exe[strlen(exe) - 1] != '/'))
|
||||||
|
strcat(exe, "/");
|
||||||
|
strcat(exe, bin);
|
||||||
|
|
||||||
|
if (access(exe, X_OK) == 0) /* Exists as executable? We're done. */
|
||||||
|
{
|
||||||
|
exe[(size - binlen) - 1] = '\0'; /* chop off filename, leave '/' */
|
||||||
|
return exe;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
start = ptr + 1; /* start points to beginning of next element. */
|
||||||
|
} while (ptr != NULL);
|
||||||
|
|
||||||
|
if (exe != NULL)
|
||||||
|
allocator.Free(exe);
|
||||||
|
|
||||||
|
return NULL; /* doesn't exist in path. */
|
||||||
|
} /* findBinaryInPath */
|
||||||
|
|
||||||
|
|
||||||
|
static char *readSymLink(const char *path)
|
||||||
|
{
|
||||||
|
ssize_t len = 64;
|
||||||
|
ssize_t rc = -1;
|
||||||
|
char *retval = NULL;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char *ptr = (char *) allocator.Realloc(retval, (size_t) len);
|
||||||
|
if (ptr == NULL)
|
||||||
|
break; /* out of memory. */
|
||||||
|
retval = ptr;
|
||||||
|
|
||||||
|
rc = readlink(path, retval, len);
|
||||||
|
if (rc == -1)
|
||||||
|
break; /* not a symlink, i/o error, etc. */
|
||||||
|
|
||||||
|
else if (rc < len)
|
||||||
|
{
|
||||||
|
retval[rc] = '\0'; /* readlink doesn't null-terminate. */
|
||||||
|
return retval; /* we're good to go. */
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
len *= 2; /* grow buffer, try again. */
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
if (retval != NULL)
|
||||||
|
allocator.Free(retval);
|
||||||
|
return NULL;
|
||||||
|
} /* readSymLink */
|
||||||
|
|
||||||
|
|
||||||
|
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
|
||||||
|
{
|
||||||
|
char *retval = NULL;
|
||||||
|
const char *envr = NULL;
|
||||||
|
|
||||||
|
/* Try to avoid using argv0 unless forced to. Try system-specific stuff. */
|
||||||
|
|
||||||
|
#if defined(PHYSFS_PLATFORM_FREEBSD)
|
||||||
|
{
|
||||||
|
char fullpath[PATH_MAX];
|
||||||
|
size_t buflen = sizeof (fullpath);
|
||||||
|
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
|
||||||
|
if (sysctl(mib, 4, fullpath, &buflen, NULL, 0) != -1)
|
||||||
|
retval = __PHYSFS_strdup(fullpath);
|
||||||
|
}
|
||||||
|
#elif defined(PHYSFS_PLATFORM_SOLARIS)
|
||||||
|
{
|
||||||
|
const char *path = getexecname();
|
||||||
|
if ((path != NULL) && (path[0] == '/')) /* must be absolute path... */
|
||||||
|
retval = __PHYSFS_strdup(path);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If there's a Linux-like /proc filesystem, you can get the full path to
|
||||||
|
* the current process from a symlink in there.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!retval && (access("/proc", F_OK) == 0))
|
||||||
|
{
|
||||||
|
retval = readSymLink("/proc/self/exe");
|
||||||
|
if (!retval) retval = readSymLink("/proc/curproc/file");
|
||||||
|
if (!retval) retval = readSymLink("/proc/curproc/exe");
|
||||||
|
if (retval == NULL)
|
||||||
|
{
|
||||||
|
/* older kernels don't have /proc/self ... try PID version... */
|
||||||
|
const unsigned long long pid = (unsigned long long) getpid();
|
||||||
|
char path[64];
|
||||||
|
const int rc = (int) snprintf(path,sizeof(path),"/proc/%llu/exe",pid);
|
||||||
|
if ( (rc > 0) && (rc < sizeof(path)) )
|
||||||
|
retval = readSymLink(path);
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (retval != NULL) /* chop off filename. */
|
||||||
|
{
|
||||||
|
char *ptr = strrchr(retval, '/');
|
||||||
|
if (ptr != NULL)
|
||||||
|
*(ptr+1) = '\0';
|
||||||
|
else /* shouldn't happen, but just in case... */
|
||||||
|
{
|
||||||
|
allocator.Free(retval);
|
||||||
|
retval = NULL;
|
||||||
|
} /* else */
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
/* No /proc/self/exe, etc, but we have an argv[0] we can parse? */
|
||||||
|
if ((retval == NULL) && (argv0 != NULL))
|
||||||
|
{
|
||||||
|
/* fast path: default behaviour can handle this. */
|
||||||
|
if (strchr(argv0, '/') != NULL)
|
||||||
|
return NULL; /* higher level parses out real path from argv0. */
|
||||||
|
|
||||||
|
/* If there's no dirsep on argv0, then look through $PATH for it. */
|
||||||
|
envr = getenv("PATH");
|
||||||
|
if (envr != NULL)
|
||||||
|
{
|
||||||
|
char *path = (char *) __PHYSFS_smallAlloc(strlen(envr) + 1);
|
||||||
|
BAIL_IF(!path, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
strcpy(path, envr);
|
||||||
|
retval = findBinaryInPath(argv0, path);
|
||||||
|
__PHYSFS_smallFree(path);
|
||||||
|
} /* if */
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (retval != NULL)
|
||||||
|
{
|
||||||
|
/* try to shrink buffer... */
|
||||||
|
char *ptr = (char *) allocator.Realloc(retval, strlen(retval) + 1);
|
||||||
|
if (ptr != NULL)
|
||||||
|
retval = ptr; /* oh well if it failed. */
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
} /* __PHYSFS_platformCalcBaseDir */
|
||||||
|
|
||||||
|
|
||||||
|
char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We use XDG's base directory spec, even if you're not on Linux.
|
||||||
|
* This isn't strictly correct, but the results are relatively sane
|
||||||
|
* in any case.
|
||||||
|
*
|
||||||
|
* https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||||
|
*/
|
||||||
|
const char *envr = getenv("XDG_DATA_HOME");
|
||||||
|
const char *append = "/";
|
||||||
|
char *retval = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (!envr)
|
||||||
|
{
|
||||||
|
/* You end up with "$HOME/.local/share/Game Name 2" */
|
||||||
|
envr = __PHYSFS_getUserDir();
|
||||||
|
BAIL_IF_ERRPASS(!envr, NULL); /* oh well. */
|
||||||
|
append = ".local/share/";
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
len = strlen(envr) + strlen(append) + strlen(app) + 2;
|
||||||
|
retval = (char *) allocator.Malloc(len);
|
||||||
|
BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
|
||||||
|
snprintf(retval, len, "%s%s%s/", envr, append, app);
|
||||||
|
return retval;
|
||||||
|
} /* __PHYSFS_platformCalcPrefDir */
|
||||||
|
|
||||||
|
#endif /* PHYSFS_PLATFORM_UNIX */
|
||||||
|
|
||||||
|
/* end of physfs_platform_unix.c ... */
|
||||||
|
|
||||||
1028
desktop_version/physfs/physfs_platform_windows.c
Normal file
1028
desktop_version/physfs/physfs_platform_windows.c
Normal file
File diff suppressed because it is too large
Load Diff
80
desktop_version/physfs/physfs_platforms.h
Normal file
80
desktop_version/physfs/physfs_platforms.h
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#ifndef _INCL_PHYSFS_PLATFORMS
|
||||||
|
#define _INCL_PHYSFS_PLATFORMS
|
||||||
|
|
||||||
|
#ifndef __PHYSICSFS_INTERNAL__
|
||||||
|
#error Do not include this header from your applications.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These only define the platforms to determine which files in the platforms
|
||||||
|
* directory should be compiled. For example, technically BeOS can be called
|
||||||
|
* a "unix" system, but since it doesn't use unix.c, we don't define
|
||||||
|
* PHYSFS_PLATFORM_UNIX on that system.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (defined __HAIKU__)
|
||||||
|
# define PHYSFS_PLATFORM_HAIKU 1
|
||||||
|
# define PHYSFS_PLATFORM_POSIX 1
|
||||||
|
#elif ((defined __BEOS__) || (defined __beos__))
|
||||||
|
# error BeOS support was dropped since PhysicsFS 2.1. Sorry. Try Haiku!
|
||||||
|
#elif (defined _WIN32_WCE) || (defined _WIN64_WCE)
|
||||||
|
# error PocketPC support was dropped since PhysicsFS 2.1. Sorry. Try WinRT!
|
||||||
|
#elif (defined(_MSC_VER) && (_MSC_VER >= 1700) && !_USING_V110_SDK71_) /* _MSC_VER==1700 for MSVC 2012 */
|
||||||
|
# include <winapifamily.h>
|
||||||
|
# define PHYSFS_PLATFORM_WINDOWS 1
|
||||||
|
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||||
|
# define PHYSFS_NO_CDROM_SUPPORT 1
|
||||||
|
# define PHYSFS_PLATFORM_WINRT 1
|
||||||
|
# endif
|
||||||
|
#elif (((defined _WIN32) || (defined _WIN64)) && (!defined __CYGWIN__))
|
||||||
|
# define PHYSFS_PLATFORM_WINDOWS 1
|
||||||
|
#elif defined(__OS2__) || defined(OS2)
|
||||||
|
# define PHYSFS_PLATFORM_OS2 1
|
||||||
|
#elif ((defined __MACH__) && (defined __APPLE__))
|
||||||
|
/* To check if iOS or not, we need to include this file */
|
||||||
|
# include <TargetConditionals.h>
|
||||||
|
# if ((TARGET_IPHONE_SIMULATOR) || (TARGET_OS_IPHONE))
|
||||||
|
# define PHYSFS_NO_CDROM_SUPPORT 1
|
||||||
|
# endif
|
||||||
|
# define PHYSFS_PLATFORM_APPLE 1
|
||||||
|
# define PHYSFS_PLATFORM_POSIX 1
|
||||||
|
#elif defined(macintosh)
|
||||||
|
# error Classic Mac OS support was dropped from PhysicsFS 2.0. Move to OS X.
|
||||||
|
#elif defined(ANDROID)
|
||||||
|
# define PHYSFS_PLATFORM_LINUX 1
|
||||||
|
# define PHYSFS_PLATFORM_UNIX 1
|
||||||
|
# define PHYSFS_PLATFORM_POSIX 1
|
||||||
|
# define PHYSFS_NO_CDROM_SUPPORT 1
|
||||||
|
#elif defined(__linux)
|
||||||
|
# define PHYSFS_PLATFORM_LINUX 1
|
||||||
|
# define PHYSFS_PLATFORM_UNIX 1
|
||||||
|
# define PHYSFS_PLATFORM_POSIX 1
|
||||||
|
#elif defined(__sun) || defined(sun)
|
||||||
|
# define PHYSFS_PLATFORM_SOLARIS 1
|
||||||
|
# define PHYSFS_PLATFORM_UNIX 1
|
||||||
|
# define PHYSFS_PLATFORM_POSIX 1
|
||||||
|
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
|
||||||
|
# define PHYSFS_PLATFORM_FREEBSD 1
|
||||||
|
# define PHYSFS_PLATFORM_BSD 1
|
||||||
|
# define PHYSFS_PLATFORM_UNIX 1
|
||||||
|
# define PHYSFS_PLATFORM_POSIX 1
|
||||||
|
#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)
|
||||||
|
# define PHYSFS_PLATFORM_BSD 1
|
||||||
|
# define PHYSFS_PLATFORM_UNIX 1
|
||||||
|
# define PHYSFS_PLATFORM_POSIX 1
|
||||||
|
#elif defined(__EMSCRIPTEN__)
|
||||||
|
# define PHYSFS_NO_CDROM_SUPPORT 1
|
||||||
|
# define PHYSFS_PLATFORM_UNIX 1
|
||||||
|
# define PHYSFS_PLATFORM_POSIX 1
|
||||||
|
#elif defined(__QNX__)
|
||||||
|
# define PHYSFS_PLATFORM_QNX 1
|
||||||
|
# define PHYSFS_PLATFORM_POSIX 1
|
||||||
|
#elif defined(unix) || defined(__unix__)
|
||||||
|
# define PHYSFS_PLATFORM_UNIX 1
|
||||||
|
# define PHYSFS_PLATFORM_POSIX 1
|
||||||
|
#else
|
||||||
|
# error Unknown platform.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* include-once blocker. */
|
||||||
|
|
||||||
567
desktop_version/physfs/physfs_unicode.c
Normal file
567
desktop_version/physfs/physfs_unicode.c
Normal file
@@ -0,0 +1,567 @@
|
|||||||
|
#define __PHYSICSFS_INTERNAL__
|
||||||
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
|
#include "physfs_casefolding.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* From rfc3629, the UTF-8 spec:
|
||||||
|
* https://www.ietf.org/rfc/rfc3629.txt
|
||||||
|
*
|
||||||
|
* Char. number range | UTF-8 octet sequence
|
||||||
|
* (hexadecimal) | (binary)
|
||||||
|
* --------------------+---------------------------------------------
|
||||||
|
* 0000 0000-0000 007F | 0xxxxxxx
|
||||||
|
* 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
|
||||||
|
* 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
|
||||||
|
* 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This may not be the best value, but it's one that isn't represented
|
||||||
|
* in Unicode (0x10FFFF is the largest codepoint value). We return this
|
||||||
|
* value from utf8codepoint() if there's bogus bits in the
|
||||||
|
* stream. utf8codepoint() will turn this value into something
|
||||||
|
* reasonable (like a question mark), for text that wants to try to recover,
|
||||||
|
* whereas utf8valid() will use the value to determine if a string has bad
|
||||||
|
* bits.
|
||||||
|
*/
|
||||||
|
#define UNICODE_BOGUS_CHAR_VALUE 0xFFFFFFFF
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the codepoint we currently return when there was bogus bits in a
|
||||||
|
* UTF-8 string. May not fly in Asian locales?
|
||||||
|
*/
|
||||||
|
#define UNICODE_BOGUS_CHAR_CODEPOINT '?'
|
||||||
|
|
||||||
|
static PHYSFS_uint32 utf8codepoint(const char **_str)
|
||||||
|
{
|
||||||
|
const char *str = *_str;
|
||||||
|
PHYSFS_uint32 retval = 0;
|
||||||
|
PHYSFS_uint32 octet = (PHYSFS_uint32) ((PHYSFS_uint8) *str);
|
||||||
|
PHYSFS_uint32 octet2, octet3, octet4;
|
||||||
|
|
||||||
|
if (octet == 0) /* null terminator, end of string. */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
else if (octet < 128) /* one octet char: 0 to 127 */
|
||||||
|
{
|
||||||
|
(*_str)++; /* skip to next possible start of codepoint. */
|
||||||
|
return octet;
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else if ((octet > 127) && (octet < 192)) /* bad (starts with 10xxxxxx). */
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Apparently each of these is supposed to be flagged as a bogus
|
||||||
|
* char, instead of just resyncing to the next valid codepoint.
|
||||||
|
*/
|
||||||
|
(*_str)++; /* skip to next possible start of codepoint. */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else if (octet < 224) /* two octets */
|
||||||
|
{
|
||||||
|
(*_str)++; /* advance at least one byte in case of an error */
|
||||||
|
octet -= (128+64);
|
||||||
|
octet2 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet2 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
*_str += 1; /* skip to next possible start of codepoint. */
|
||||||
|
retval = ((octet << 6) | (octet2 - 128));
|
||||||
|
if ((retval >= 0x80) && (retval <= 0x7FF))
|
||||||
|
return retval;
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else if (octet < 240) /* three octets */
|
||||||
|
{
|
||||||
|
(*_str)++; /* advance at least one byte in case of an error */
|
||||||
|
octet -= (128+64+32);
|
||||||
|
octet2 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet2 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
octet3 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet3 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
*_str += 2; /* skip to next possible start of codepoint. */
|
||||||
|
retval = ( ((octet << 12)) | ((octet2-128) << 6) | ((octet3-128)) );
|
||||||
|
|
||||||
|
/* There are seven "UTF-16 surrogates" that are illegal in UTF-8. */
|
||||||
|
switch (retval)
|
||||||
|
{
|
||||||
|
case 0xD800:
|
||||||
|
case 0xDB7F:
|
||||||
|
case 0xDB80:
|
||||||
|
case 0xDBFF:
|
||||||
|
case 0xDC00:
|
||||||
|
case 0xDF80:
|
||||||
|
case 0xDFFF:
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
} /* switch */
|
||||||
|
|
||||||
|
/* 0xFFFE and 0xFFFF are illegal, too, so we check them at the edge. */
|
||||||
|
if ((retval >= 0x800) && (retval <= 0xFFFD))
|
||||||
|
return retval;
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else if (octet < 248) /* four octets */
|
||||||
|
{
|
||||||
|
(*_str)++; /* advance at least one byte in case of an error */
|
||||||
|
octet -= (128+64+32+16);
|
||||||
|
octet2 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet2 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
octet3 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet3 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
octet4 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet4 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
*_str += 3; /* skip to next possible start of codepoint. */
|
||||||
|
retval = ( ((octet << 18)) | ((octet2 - 128) << 12) |
|
||||||
|
((octet3 - 128) << 6) | ((octet4 - 128)) );
|
||||||
|
if ((retval >= 0x10000) && (retval <= 0x10FFFF))
|
||||||
|
return retval;
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Five and six octet sequences became illegal in rfc3629.
|
||||||
|
* We throw the codepoint away, but parse them to make sure we move
|
||||||
|
* ahead the right number of bytes and don't overflow the buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
else if (octet < 252) /* five octets */
|
||||||
|
{
|
||||||
|
(*_str)++; /* advance at least one byte in case of an error */
|
||||||
|
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
*_str += 4; /* skip to next possible start of codepoint. */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else /* six octets */
|
||||||
|
{
|
||||||
|
(*_str)++; /* advance at least one byte in case of an error */
|
||||||
|
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
|
||||||
|
if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
|
||||||
|
*_str += 6; /* skip to next possible start of codepoint. */
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
return UNICODE_BOGUS_CHAR_VALUE;
|
||||||
|
} /* utf8codepoint */
|
||||||
|
|
||||||
|
static PHYSFS_uint32 utf16codepoint(const PHYSFS_uint16 **_str)
|
||||||
|
{
|
||||||
|
const PHYSFS_uint16 *src = *_str;
|
||||||
|
PHYSFS_uint32 cp = (PHYSFS_uint32) *(src++);
|
||||||
|
|
||||||
|
if (cp == 0) /* null terminator, end of string. */
|
||||||
|
return 0;
|
||||||
|
/* Orphaned second half of surrogate pair? */
|
||||||
|
else if ((cp >= 0xDC00) && (cp <= 0xDFFF))
|
||||||
|
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||||
|
else if ((cp >= 0xD800) && (cp <= 0xDBFF)) /* start surrogate pair! */
|
||||||
|
{
|
||||||
|
const PHYSFS_uint32 pair = (PHYSFS_uint32) *src;
|
||||||
|
if (pair == 0)
|
||||||
|
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||||
|
else if ((pair < 0xDC00) || (pair > 0xDFFF))
|
||||||
|
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src++; /* eat the other surrogate. */
|
||||||
|
cp = (((cp - 0xD800) << 10) | (pair - 0xDC00));
|
||||||
|
} /* else */
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
*_str = src;
|
||||||
|
return cp;
|
||||||
|
} /* utf16codepoint */
|
||||||
|
|
||||||
|
static PHYSFS_uint32 utf32codepoint(const PHYSFS_uint32 **_str)
|
||||||
|
{
|
||||||
|
const PHYSFS_uint32 *src = *_str;
|
||||||
|
PHYSFS_uint32 cp = *(src++);
|
||||||
|
|
||||||
|
if (cp == 0) /* null terminator, end of string. */
|
||||||
|
return 0;
|
||||||
|
else if (cp > 0x10FFF)
|
||||||
|
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||||
|
|
||||||
|
*_str = src;
|
||||||
|
return cp;
|
||||||
|
} /* utf32codepoint */
|
||||||
|
|
||||||
|
|
||||||
|
void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len)
|
||||||
|
{
|
||||||
|
len -= sizeof (PHYSFS_uint32); /* save room for null char. */
|
||||||
|
while (len >= sizeof (PHYSFS_uint32))
|
||||||
|
{
|
||||||
|
PHYSFS_uint32 cp = utf8codepoint(&src);
|
||||||
|
if (cp == 0)
|
||||||
|
break;
|
||||||
|
else if (cp == UNICODE_BOGUS_CHAR_VALUE)
|
||||||
|
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||||
|
*(dst++) = cp;
|
||||||
|
len -= sizeof (PHYSFS_uint32);
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
*dst = 0;
|
||||||
|
} /* PHYSFS_utf8ToUcs4 */
|
||||||
|
|
||||||
|
|
||||||
|
void PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
|
||||||
|
{
|
||||||
|
len -= sizeof (PHYSFS_uint16); /* save room for null char. */
|
||||||
|
while (len >= sizeof (PHYSFS_uint16))
|
||||||
|
{
|
||||||
|
PHYSFS_uint32 cp = utf8codepoint(&src);
|
||||||
|
if (cp == 0)
|
||||||
|
break;
|
||||||
|
else if (cp == UNICODE_BOGUS_CHAR_VALUE)
|
||||||
|
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||||
|
|
||||||
|
if (cp > 0xFFFF) /* UTF-16 surrogates (bogus chars in UCS-2) */
|
||||||
|
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||||
|
|
||||||
|
*(dst++) = cp;
|
||||||
|
len -= sizeof (PHYSFS_uint16);
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
*dst = 0;
|
||||||
|
} /* PHYSFS_utf8ToUcs2 */
|
||||||
|
|
||||||
|
|
||||||
|
void PHYSFS_utf8ToUtf16(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
|
||||||
|
{
|
||||||
|
len -= sizeof (PHYSFS_uint16); /* save room for null char. */
|
||||||
|
while (len >= sizeof (PHYSFS_uint16))
|
||||||
|
{
|
||||||
|
PHYSFS_uint32 cp = utf8codepoint(&src);
|
||||||
|
if (cp == 0)
|
||||||
|
break;
|
||||||
|
else if (cp == UNICODE_BOGUS_CHAR_VALUE)
|
||||||
|
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||||
|
|
||||||
|
if (cp > 0xFFFF) /* encode as surrogate pair */
|
||||||
|
{
|
||||||
|
if (len < (sizeof (PHYSFS_uint16) * 2))
|
||||||
|
break; /* not enough room for the pair, stop now. */
|
||||||
|
|
||||||
|
cp -= 0x10000; /* Make this a 20-bit value */
|
||||||
|
|
||||||
|
*(dst++) = 0xD800 + ((cp >> 10) & 0x3FF);
|
||||||
|
len -= sizeof (PHYSFS_uint16);
|
||||||
|
|
||||||
|
cp = 0xDC00 + (cp & 0x3FF);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
*(dst++) = cp;
|
||||||
|
len -= sizeof (PHYSFS_uint16);
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
*dst = 0;
|
||||||
|
} /* PHYSFS_utf8ToUtf16 */
|
||||||
|
|
||||||
|
static void utf8fromcodepoint(PHYSFS_uint32 cp, char **_dst, PHYSFS_uint64 *_len)
|
||||||
|
{
|
||||||
|
char *dst = *_dst;
|
||||||
|
PHYSFS_uint64 len = *_len;
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cp > 0x10FFFF)
|
||||||
|
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||||
|
else if ((cp == 0xFFFE) || (cp == 0xFFFF)) /* illegal values. */
|
||||||
|
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* There are seven "UTF-16 surrogates" that are illegal in UTF-8. */
|
||||||
|
switch (cp)
|
||||||
|
{
|
||||||
|
case 0xD800:
|
||||||
|
case 0xDB7F:
|
||||||
|
case 0xDB80:
|
||||||
|
case 0xDBFF:
|
||||||
|
case 0xDC00:
|
||||||
|
case 0xDF80:
|
||||||
|
case 0xDFFF:
|
||||||
|
cp = UNICODE_BOGUS_CHAR_CODEPOINT;
|
||||||
|
} /* switch */
|
||||||
|
} /* else */
|
||||||
|
|
||||||
|
/* Do the encoding... */
|
||||||
|
if (cp < 0x80)
|
||||||
|
{
|
||||||
|
*(dst++) = (char) cp;
|
||||||
|
len--;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
else if (cp < 0x800)
|
||||||
|
{
|
||||||
|
if (len < 2)
|
||||||
|
len = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*(dst++) = (char) ((cp >> 6) | 128 | 64);
|
||||||
|
*(dst++) = (char) (cp & 0x3F) | 128;
|
||||||
|
len -= 2;
|
||||||
|
} /* else */
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else if (cp < 0x10000)
|
||||||
|
{
|
||||||
|
if (len < 3)
|
||||||
|
len = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*(dst++) = (char) ((cp >> 12) | 128 | 64 | 32);
|
||||||
|
*(dst++) = (char) ((cp >> 6) & 0x3F) | 128;
|
||||||
|
*(dst++) = (char) (cp & 0x3F) | 128;
|
||||||
|
len -= 3;
|
||||||
|
} /* else */
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (len < 4)
|
||||||
|
len = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*(dst++) = (char) ((cp >> 18) | 128 | 64 | 32 | 16);
|
||||||
|
*(dst++) = (char) ((cp >> 12) & 0x3F) | 128;
|
||||||
|
*(dst++) = (char) ((cp >> 6) & 0x3F) | 128;
|
||||||
|
*(dst++) = (char) (cp & 0x3F) | 128;
|
||||||
|
len -= 4;
|
||||||
|
} /* else if */
|
||||||
|
} /* else */
|
||||||
|
|
||||||
|
*_dst = dst;
|
||||||
|
*_len = len;
|
||||||
|
} /* utf8fromcodepoint */
|
||||||
|
|
||||||
|
#define UTF8FROMTYPE(typ, src, dst, len) \
|
||||||
|
if (len == 0) return; \
|
||||||
|
len--; \
|
||||||
|
while (len) \
|
||||||
|
{ \
|
||||||
|
const PHYSFS_uint32 cp = (PHYSFS_uint32) ((typ) (*(src++))); \
|
||||||
|
if (cp == 0) break; \
|
||||||
|
utf8fromcodepoint(cp, &dst, &len); \
|
||||||
|
} \
|
||||||
|
*dst = '\0'; \
|
||||||
|
|
||||||
|
void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst, PHYSFS_uint64 len)
|
||||||
|
{
|
||||||
|
UTF8FROMTYPE(PHYSFS_uint32, src, dst, len);
|
||||||
|
} /* PHYSFS_utf8FromUcs4 */
|
||||||
|
|
||||||
|
void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
|
||||||
|
{
|
||||||
|
UTF8FROMTYPE(PHYSFS_uint64, src, dst, len);
|
||||||
|
} /* PHYSFS_utf8FromUcs2 */
|
||||||
|
|
||||||
|
/* latin1 maps to unicode codepoints directly, we just utf-8 encode it. */
|
||||||
|
void PHYSFS_utf8FromLatin1(const char *src, char *dst, PHYSFS_uint64 len)
|
||||||
|
{
|
||||||
|
UTF8FROMTYPE(PHYSFS_uint8, src, dst, len);
|
||||||
|
} /* PHYSFS_utf8FromLatin1 */
|
||||||
|
|
||||||
|
#undef UTF8FROMTYPE
|
||||||
|
|
||||||
|
|
||||||
|
void PHYSFS_utf8FromUtf16(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
|
||||||
|
{
|
||||||
|
if (len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
len--;
|
||||||
|
while (len)
|
||||||
|
{
|
||||||
|
const PHYSFS_uint32 cp = utf16codepoint(&src);
|
||||||
|
if (!cp)
|
||||||
|
break;
|
||||||
|
utf8fromcodepoint(cp, &dst, &len);
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
*dst = '\0';
|
||||||
|
} /* PHYSFS_utf8FromUtf16 */
|
||||||
|
|
||||||
|
|
||||||
|
int PHYSFS_caseFold(const PHYSFS_uint32 from, PHYSFS_uint32 *to)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (from < 128) /* low-ASCII, easy! */
|
||||||
|
{
|
||||||
|
if ((from >= 'A') && (from <= 'Z'))
|
||||||
|
*to = from - ('A' - 'a');
|
||||||
|
else
|
||||||
|
*to = from;
|
||||||
|
return 1;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
else if (from <= 0xFFFF)
|
||||||
|
{
|
||||||
|
const PHYSFS_uint8 hash = ((from ^ (from >> 8)) & 0xFF);
|
||||||
|
const PHYSFS_uint16 from16 = (PHYSFS_uint16) from;
|
||||||
|
|
||||||
|
{
|
||||||
|
const CaseFoldHashBucket1_16 *bucket = &case_fold_hash1_16[hash];
|
||||||
|
const int count = (int) bucket->count;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
const CaseFoldMapping1_16 *mapping = &bucket->list[i];
|
||||||
|
if (mapping->from == from16)
|
||||||
|
{
|
||||||
|
*to = mapping->to0;
|
||||||
|
return 1;
|
||||||
|
} /* if */
|
||||||
|
} /* for */
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const CaseFoldHashBucket2_16 *bucket = &case_fold_hash2_16[hash & 15];
|
||||||
|
const int count = (int) bucket->count;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
const CaseFoldMapping2_16 *mapping = &bucket->list[i];
|
||||||
|
if (mapping->from == from16)
|
||||||
|
{
|
||||||
|
to[0] = mapping->to0;
|
||||||
|
to[1] = mapping->to1;
|
||||||
|
return 2;
|
||||||
|
} /* if */
|
||||||
|
} /* for */
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const CaseFoldHashBucket3_16 *bucket = &case_fold_hash3_16[hash & 3];
|
||||||
|
const int count = (int) bucket->count;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
const CaseFoldMapping3_16 *mapping = &bucket->list[i];
|
||||||
|
if (mapping->from == from16)
|
||||||
|
{
|
||||||
|
to[0] = mapping->to0;
|
||||||
|
to[1] = mapping->to1;
|
||||||
|
to[2] = mapping->to2;
|
||||||
|
return 3;
|
||||||
|
} /* if */
|
||||||
|
} /* for */
|
||||||
|
}
|
||||||
|
} /* else if */
|
||||||
|
|
||||||
|
else /* codepoint that doesn't fit in 16 bits. */
|
||||||
|
{
|
||||||
|
const PHYSFS_uint8 hash = ((from ^ (from >> 8)) & 0xFF);
|
||||||
|
const CaseFoldHashBucket1_32 *bucket = &case_fold_hash1_32[hash & 15];
|
||||||
|
const int count = (int) bucket->count;
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
const CaseFoldMapping1_32 *mapping = &bucket->list[i];
|
||||||
|
if (mapping->from == from)
|
||||||
|
{
|
||||||
|
*to = mapping->to0;
|
||||||
|
return 1;
|
||||||
|
} /* if */
|
||||||
|
} /* for */
|
||||||
|
} /* else */
|
||||||
|
|
||||||
|
|
||||||
|
/* Not found...there's no remapping for this codepoint. */
|
||||||
|
*to = from;
|
||||||
|
return 1;
|
||||||
|
} /* PHYSFS_caseFold */
|
||||||
|
|
||||||
|
|
||||||
|
#define UTFSTRICMP(bits) \
|
||||||
|
PHYSFS_uint32 folded1[3], folded2[3]; \
|
||||||
|
int head1 = 0, tail1 = 0, head2 = 0, tail2 = 0; \
|
||||||
|
while (1) { \
|
||||||
|
PHYSFS_uint32 cp1, cp2; \
|
||||||
|
if (head1 != tail1) { \
|
||||||
|
cp1 = folded1[tail1++]; \
|
||||||
|
} else { \
|
||||||
|
head1 = PHYSFS_caseFold(utf##bits##codepoint(&str1), folded1); \
|
||||||
|
cp1 = folded1[0]; \
|
||||||
|
tail1 = 1; \
|
||||||
|
} \
|
||||||
|
if (head2 != tail2) { \
|
||||||
|
cp2 = folded2[tail2++]; \
|
||||||
|
} else { \
|
||||||
|
head2 = PHYSFS_caseFold(utf##bits##codepoint(&str2), folded2); \
|
||||||
|
cp2 = folded2[0]; \
|
||||||
|
tail2 = 1; \
|
||||||
|
} \
|
||||||
|
if (cp1 < cp2) { \
|
||||||
|
return -1; \
|
||||||
|
} else if (cp1 > cp2) { \
|
||||||
|
return 1; \
|
||||||
|
} else if (cp1 == 0) { \
|
||||||
|
break; /* complete match. */ \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
return 0
|
||||||
|
|
||||||
|
int PHYSFS_utf8stricmp(const char *str1, const char *str2)
|
||||||
|
{
|
||||||
|
UTFSTRICMP(8);
|
||||||
|
} /* PHYSFS_utf8stricmp */
|
||||||
|
|
||||||
|
int PHYSFS_utf16stricmp(const PHYSFS_uint16 *str1, const PHYSFS_uint16 *str2)
|
||||||
|
{
|
||||||
|
UTFSTRICMP(16);
|
||||||
|
} /* PHYSFS_utf16stricmp */
|
||||||
|
|
||||||
|
int PHYSFS_ucs4stricmp(const PHYSFS_uint32 *str1, const PHYSFS_uint32 *str2)
|
||||||
|
{
|
||||||
|
UTFSTRICMP(32);
|
||||||
|
} /* PHYSFS_ucs4stricmp */
|
||||||
|
|
||||||
|
#undef UTFSTRICMP
|
||||||
|
|
||||||
|
/* end of physfs_unicode.c ... */
|
||||||
|
|
||||||
145
desktop_version/src/BinaryBlob.cpp
Normal file
145
desktop_version/src/BinaryBlob.cpp
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
#include "BinaryBlob.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* FIXME: Abstract to FileSystemUtils! */
|
||||||
|
#include <physfs.h>
|
||||||
|
|
||||||
|
binaryBlob::binaryBlob()
|
||||||
|
{
|
||||||
|
numberofHeaders = 0;
|
||||||
|
for (int i = 0; i < 128; i += 1)
|
||||||
|
{
|
||||||
|
m_headers[i].valid = false;
|
||||||
|
|
||||||
|
for (int j = 0; j < 48; j += 1)
|
||||||
|
{
|
||||||
|
m_headers[i].name[j] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef VVV_COMPILEMUSIC
|
||||||
|
void binaryBlob::AddFileToBinaryBlob(const char* _path)
|
||||||
|
{
|
||||||
|
long size;
|
||||||
|
char * memblock;
|
||||||
|
|
||||||
|
FILE *file = fopen(_path, "rb");
|
||||||
|
if (file != NULL)
|
||||||
|
{
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
size = ftell(file);
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
memblock = (char*) malloc(size);
|
||||||
|
fread(memblock, 1, size, file);
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
printf("The complete file size: %li\n", size);
|
||||||
|
|
||||||
|
m_memblocks[numberofHeaders] = memblock;
|
||||||
|
for (int i = 0; _path[i]; i += 1)
|
||||||
|
{
|
||||||
|
m_headers[numberofHeaders].name[i] = _path[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_headers[numberofHeaders].valid = true;
|
||||||
|
m_headers[numberofHeaders].size = size;
|
||||||
|
numberofHeaders += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Unable to open file\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void binaryBlob::writeBinaryBlob(const char* _name)
|
||||||
|
{
|
||||||
|
FILE *file = fopen(_name, "wb");
|
||||||
|
if (file != NULL)
|
||||||
|
{
|
||||||
|
fwrite((char*) &m_headers, 1, sizeof(resourceheader) * 128, file);
|
||||||
|
|
||||||
|
for (int i = 0; i < numberofHeaders; i += 1)
|
||||||
|
{
|
||||||
|
fwrite(m_memblocks[i], 1, m_headers[i].size, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Unable to open new file for writing. Feels bad.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool binaryBlob::unPackBinary(const char* name)
|
||||||
|
{
|
||||||
|
PHYSFS_sint64 size;
|
||||||
|
|
||||||
|
PHYSFS_File *handle = PHYSFS_openRead(name);
|
||||||
|
if (handle == NULL)
|
||||||
|
{
|
||||||
|
printf("Unable to open file %s\n", name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = PHYSFS_fileLength(handle);
|
||||||
|
|
||||||
|
PHYSFS_read(handle, &m_headers, 1, sizeof(resourceheader) * 128);
|
||||||
|
|
||||||
|
int offset = 0 + (sizeof(resourceheader) * 128);
|
||||||
|
|
||||||
|
for (int i = 0; i < 128; i += 1)
|
||||||
|
{
|
||||||
|
if (m_headers[i].valid)
|
||||||
|
{
|
||||||
|
PHYSFS_seek(handle, offset);
|
||||||
|
m_memblocks[i] = (char*) malloc(m_headers[i].size);
|
||||||
|
PHYSFS_read(handle, m_memblocks[i], 1, m_headers[i].size);
|
||||||
|
offset += m_headers[i].size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PHYSFS_close(handle);
|
||||||
|
|
||||||
|
printf("The complete reloaded file size: %li\n", size);
|
||||||
|
|
||||||
|
for (int i = 0; i < 128; i += 1)
|
||||||
|
{
|
||||||
|
if (m_headers[i].valid == false)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s unpacked\n", m_headers[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int binaryBlob::getIndex(const char* _name)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 128; i += 1)
|
||||||
|
{
|
||||||
|
if (strcmp(_name, m_headers[i].name) == 0)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int binaryBlob::getSize(int _index)
|
||||||
|
{
|
||||||
|
return m_headers[_index].size;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* binaryBlob::getAddress(int _index)
|
||||||
|
{
|
||||||
|
return m_memblocks[_index];
|
||||||
|
}
|
||||||
41
desktop_version/src/BinaryBlob.h
Normal file
41
desktop_version/src/BinaryBlob.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef BINARYBLOB_H
|
||||||
|
#define BINARYBLOB_H
|
||||||
|
|
||||||
|
/* Laaaazyyyyyyy -flibit */
|
||||||
|
// #define VVV_COMPILEMUSIC
|
||||||
|
|
||||||
|
struct resourceheader
|
||||||
|
{
|
||||||
|
char name[48];
|
||||||
|
int start;
|
||||||
|
int size;
|
||||||
|
bool valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
class binaryBlob
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
binaryBlob();
|
||||||
|
|
||||||
|
#ifdef VVV_COMPILEMUSIC
|
||||||
|
void AddFileToBinaryBlob(const char* _path);
|
||||||
|
|
||||||
|
void writeBinaryBlob(const char* _name);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool unPackBinary(const char* _name);
|
||||||
|
|
||||||
|
int getIndex(const char* _name);
|
||||||
|
|
||||||
|
int getSize(int _index);
|
||||||
|
|
||||||
|
char* getAddress(int _index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int numberofHeaders;
|
||||||
|
resourceheader m_headers[128];
|
||||||
|
char* m_memblocks[128];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* BINARYBLOB_H */
|
||||||
36
desktop_version/src/BlockV.cpp
Normal file
36
desktop_version/src/BlockV.cpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include "BlockV.h"
|
||||||
|
|
||||||
|
blockclass::blockclass()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void blockclass::clear()
|
||||||
|
{
|
||||||
|
active = false;
|
||||||
|
type = 0;
|
||||||
|
trigger = 0;
|
||||||
|
|
||||||
|
xp = 0;
|
||||||
|
yp = 0;
|
||||||
|
wp = 0;
|
||||||
|
hp = 0;
|
||||||
|
rect.x = xp;
|
||||||
|
rect.y = yp;
|
||||||
|
rect.w = wp;
|
||||||
|
rect.h = hp;
|
||||||
|
|
||||||
|
prompt = "";
|
||||||
|
script = "";
|
||||||
|
r = 0;
|
||||||
|
g = 0;
|
||||||
|
b = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void blockclass::rectset(const int xi, const int yi, const int wi, const int hi)
|
||||||
|
{
|
||||||
|
rect.x = xi;
|
||||||
|
rect.y = yi;
|
||||||
|
rect.w = wi;
|
||||||
|
rect.h = hi;
|
||||||
|
}
|
||||||
31
desktop_version/src/BlockV.h
Normal file
31
desktop_version/src/BlockV.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef BLOCKV_H
|
||||||
|
#define BLOCKV_H
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class blockclass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
blockclass();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
void rectset(const int xi, const int yi, const int wi, const int hi);
|
||||||
|
public:
|
||||||
|
//Fundamentals
|
||||||
|
bool active;
|
||||||
|
SDL_Rect rect;
|
||||||
|
int type;
|
||||||
|
int trigger;
|
||||||
|
int xp, yp, wp, hp;
|
||||||
|
std::string script, prompt;
|
||||||
|
int r, g, b;
|
||||||
|
|
||||||
|
//These would come from the sprite in the flash
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* BLOCKV_H */
|
||||||
88
desktop_version/src/Ent.cpp
Normal file
88
desktop_version/src/Ent.cpp
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#include "Ent.h"
|
||||||
|
|
||||||
|
entclass::entclass()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void entclass::clear()
|
||||||
|
{
|
||||||
|
// Set all values to a default, required for creating a new entity
|
||||||
|
active = false;
|
||||||
|
invis = false;
|
||||||
|
type = 0;
|
||||||
|
size = 0;
|
||||||
|
tile = 0;
|
||||||
|
rule = 0;
|
||||||
|
state = 0;
|
||||||
|
statedelay = 0;
|
||||||
|
life = 0;
|
||||||
|
colour = 0;
|
||||||
|
para = 0;
|
||||||
|
behave = 0;
|
||||||
|
animate = 0;
|
||||||
|
|
||||||
|
xp = 0;
|
||||||
|
yp = 0;
|
||||||
|
ax = 0;
|
||||||
|
ay = 0;
|
||||||
|
vx = 0;
|
||||||
|
vy = 0;
|
||||||
|
w = 16;
|
||||||
|
h = 16;
|
||||||
|
cx = 0;
|
||||||
|
cy = 0;
|
||||||
|
newxp = 0;
|
||||||
|
newyp = 0;
|
||||||
|
|
||||||
|
x1 = 0;
|
||||||
|
y1 = 0;
|
||||||
|
x2 = 320;
|
||||||
|
y2 = 240;
|
||||||
|
|
||||||
|
jumping = false;
|
||||||
|
gravity = false;
|
||||||
|
onground = 0;
|
||||||
|
onroof = 0;
|
||||||
|
jumpframe = 0;
|
||||||
|
|
||||||
|
onentity = 0;
|
||||||
|
harmful = false;
|
||||||
|
onwall = 0;
|
||||||
|
onxwall = 0;
|
||||||
|
onywall = 0;
|
||||||
|
isplatform = false;
|
||||||
|
|
||||||
|
framedelay = 0;
|
||||||
|
drawframe = 0;
|
||||||
|
walkingframe = 0;
|
||||||
|
dir = 0;
|
||||||
|
actionframe = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool entclass::outside()
|
||||||
|
{
|
||||||
|
// Returns true if any point of the entity is outside the map.
|
||||||
|
// Adjusts velocity for a clean collision.
|
||||||
|
if (xp < x1)
|
||||||
|
{
|
||||||
|
xp = x1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (yp < y1)
|
||||||
|
{
|
||||||
|
yp = y1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (xp + w > x2)
|
||||||
|
{
|
||||||
|
xp = x2 - w;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (yp + h > y2)
|
||||||
|
{
|
||||||
|
yp = y2 - h;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
44
desktop_version/src/Ent.h
Normal file
44
desktop_version/src/Ent.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#ifndef ENT_H
|
||||||
|
#define ENT_H
|
||||||
|
|
||||||
|
class entclass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
entclass();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
bool outside();
|
||||||
|
|
||||||
|
public:
|
||||||
|
//Fundamentals
|
||||||
|
bool active, invis;
|
||||||
|
int type, size, tile, rule;
|
||||||
|
int state, statedelay;
|
||||||
|
int behave, animate;
|
||||||
|
float para;
|
||||||
|
int life, colour;
|
||||||
|
|
||||||
|
//Position and velocity
|
||||||
|
int oldxp, oldyp;
|
||||||
|
float ax, ay, vx, vy;
|
||||||
|
int cx, cy, w, h;
|
||||||
|
float newxp, newyp;
|
||||||
|
bool isplatform;
|
||||||
|
int x1,y1,x2,y2;
|
||||||
|
//Collision Rules
|
||||||
|
int onentity;
|
||||||
|
bool harmful;
|
||||||
|
int onwall, onxwall, onywall;
|
||||||
|
|
||||||
|
//Platforming specific
|
||||||
|
bool jumping;
|
||||||
|
bool gravity;
|
||||||
|
int onground, onroof;
|
||||||
|
int jumpframe;
|
||||||
|
//Animation
|
||||||
|
int framedelay, drawframe, walkingframe, dir, actionframe;
|
||||||
|
int yp;int xp;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* ENT_H */
|
||||||
5528
desktop_version/src/Entity.cpp
Normal file
5528
desktop_version/src/Entity.cpp
Normal file
File diff suppressed because it is too large
Load Diff
245
desktop_version/src/Entity.h
Normal file
245
desktop_version/src/Entity.h
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
#ifndef ENTITY_H
|
||||||
|
#define ENTITY_H
|
||||||
|
|
||||||
|
#include "Maths.h"
|
||||||
|
#include "Ent.h"
|
||||||
|
#include "BlockV.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define rn( rx, ry) ((rx) + ((ry) * 100))
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BLOCK = 0,
|
||||||
|
TRIGGER = 1,
|
||||||
|
DAMAGE = 2,
|
||||||
|
DIRECTIONAL = 3,
|
||||||
|
SAFE = 4,
|
||||||
|
ACTIVITY = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
class mapclass;
|
||||||
|
class musicclass;
|
||||||
|
class Graphics;
|
||||||
|
class Game;
|
||||||
|
class UtilityClass;
|
||||||
|
|
||||||
|
class entityclass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void resetallflags();
|
||||||
|
|
||||||
|
void resetflags();
|
||||||
|
|
||||||
|
void confirmflags();
|
||||||
|
|
||||||
|
void changecollect(int t, int s);
|
||||||
|
|
||||||
|
void changecustomcollect(int t, int s);
|
||||||
|
|
||||||
|
void changeflag(int t, int s);
|
||||||
|
|
||||||
|
void fatal_top()
|
||||||
|
{
|
||||||
|
createblock(DAMAGE, -8, -8, 384, 16);
|
||||||
|
}
|
||||||
|
void fatal_bottom()
|
||||||
|
{
|
||||||
|
createblock(DAMAGE, -8, 224, 384, 16);
|
||||||
|
}
|
||||||
|
void fatal_left()
|
||||||
|
{
|
||||||
|
createblock(DAMAGE, -8, -8, 16, 260);
|
||||||
|
}
|
||||||
|
void fatal_right()
|
||||||
|
{
|
||||||
|
createblock(DAMAGE, 312, -8, 16, 260);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setblockcolour(int t, std::string col);
|
||||||
|
|
||||||
|
int swncolour(int t );
|
||||||
|
|
||||||
|
void swnenemiescol(int t);
|
||||||
|
|
||||||
|
void gravcreate(Game& game, int ypos, int dir, int xoff = 0, int yoff = 0);
|
||||||
|
|
||||||
|
void generateswnwave(Game& game, UtilityClass& help, int t);
|
||||||
|
|
||||||
|
void createblock(int t, int xp, int yp, int w, int h, int trig = 0);
|
||||||
|
|
||||||
|
void removeallblocks();
|
||||||
|
|
||||||
|
void removeblock(int t);
|
||||||
|
|
||||||
|
void removeblockat(int x, int y);
|
||||||
|
|
||||||
|
void removetrigger(int t);
|
||||||
|
|
||||||
|
void copylinecross(int t);
|
||||||
|
|
||||||
|
void revertlinecross(int t, int s);
|
||||||
|
|
||||||
|
bool gridmatch(int p1, int p2, int p3, int p4, int p11, int p21, int p31, int p41);
|
||||||
|
|
||||||
|
int crewcolour(int t);
|
||||||
|
|
||||||
|
void setenemyroom(int t, int rx, int ry);
|
||||||
|
|
||||||
|
void setenemy(int t, int r);
|
||||||
|
|
||||||
|
void settreadmillcolour(int t, int rx, int ry);
|
||||||
|
|
||||||
|
void createentity(Game& game, float xp, float yp, int t, float vx = 0, float vy = 0,
|
||||||
|
int p1 = 0, int p2 = 0, int p3 = 320, int p4 = 240 );
|
||||||
|
|
||||||
|
bool updateentities(int i, UtilityClass& help, Game& game, musicclass& music);
|
||||||
|
|
||||||
|
void animateentities(int i, Game& game, UtilityClass& help);
|
||||||
|
|
||||||
|
bool gettype(int t);
|
||||||
|
|
||||||
|
int getcompanion(int t);
|
||||||
|
|
||||||
|
int getplayer();
|
||||||
|
|
||||||
|
int getscm();
|
||||||
|
|
||||||
|
int getlineat(int t);
|
||||||
|
|
||||||
|
int getcrewman(int t);
|
||||||
|
int getcustomcrewman(int t);
|
||||||
|
|
||||||
|
int getteleporter();
|
||||||
|
|
||||||
|
void rectset(int xi, int yi, int wi, int hi);
|
||||||
|
|
||||||
|
void rect2set(int xi, int yi, int wi, int hi);
|
||||||
|
|
||||||
|
bool entitycollide(int a, int b);
|
||||||
|
|
||||||
|
bool checkdirectional(int t);
|
||||||
|
|
||||||
|
bool checkdamage();
|
||||||
|
|
||||||
|
bool scmcheckdamage();
|
||||||
|
|
||||||
|
void settemprect(int t);
|
||||||
|
|
||||||
|
int checktrigger();
|
||||||
|
|
||||||
|
int checkactivity();
|
||||||
|
|
||||||
|
int getgridpoint(int t);
|
||||||
|
|
||||||
|
bool cblocks(int t);
|
||||||
|
|
||||||
|
bool checkplatform();
|
||||||
|
|
||||||
|
bool checkblocks();
|
||||||
|
|
||||||
|
bool checktowerspikes(int t, mapclass& map);
|
||||||
|
|
||||||
|
bool checkwall(mapclass& map);
|
||||||
|
|
||||||
|
float hplatformat();
|
||||||
|
|
||||||
|
int yline(int a, int b);
|
||||||
|
|
||||||
|
bool entityhlinecollide(int t, int l);
|
||||||
|
|
||||||
|
bool entityvlinecollide(int t, int l);
|
||||||
|
|
||||||
|
bool entitywarphlinecollide(int t, int l);
|
||||||
|
bool entitywarpvlinecollide(int t, int l);
|
||||||
|
|
||||||
|
void customwarplinecheck(int i);
|
||||||
|
|
||||||
|
float entitycollideplatformroof(mapclass& map, int t);
|
||||||
|
|
||||||
|
float entitycollideplatformfloor(mapclass& map, int t);
|
||||||
|
|
||||||
|
bool entitycollidefloor(mapclass& map, int t);
|
||||||
|
|
||||||
|
bool entitycollideroof(mapclass& map, int t);
|
||||||
|
|
||||||
|
bool testwallsx(int t, mapclass& map, int tx, int ty);
|
||||||
|
|
||||||
|
bool testwallsy(int t, mapclass& map, float tx, float ty);
|
||||||
|
|
||||||
|
void fixfriction(int t, float xfix, float xrate, float yrate);
|
||||||
|
|
||||||
|
void applyfriction(int t, float xrate, float yrate);
|
||||||
|
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
void updateentitylogic(int t, Game& game);
|
||||||
|
|
||||||
|
|
||||||
|
void entitymapcollision(int t, mapclass& map);
|
||||||
|
|
||||||
|
void movingplatformfix(int t, mapclass& map);
|
||||||
|
|
||||||
|
void scmmovingplatformfix(int t, mapclass& map);
|
||||||
|
|
||||||
|
void hormovingplatformfix(int t, mapclass& map);
|
||||||
|
|
||||||
|
void entitycollisioncheck(Graphics& dwgfx, Game& game, mapclass& map, musicclass& music);
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<entclass> entities;
|
||||||
|
|
||||||
|
int nentity;
|
||||||
|
|
||||||
|
std::vector<entclass> linecrosskludge;
|
||||||
|
int nlinecrosskludge;
|
||||||
|
|
||||||
|
point colpoint1, colpoint2;
|
||||||
|
|
||||||
|
int tempx, tempy, tempw, temph, temp, temp2;
|
||||||
|
//public var tempx:int, tempy:int, tempw:int, temph:int, temp:int, temp2:int;
|
||||||
|
int tpx1, tpy1, tpx2, tpy2;
|
||||||
|
|
||||||
|
SDL_Rect temprect, temprect2;
|
||||||
|
|
||||||
|
int x, k;
|
||||||
|
float dx, dy, dr;
|
||||||
|
|
||||||
|
int px, py, linetemp;
|
||||||
|
int activetrigger;
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<blockclass> blocks;
|
||||||
|
std::vector<int> flags;
|
||||||
|
std::vector<int> collect;
|
||||||
|
std::vector<int> customcollect;
|
||||||
|
|
||||||
|
int nblocks;
|
||||||
|
bool skipblocks, skipdirblocks;
|
||||||
|
|
||||||
|
int platformtile;
|
||||||
|
bool vertplatforms, horplatforms;
|
||||||
|
|
||||||
|
// :(
|
||||||
|
bool nearelephant, upsetmode;
|
||||||
|
int upset;
|
||||||
|
|
||||||
|
//Trophy Text
|
||||||
|
int trophytext, trophytype;
|
||||||
|
|
||||||
|
//Secret lab scripts
|
||||||
|
int altstates;
|
||||||
|
|
||||||
|
//Custom stuff
|
||||||
|
int customenemy;
|
||||||
|
int customplatformtile;
|
||||||
|
bool customwarpmode, customwarpmodevon, customwarpmodehon;
|
||||||
|
std::string customscript;
|
||||||
|
int customcrewmoods[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* ENTITY_H */
|
||||||
11
desktop_version/src/Enums.h
Normal file
11
desktop_version/src/Enums.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef ENUMGAME_H
|
||||||
|
#define ENUMGAME_H
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
|
||||||
|
GAMEMODE, TITLEMODE, CLICKTOSTART, FOCUSMODE, MAPMODE, TELEPORTERMODE, GAMECOMPLETE, GAMECOMPLETE2, EDITORMODE, PRELOADER
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* ENUMGAME_H */
|
||||||
363
desktop_version/src/FileSystemUtils.cpp
Normal file
363
desktop_version/src/FileSystemUtils.cpp
Normal file
@@ -0,0 +1,363 @@
|
|||||||
|
#include "FileSystemUtils.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <physfs.h>
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
#include <shlobj.h>
|
||||||
|
#define mkdir(a, b) CreateDirectory(a, NULL)
|
||||||
|
#define VNEEDS_MIGRATION (mkdirResult != 0)
|
||||||
|
#elif defined(__linux__) || defined(__APPLE__)
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#define VNEEDS_MIGRATION (mkdirResult == 0)
|
||||||
|
/* These are needed for PLATFORM_* crap */
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#define MAX_PATH PATH_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char saveDir[MAX_PATH];
|
||||||
|
char levelDir[MAX_PATH];
|
||||||
|
|
||||||
|
void PLATFORM_getOSDirectory(char* output);
|
||||||
|
void PLATFORM_migrateSaveData(char* output);
|
||||||
|
void PLATFORM_copyFile(const char *oldLocation, const char *newLocation);
|
||||||
|
|
||||||
|
void FILESYSTEM_init(char *argvZero)
|
||||||
|
{
|
||||||
|
char output[MAX_PATH];
|
||||||
|
int mkdirResult;
|
||||||
|
|
||||||
|
PHYSFS_init(argvZero);
|
||||||
|
|
||||||
|
/* Determine the OS user directory */
|
||||||
|
PLATFORM_getOSDirectory(output);
|
||||||
|
|
||||||
|
/* Create base user directory, mount */
|
||||||
|
mkdirResult = mkdir(output, 0777);
|
||||||
|
|
||||||
|
/* Mount our base user directory */
|
||||||
|
PHYSFS_mount(output, NULL, 1);
|
||||||
|
printf("Base directory: %s\n", output);
|
||||||
|
|
||||||
|
/* Create save directory */
|
||||||
|
strcpy(saveDir, output);
|
||||||
|
strcat(saveDir, "saves");
|
||||||
|
strcat(saveDir, PHYSFS_getDirSeparator());
|
||||||
|
mkdir(saveDir, 0777);
|
||||||
|
printf("Save directory: %s\n", saveDir);
|
||||||
|
|
||||||
|
/* Create level directory */
|
||||||
|
strcpy(levelDir, output);
|
||||||
|
strcat(levelDir, "levels");
|
||||||
|
strcat(levelDir, PHYSFS_getDirSeparator());
|
||||||
|
mkdirResult |= mkdir(levelDir, 0777);
|
||||||
|
printf("Level directory: %s\n", levelDir);
|
||||||
|
|
||||||
|
/* We didn't exist until now, migrate files! */
|
||||||
|
if (VNEEDS_MIGRATION)
|
||||||
|
{
|
||||||
|
PLATFORM_migrateSaveData(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mount the stock content last */
|
||||||
|
#ifdef _WIN32
|
||||||
|
strcpy(output, PHYSFS_getBaseDir());
|
||||||
|
strcat(output, "data.zip");
|
||||||
|
#else
|
||||||
|
strcpy(output, "data.zip");
|
||||||
|
#endif
|
||||||
|
PHYSFS_mount(output, NULL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FILESYSTEM_deinit()
|
||||||
|
{
|
||||||
|
PHYSFS_deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
char *FILESYSTEM_getUserSaveDirectory()
|
||||||
|
{
|
||||||
|
return saveDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *FILESYSTEM_getUserLevelDirectory()
|
||||||
|
{
|
||||||
|
return levelDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FILESYSTEM_loadFileToMemory(const char *name, unsigned char **mem, size_t *len)
|
||||||
|
{
|
||||||
|
PHYSFS_File *handle = PHYSFS_openRead(name);
|
||||||
|
if (handle == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PHYSFS_uint32 length = PHYSFS_fileLength(handle);
|
||||||
|
if (len != NULL)
|
||||||
|
{
|
||||||
|
*len = length;
|
||||||
|
}
|
||||||
|
*mem = (unsigned char*) malloc(length);
|
||||||
|
PHYSFS_read(handle, *mem, 1, length);
|
||||||
|
PHYSFS_close(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FILESYSTEM_freeMemory(unsigned char **mem)
|
||||||
|
{
|
||||||
|
free(*mem);
|
||||||
|
*mem = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> FILESYSTEM_getLevelDirFileNames()
|
||||||
|
{
|
||||||
|
std::vector<std::string> list;
|
||||||
|
char **fileList = PHYSFS_enumerateFiles("/levels");
|
||||||
|
char **i;
|
||||||
|
std::string builtLocation;
|
||||||
|
|
||||||
|
for (i = fileList; *i != NULL; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(*i, "data") == 0)
|
||||||
|
{
|
||||||
|
continue; /* FIXME: lolwut -flibit */
|
||||||
|
}
|
||||||
|
builtLocation = "levels/";
|
||||||
|
builtLocation += *i;
|
||||||
|
list.push_back(builtLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
PHYSFS_freeList(fileList);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PLATFORM_getOSDirectory(char* output)
|
||||||
|
{
|
||||||
|
#if defined(__linux__)
|
||||||
|
const char *homeDir = getenv("XDG_DATA_HOME");
|
||||||
|
if (homeDir == NULL)
|
||||||
|
{
|
||||||
|
strcpy(output, PHYSFS_getUserDir());
|
||||||
|
strcat(output, ".local/share/VVVVVV/");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(output, homeDir);
|
||||||
|
strcat(output, "/VVVVVV/");
|
||||||
|
}
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
strcpy(output, PHYSFS_getUserDir());
|
||||||
|
strcat(output, "Library/Application Support/VVVVVV/");
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, output);
|
||||||
|
strcat(output, "\\VVVVVV\\");
|
||||||
|
#else
|
||||||
|
#error See PLATFORM_getOSDirectory
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void PLATFORM_migrateSaveData(char* output)
|
||||||
|
{
|
||||||
|
char oldLocation[MAX_PATH];
|
||||||
|
char newLocation[MAX_PATH];
|
||||||
|
char oldDirectory[MAX_PATH];
|
||||||
|
#if defined(__linux__) || defined(__APPLE__)
|
||||||
|
DIR *dir = NULL;
|
||||||
|
struct dirent *de = NULL;
|
||||||
|
DIR *subDir = NULL;
|
||||||
|
struct dirent *subDe = NULL;
|
||||||
|
char subDirLocation[MAX_PATH];
|
||||||
|
const char *homeDir = getenv("HOME");
|
||||||
|
if (homeDir == NULL)
|
||||||
|
{
|
||||||
|
/* Uhh, I don't want to get near this. -flibit */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
strcpy(oldDirectory, homeDir);
|
||||||
|
#if defined(__linux__)
|
||||||
|
strcat(oldDirectory, "/.vvvvvv/");
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
strcat(oldDirectory, "/Documents/VVVVVV/");
|
||||||
|
#endif
|
||||||
|
dir = opendir(oldDirectory);
|
||||||
|
if (!dir)
|
||||||
|
{
|
||||||
|
printf("Could not find directory %s\n", oldDirectory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Migrating old savedata to new location...\n");
|
||||||
|
for (de = readdir(dir); de != NULL; de = readdir(dir))
|
||||||
|
{
|
||||||
|
if ( strcmp(de->d_name, "..") == 0 ||
|
||||||
|
strcmp(de->d_name, ".") == 0 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#define COPY_SAVEFILE(name) \
|
||||||
|
else if (strcmp(de->d_name, name) == 0) \
|
||||||
|
{ \
|
||||||
|
strcpy(oldLocation, oldDirectory); \
|
||||||
|
strcat(oldLocation, name); \
|
||||||
|
strcpy(newLocation, output); \
|
||||||
|
strcat(newLocation, "saves/"); \
|
||||||
|
strcat(newLocation, name); \
|
||||||
|
PLATFORM_copyFile(oldLocation, newLocation); \
|
||||||
|
}
|
||||||
|
COPY_SAVEFILE("unlock.vvv")
|
||||||
|
COPY_SAVEFILE("tsave.vvv")
|
||||||
|
COPY_SAVEFILE("qsave.vvv")
|
||||||
|
#undef COPY_SAVEFILE
|
||||||
|
else if (strstr(de->d_name, ".vvvvvv.vvv") != NULL)
|
||||||
|
{
|
||||||
|
strcpy(oldLocation, oldDirectory);
|
||||||
|
strcat(oldLocation, de->d_name);
|
||||||
|
strcpy(newLocation, output);
|
||||||
|
strcat(newLocation, "saves/");
|
||||||
|
strcat(newLocation, de->d_name);
|
||||||
|
PLATFORM_copyFile(oldLocation, newLocation);
|
||||||
|
}
|
||||||
|
else if (strstr(de->d_name, ".vvvvvv") != NULL)
|
||||||
|
{
|
||||||
|
strcpy(oldLocation, oldDirectory);
|
||||||
|
strcat(oldLocation, de->d_name);
|
||||||
|
strcpy(newLocation, output);
|
||||||
|
strcat(newLocation, "levels/");
|
||||||
|
strcat(newLocation, de->d_name);
|
||||||
|
PLATFORM_copyFile(oldLocation, newLocation);
|
||||||
|
}
|
||||||
|
else if (strcmp(de->d_name, "Saves") == 0)
|
||||||
|
{
|
||||||
|
strcpy(subDirLocation, oldDirectory);
|
||||||
|
strcat(subDirLocation, "Saves/");
|
||||||
|
subDir = opendir(subDirLocation);
|
||||||
|
if (!subDir)
|
||||||
|
{
|
||||||
|
printf("Could not open Saves/ subdir!\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (
|
||||||
|
subDe = readdir(subDir);
|
||||||
|
subDe != NULL;
|
||||||
|
subDe = readdir(subDir)
|
||||||
|
) {
|
||||||
|
#define COPY_SAVEFILE(name) \
|
||||||
|
(strcmp(subDe->d_name, name) == 0) \
|
||||||
|
{ \
|
||||||
|
strcpy(oldLocation, subDirLocation); \
|
||||||
|
strcat(oldLocation, name); \
|
||||||
|
strcpy(newLocation, output); \
|
||||||
|
strcat(newLocation, "saves/"); \
|
||||||
|
strcat(newLocation, name); \
|
||||||
|
PLATFORM_copyFile(oldLocation, newLocation); \
|
||||||
|
}
|
||||||
|
if COPY_SAVEFILE("unlock.vvv")
|
||||||
|
else if COPY_SAVEFILE("tsave.vvv")
|
||||||
|
else if COPY_SAVEFILE("qsave.vvv")
|
||||||
|
#undef COPY_SAVEFILE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
WIN32_FIND_DATA findHandle;
|
||||||
|
HANDLE hFind = NULL;
|
||||||
|
char fileSearch[MAX_PATH];
|
||||||
|
|
||||||
|
/* Same place, different layout. */
|
||||||
|
strcpy(oldDirectory, output);
|
||||||
|
|
||||||
|
/* In theory we don't need to worry about this, thanks case insensitivity!
|
||||||
|
sprintf(fileSearch, "%s\\Saves\\*.vvv", oldDirectory);
|
||||||
|
hFind = FindFirstFile(fileSearch, &findHandle);
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
printf("Could not find directory %s\\Saves\\\n", oldDirectory);
|
||||||
|
}
|
||||||
|
else do
|
||||||
|
{
|
||||||
|
if ((findHandle.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
|
||||||
|
{
|
||||||
|
#define COPY_SAVEFILE(name) \
|
||||||
|
(strcmp(findHandle.cFileName, name) == 0) \
|
||||||
|
{ \
|
||||||
|
strcpy(oldLocation, oldDirectory); \
|
||||||
|
strcat(oldLocation, "Saves\\"); \
|
||||||
|
strcat(oldLocation, name); \
|
||||||
|
strcpy(newLocation, output); \
|
||||||
|
strcat(newLocation, "saves\\"); \
|
||||||
|
strcat(newLocation, name); \
|
||||||
|
PLATFORM_copyFile(oldLocation, newLocation); \
|
||||||
|
}
|
||||||
|
if COPY_SAVEFILE("unlock.vvv")
|
||||||
|
else if COPY_SAVEFILE("tsave.vvv")
|
||||||
|
else if COPY_SAVEFILE("qsave.vvv")
|
||||||
|
#undef COPY_SAVEFILE
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &findHandle));
|
||||||
|
*/
|
||||||
|
|
||||||
|
sprintf(fileSearch, "%s\\*.vvvvvv", oldDirectory);
|
||||||
|
hFind = FindFirstFile(fileSearch, &findHandle);
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
printf("Could not find directory %s\n", oldDirectory);
|
||||||
|
}
|
||||||
|
else do
|
||||||
|
{
|
||||||
|
if ((findHandle.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
|
||||||
|
{
|
||||||
|
strcpy(oldLocation, oldDirectory);
|
||||||
|
strcat(oldLocation, findHandle.cFileName);
|
||||||
|
strcpy(newLocation, output);
|
||||||
|
strcat(newLocation, "levels\\");
|
||||||
|
strcat(newLocation, findHandle.cFileName);
|
||||||
|
PLATFORM_copyFile(oldLocation, newLocation);
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &findHandle));
|
||||||
|
#else
|
||||||
|
#error See PLATFORM_migrateSaveData
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void PLATFORM_copyFile(const char *oldLocation, const char *newLocation)
|
||||||
|
{
|
||||||
|
char *data;
|
||||||
|
long int length;
|
||||||
|
|
||||||
|
/* Read data */
|
||||||
|
FILE *file = fopen(oldLocation, "rb");
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
printf("Cannot open/copy %s\n", oldLocation);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
length = ftell(file);
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
data = (char*) malloc(length);
|
||||||
|
fread(data, 1, length, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
/* Write data */
|
||||||
|
file = fopen(newLocation, "wb");
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
printf("Could not write to %s\n", newLocation);
|
||||||
|
free(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fwrite(data, 1, length, file);
|
||||||
|
fclose(file);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
/* WTF did we just do */
|
||||||
|
printf("Copied:\n\tOld: %s\n\tNew: %s\n", oldLocation, newLocation);
|
||||||
|
}
|
||||||
18
desktop_version/src/FileSystemUtils.h
Normal file
18
desktop_version/src/FileSystemUtils.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef FILESYSTEMUTILS_H
|
||||||
|
#define FILESYSTEMUTILS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
void FILESYSTEM_init(char *argvZero);
|
||||||
|
void FILESYSTEM_deinit();
|
||||||
|
|
||||||
|
char *FILESYSTEM_getUserSaveDirectory();
|
||||||
|
char *FILESYSTEM_getUserLevelDirectory();
|
||||||
|
|
||||||
|
void FILESYSTEM_loadFileToMemory(const char *name, unsigned char **mem, size_t *len);
|
||||||
|
void FILESYSTEM_freeMemory(unsigned char **mem);
|
||||||
|
|
||||||
|
std::vector<std::string> FILESYSTEM_getLevelDirFileNames();
|
||||||
|
|
||||||
|
#endif /* FILESYSTEMUTILS_H */
|
||||||
2317
desktop_version/src/Finalclass.cpp
Normal file
2317
desktop_version/src/Finalclass.cpp
Normal file
File diff suppressed because it is too large
Load Diff
20
desktop_version/src/Finalclass.h
Normal file
20
desktop_version/src/Finalclass.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef FINALCLASS_H
|
||||||
|
#define FINALCLASS_H
|
||||||
|
|
||||||
|
#include "Game.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class finalclass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<std::string> loadlevel(int rx, int ry, Game& game, entityclass& obj);
|
||||||
|
|
||||||
|
std::string roomname;
|
||||||
|
int coin, rcol;
|
||||||
|
bool warpx, warpy;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FINALCLASS_H */
|
||||||
7707
desktop_version/src/Game.cpp
Normal file
7707
desktop_version/src/Game.cpp
Normal file
File diff suppressed because it is too large
Load Diff
359
desktop_version/src/Game.h
Normal file
359
desktop_version/src/Game.h
Normal file
@@ -0,0 +1,359 @@
|
|||||||
|
#ifndef GAME_H
|
||||||
|
#define GAME_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "SDL.h"
|
||||||
|
#include "Maths.h"
|
||||||
|
#include "UtilityClass.h"
|
||||||
|
#include "GraphicsUtil.h"
|
||||||
|
|
||||||
|
|
||||||
|
class entityclass;
|
||||||
|
class mapclass;
|
||||||
|
class Graphics;
|
||||||
|
class musicclass;
|
||||||
|
|
||||||
|
class Game
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Game(void);
|
||||||
|
~Game(void);
|
||||||
|
|
||||||
|
|
||||||
|
void setGlobalSoundVol(const float _vol)
|
||||||
|
{
|
||||||
|
m_globalVol = _vol;
|
||||||
|
}
|
||||||
|
float getGlobalSoundVol()
|
||||||
|
{
|
||||||
|
return m_globalVol;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int crewrescued();
|
||||||
|
|
||||||
|
std::string unrescued();
|
||||||
|
|
||||||
|
void resetgameclock();
|
||||||
|
|
||||||
|
void customsavequick(std::string savfile, mapclass& map, entityclass& obj, musicclass& music);
|
||||||
|
void savequick(mapclass& map, entityclass& obj, musicclass& music);
|
||||||
|
|
||||||
|
void gameclock();
|
||||||
|
|
||||||
|
std::string giventimestring(int hrs, int min, int sec, UtilityClass& help );
|
||||||
|
|
||||||
|
std::string timestring(UtilityClass& help);
|
||||||
|
|
||||||
|
std::string partimestring(UtilityClass& help);
|
||||||
|
|
||||||
|
std::string resulttimestring(UtilityClass& help);
|
||||||
|
|
||||||
|
std::string timetstring(int t, UtilityClass& help);
|
||||||
|
|
||||||
|
void createmenu(std::string t);
|
||||||
|
|
||||||
|
void lifesequence(entityclass& obj);
|
||||||
|
|
||||||
|
void gethardestroom(mapclass& map);
|
||||||
|
|
||||||
|
void updatestate(Graphics& dwgfx, mapclass& map, entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
void unlocknum(int t, mapclass& map, Graphics& dwgfx);
|
||||||
|
|
||||||
|
void loadstats(mapclass& map, Graphics& dwgfx);
|
||||||
|
|
||||||
|
void savestats(mapclass& map, Graphics& dwgfx);
|
||||||
|
|
||||||
|
void deletestats(mapclass& map, Graphics& dwgfx);
|
||||||
|
|
||||||
|
void deletequick();
|
||||||
|
|
||||||
|
void savetele(mapclass& map, entityclass& obj, musicclass& music);
|
||||||
|
|
||||||
|
void loadtele(mapclass& map, entityclass& obj, musicclass& music);
|
||||||
|
|
||||||
|
void deletetele();
|
||||||
|
|
||||||
|
void customstart(entityclass& obj, musicclass& music );
|
||||||
|
|
||||||
|
void start(entityclass& obj, musicclass& music );
|
||||||
|
|
||||||
|
void startspecial(int t, entityclass& obj, musicclass& music);
|
||||||
|
|
||||||
|
void starttrial(int t, entityclass& obj, musicclass& music);
|
||||||
|
|
||||||
|
void telegotoship()
|
||||||
|
{
|
||||||
|
//Special function to move the telesave to the ship teleporter.
|
||||||
|
//telecookie.data.savex = 13*8;
|
||||||
|
//telecookie.data.savey = 129;
|
||||||
|
//telecookie.data.saverx = 102;
|
||||||
|
//telecookie.data.savery = 111;
|
||||||
|
//telecookie.data.savegc = 0;
|
||||||
|
//telecookie.data.savedir = 1;
|
||||||
|
//telecookie.data.savepoint = 0;
|
||||||
|
|
||||||
|
//telecookie.data.currentsong = 4;
|
||||||
|
//telecookie.data.companion = 0;
|
||||||
|
|
||||||
|
//telecookie.data.finalmode = false;
|
||||||
|
//telecookie.data.finalstretch = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swnpenalty();
|
||||||
|
|
||||||
|
void deathsequence(mapclass& map, entityclass& obj, musicclass& music);
|
||||||
|
|
||||||
|
void customloadquick(std::string savfile, mapclass& map, entityclass& obj, musicclass& music);
|
||||||
|
void loadquick(mapclass& map, entityclass& obj, musicclass& music);
|
||||||
|
|
||||||
|
void loadsummary(mapclass& map, UtilityClass& help);
|
||||||
|
|
||||||
|
void initteleportermode(mapclass& map);
|
||||||
|
|
||||||
|
std::string saveFilePath;
|
||||||
|
|
||||||
|
|
||||||
|
int door_left;
|
||||||
|
int door_right;
|
||||||
|
int door_up;
|
||||||
|
int door_down;
|
||||||
|
int roomx, roomy, roomchangedir;
|
||||||
|
int temp, j, k;
|
||||||
|
|
||||||
|
int savex, savey, saverx, savery;
|
||||||
|
int savegc, savedir;
|
||||||
|
|
||||||
|
//Added for port
|
||||||
|
int edsavex, edsavey, edsaverx, edsavery;
|
||||||
|
int edsavegc, edsavedir;
|
||||||
|
|
||||||
|
//State logic stuff
|
||||||
|
int state, statedelay;
|
||||||
|
|
||||||
|
bool glitchrunkludge;
|
||||||
|
|
||||||
|
int usingmmmmmm;
|
||||||
|
|
||||||
|
int gamestate;
|
||||||
|
bool hascontrol, jumpheld;
|
||||||
|
int jumppressed;
|
||||||
|
int gravitycontrol;
|
||||||
|
|
||||||
|
bool infocus;
|
||||||
|
bool muted;
|
||||||
|
int mutebutton;
|
||||||
|
private:
|
||||||
|
float m_globalVol;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
int tapleft, tapright;
|
||||||
|
|
||||||
|
//Menu interaction stuff
|
||||||
|
bool mapheld;
|
||||||
|
int menupage;
|
||||||
|
//public var crewstats:Array = new Array();
|
||||||
|
int lastsaved;
|
||||||
|
int deathcounts;
|
||||||
|
int timerStartTime;
|
||||||
|
|
||||||
|
int frames, seconds, minutes, hours;
|
||||||
|
bool gamesaved;
|
||||||
|
std::string savetime;
|
||||||
|
std::string savearea;
|
||||||
|
int savetrinkets;
|
||||||
|
bool startscript;
|
||||||
|
std::string newscript;
|
||||||
|
|
||||||
|
int mainmenu;
|
||||||
|
bool menustart;
|
||||||
|
|
||||||
|
//Teleporting
|
||||||
|
bool teleport_to_new_area;
|
||||||
|
int teleport_to_x, teleport_to_y;
|
||||||
|
std::string teleportscript;
|
||||||
|
bool useteleporter;
|
||||||
|
int teleport_to_teleporter;
|
||||||
|
|
||||||
|
//Main Menu Variables
|
||||||
|
std::vector<std::string> menuoptions;
|
||||||
|
std::vector<bool> menuoptionsactive;
|
||||||
|
int nummenuoptions, currentmenuoption ;
|
||||||
|
std::string menuselection, currentmenuname, previousmenuname;
|
||||||
|
int menuxoff, menuyoff;
|
||||||
|
|
||||||
|
int menucountdown;
|
||||||
|
std::string menudest;
|
||||||
|
|
||||||
|
int creditposx, creditposy, creditposdelay;
|
||||||
|
|
||||||
|
|
||||||
|
//60 fps mode!
|
||||||
|
bool sfpsmode;
|
||||||
|
|
||||||
|
//Sine Wave Ninja Minigame
|
||||||
|
bool swnmode;
|
||||||
|
int swngame, swnstate, swnstate2, swnstate3, swnstate4, swndelay, swndeaths;
|
||||||
|
int swntimer, swncolstate, swncoldelay;
|
||||||
|
int swnrecord, swnbestrank, swnrank, swnmessage;
|
||||||
|
|
||||||
|
//SuperCrewMate Stuff
|
||||||
|
bool supercrewmate, scmhurt, scmmoveme;
|
||||||
|
int scmprogress;
|
||||||
|
|
||||||
|
//Accessibility Options
|
||||||
|
bool colourblindmode;
|
||||||
|
bool noflashingmode;
|
||||||
|
int slowdown;
|
||||||
|
Uint32 gameframerate;
|
||||||
|
|
||||||
|
bool nodeathmode;
|
||||||
|
int gameoverdelay;
|
||||||
|
bool nocutscenes;
|
||||||
|
|
||||||
|
//Time Trials
|
||||||
|
bool intimetrial, timetrialparlost;
|
||||||
|
int timetrialcountdown, timetrialshinytarget, timetriallevel;
|
||||||
|
int timetrialpar, timetrialresulttime, timetrialrank;
|
||||||
|
|
||||||
|
int creditposition;
|
||||||
|
bool insecretlab;
|
||||||
|
|
||||||
|
bool inintermission;
|
||||||
|
|
||||||
|
std::vector<bool> crewstats;
|
||||||
|
|
||||||
|
bool alarmon;
|
||||||
|
int alarmdelay;
|
||||||
|
bool blackout;
|
||||||
|
|
||||||
|
std::vector<bool> tele_crewstats;
|
||||||
|
|
||||||
|
std::vector<bool> quick_crewstats;
|
||||||
|
|
||||||
|
std::vector<int> unlock;
|
||||||
|
std::vector<int> unlocknotify;
|
||||||
|
std::vector<int> temp_unlock;
|
||||||
|
std::vector<int> temp_unlocknotify;
|
||||||
|
int stat_trinkets;
|
||||||
|
bool fullscreen;
|
||||||
|
int bestgamedeaths;
|
||||||
|
|
||||||
|
bool stat_screenshakes;
|
||||||
|
bool stat_backgrounds;
|
||||||
|
bool stat_flipmode;
|
||||||
|
bool stat_invincibility;
|
||||||
|
int stat_slowdown;
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<int>besttimes;
|
||||||
|
std::vector<int>besttrinkets;
|
||||||
|
std::vector<int>bestlives;
|
||||||
|
std::vector<int> bestrank;
|
||||||
|
|
||||||
|
bool telecookieexists;
|
||||||
|
bool quickcookieexists;
|
||||||
|
|
||||||
|
std::string tele_gametime;
|
||||||
|
int tele_trinkets;
|
||||||
|
std::string tele_currentarea;
|
||||||
|
std::string quick_gametime;
|
||||||
|
int quick_trinkets;
|
||||||
|
std::string quick_currentarea;
|
||||||
|
|
||||||
|
int mx, my;
|
||||||
|
int screenshake, flashlight;
|
||||||
|
bool test;
|
||||||
|
std::string teststring, tempstring;
|
||||||
|
bool advancetext, pausescript;
|
||||||
|
|
||||||
|
int deathseq, lifeseq;
|
||||||
|
|
||||||
|
int coins, trinkets, crewmates, trinkencollect;
|
||||||
|
int savepoint, teleport, teleportxpos;
|
||||||
|
int edteleportent;
|
||||||
|
bool completestop;
|
||||||
|
|
||||||
|
float inertia;
|
||||||
|
|
||||||
|
int companion;
|
||||||
|
bool roomchange;
|
||||||
|
SDL_Rect teleblock;
|
||||||
|
bool activetele;
|
||||||
|
int readytotele;
|
||||||
|
int activity_r, activity_g, activity_b;
|
||||||
|
std::string activity_lastprompt;
|
||||||
|
|
||||||
|
std::string telesummary, quicksummary, customquicksummary;
|
||||||
|
|
||||||
|
bool backgroundtext;
|
||||||
|
|
||||||
|
int activeactivity, act_fade;
|
||||||
|
|
||||||
|
bool press_left, press_right, press_action, press_map;
|
||||||
|
|
||||||
|
//Some stats:
|
||||||
|
int totalflips;
|
||||||
|
std::string hardestroom;
|
||||||
|
int hardestroomdeaths, currentroomdeaths;
|
||||||
|
|
||||||
|
bool savemystats;
|
||||||
|
|
||||||
|
|
||||||
|
bool advanced_mode;
|
||||||
|
bool fullScreenEffect_badSignal;
|
||||||
|
bool useLinearFilter;
|
||||||
|
int stretchMode;
|
||||||
|
int controllerSensitivity;
|
||||||
|
|
||||||
|
//Screenrecording stuff, for beta/trailer
|
||||||
|
int recording;
|
||||||
|
std::string recordstring;
|
||||||
|
bool combomode;
|
||||||
|
int combolen;
|
||||||
|
std::string comboaction;
|
||||||
|
std::string currentaction;
|
||||||
|
bool recordinit;
|
||||||
|
|
||||||
|
std::vector<int> playback;
|
||||||
|
int playbackpos;
|
||||||
|
int playbacksize;
|
||||||
|
int playmove;
|
||||||
|
int playcombo;
|
||||||
|
bool playbackfinished;
|
||||||
|
|
||||||
|
bool menukludge;
|
||||||
|
bool quickrestartkludge;
|
||||||
|
|
||||||
|
bool paused;
|
||||||
|
int globalsound;
|
||||||
|
|
||||||
|
//Custom stuff
|
||||||
|
std::string customscript[50];
|
||||||
|
int customcol;
|
||||||
|
int levelpage;
|
||||||
|
int playcustomlevel;
|
||||||
|
std::string customleveltitle;
|
||||||
|
std::string customlevelfilename;
|
||||||
|
|
||||||
|
void clearcustomlevelstats();
|
||||||
|
void loadcustomlevelstats();
|
||||||
|
void savecustomlevelstats();
|
||||||
|
void updatecustomlevelstats(std::string clevel, int cscore);
|
||||||
|
|
||||||
|
std::string customlevelstats[200]; //string array containing level filenames
|
||||||
|
int customlevelscore[200];//0 - not played, 1 - finished, 2 - all trinkets, 3 - finished, all trinkets
|
||||||
|
int numcustomlevelstats;
|
||||||
|
bool customlevelstatsloaded;
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<SDL_GameControllerButton> controllerButton_map;
|
||||||
|
std::vector<SDL_GameControllerButton> controllerButton_flip;
|
||||||
|
std::vector<SDL_GameControllerButton> controllerButton_esc;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* GAME_H */
|
||||||
3207
desktop_version/src/Graphics.cpp
Normal file
3207
desktop_version/src/Graphics.cpp
Normal file
File diff suppressed because it is too large
Load Diff
280
desktop_version/src/Graphics.h
Normal file
280
desktop_version/src/Graphics.h
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
#ifndef GRAPHICS_H
|
||||||
|
#define GRAPHICS_H
|
||||||
|
|
||||||
|
#include "GraphicsResources.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "Maths.h"
|
||||||
|
#include "Textbox.h"
|
||||||
|
#include "UtilityClass.h"
|
||||||
|
#include "Game.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "GraphicsUtil.h"
|
||||||
|
#include "Screen.h"
|
||||||
|
|
||||||
|
class map;
|
||||||
|
|
||||||
|
class Graphics
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Graphics();
|
||||||
|
~Graphics();
|
||||||
|
|
||||||
|
GraphicsResources grphx;
|
||||||
|
|
||||||
|
void Makebfont();
|
||||||
|
|
||||||
|
void drawhuetile(int x, int y, int t, int c);
|
||||||
|
|
||||||
|
void drawgravityline(int t, entityclass& obj);
|
||||||
|
|
||||||
|
void MakeTileArray();
|
||||||
|
|
||||||
|
void MakeSpriteArray();
|
||||||
|
|
||||||
|
void maketelearray();
|
||||||
|
|
||||||
|
void drawcoloredtile(int x, int y, int t, int r, int g, int b);
|
||||||
|
|
||||||
|
void drawmenu(Game& game, int cr, int cg, int cb, int division = 30);
|
||||||
|
void drawlevelmenu(Game& game, int cr, int cg, int cb, int division = 30);
|
||||||
|
|
||||||
|
void processfade();
|
||||||
|
|
||||||
|
void drawfade();
|
||||||
|
|
||||||
|
void setwarprect(int a, int b, int c, int d);
|
||||||
|
|
||||||
|
void createtextbox(std::string t, int xp, int yp, int r= 255, int g= 255, int b = 255);
|
||||||
|
|
||||||
|
void textboxcleanup();
|
||||||
|
|
||||||
|
void textboxcenter();
|
||||||
|
|
||||||
|
void textboxcenterx();
|
||||||
|
|
||||||
|
int textboxwidth();
|
||||||
|
|
||||||
|
void textboxmove(int xo, int yo);
|
||||||
|
|
||||||
|
void textboxmoveto(int xo);
|
||||||
|
|
||||||
|
void textboxcentery();
|
||||||
|
|
||||||
|
void textboxadjust();
|
||||||
|
|
||||||
|
void addline(std::string t);
|
||||||
|
|
||||||
|
void textboxtimer(int t);
|
||||||
|
|
||||||
|
void textboxremove();
|
||||||
|
|
||||||
|
void textboxremovefast();
|
||||||
|
|
||||||
|
void textboxactive();
|
||||||
|
|
||||||
|
void drawtextbox(int x, int y, int w, int h, int r, int g, int b);
|
||||||
|
|
||||||
|
void drawpixeltextbox(int x, int y, int w, int h, int w2, int h2, int r, int g, int b, int xo, int yo);
|
||||||
|
void drawcustompixeltextbox(int x, int y, int w, int h, int w2, int h2, int r, int g, int b, int xo, int yo);
|
||||||
|
|
||||||
|
void drawcrewman(int x, int y, int t, bool act, UtilityClass& help, bool noshift =false);
|
||||||
|
|
||||||
|
int crewcolour(const int t);
|
||||||
|
|
||||||
|
void cutscenebars();
|
||||||
|
|
||||||
|
void drawpartimage(int t, int xp, int yp, int wp, int hp);
|
||||||
|
|
||||||
|
void drawimage(int t, int xp, int yp, bool cent=false);
|
||||||
|
|
||||||
|
void drawimagecol(int t, int xp, int yp, int r, int g, int b, bool cent= false);
|
||||||
|
|
||||||
|
void drawgui(UtilityClass& help);
|
||||||
|
|
||||||
|
void drawsprite(int x, int y, int t, int r, int g, int b);
|
||||||
|
|
||||||
|
void printcrewname(int x, int y, int t);
|
||||||
|
|
||||||
|
void printcrewnamestatus(int x, int y, int t);
|
||||||
|
|
||||||
|
void printcrewnamedark(int x, int y, int t);
|
||||||
|
|
||||||
|
void Print(int _x, int _y, std::string _s, int r, int g, int b, bool cen = false);
|
||||||
|
|
||||||
|
void RPrint(int _x, int _y, std::string _s, int r, int g, int b, bool cen = false);
|
||||||
|
|
||||||
|
void PrintOff(int _x, int _y, std::string _s, int r, int g, int b, bool cen = false);
|
||||||
|
|
||||||
|
void bprint(int x, int y, std::string t, int r, int g, int b, bool cen = false);
|
||||||
|
|
||||||
|
int len(std::string t);
|
||||||
|
void bigprint( int _x, int _y, std::string _s, int r, int g, int b, bool cen = false, int sc = 2 );
|
||||||
|
void drawspritesetcol(int x, int y, int t, int c, UtilityClass& help);
|
||||||
|
|
||||||
|
|
||||||
|
void flashlight();
|
||||||
|
void screenshake();
|
||||||
|
|
||||||
|
void render();
|
||||||
|
|
||||||
|
bool Hitest(SDL_Surface* surface1, point p1, int col, SDL_Surface* surface2, point p2, int col2);
|
||||||
|
|
||||||
|
void drawentities(mapclass& map, entityclass& obj, UtilityClass& help);
|
||||||
|
|
||||||
|
void drawtrophytext(entityclass&, UtilityClass& help);
|
||||||
|
|
||||||
|
void bigrprint(int x, int y, std::string& t, int r, int g, int b, bool cen = false, float sc = 2);
|
||||||
|
|
||||||
|
|
||||||
|
void drawtele(int x, int y, int t, int c, UtilityClass& help);
|
||||||
|
|
||||||
|
Uint32 getRGB(Uint8 r, Uint8 g, Uint8 b);
|
||||||
|
|
||||||
|
Uint32 getBGR(Uint8 r, Uint8 g, Uint8 b);
|
||||||
|
|
||||||
|
Uint32 getRGB(Uint32 _col);
|
||||||
|
|
||||||
|
Uint32 RGBflip(Uint8 r, Uint8 g, Uint8 b);
|
||||||
|
|
||||||
|
|
||||||
|
Uint32 RGBf(int r, int g, int b);
|
||||||
|
|
||||||
|
void setcolreal(Uint32 t);
|
||||||
|
|
||||||
|
void drawbackground(int t, mapclass& map);
|
||||||
|
void drawtile3( int x, int y, int t, int off );
|
||||||
|
void drawentcolours( int x, int y, int t);
|
||||||
|
void drawtile2( int x, int y, int t, int r, int g, int b );
|
||||||
|
void drawtile( int x, int y, int t, int r, int g, int b );
|
||||||
|
void drawtowertile( int x, int y, int t );
|
||||||
|
void drawtowertile3( int x, int y, int t, int off );
|
||||||
|
|
||||||
|
void drawtile(int x, int y, int t);
|
||||||
|
|
||||||
|
void drawmap(mapclass& map);
|
||||||
|
|
||||||
|
void drawforetile(int x, int y, int t);
|
||||||
|
|
||||||
|
void drawforetile2(int x, int y, int t);
|
||||||
|
|
||||||
|
void drawforetile3(int x, int y, int t, int off);
|
||||||
|
|
||||||
|
void drawrect(int x, int y, int w, int h, int r, int g, int b);
|
||||||
|
|
||||||
|
void drawtowermap(mapclass& map);
|
||||||
|
|
||||||
|
void drawtowermap_nobackground(mapclass& map);
|
||||||
|
|
||||||
|
void drawtowerspikes(mapclass& map);
|
||||||
|
|
||||||
|
void drawtowerentities(mapclass& map, entityclass& obj, UtilityClass& help);
|
||||||
|
|
||||||
|
bool onscreen(int t);
|
||||||
|
|
||||||
|
void drawtowerbackgroundsolo(mapclass& map);
|
||||||
|
|
||||||
|
|
||||||
|
void menuoffrender();
|
||||||
|
|
||||||
|
void drawtowerbackground(mapclass& map);
|
||||||
|
|
||||||
|
void setcol(int t, UtilityClass& help);
|
||||||
|
void drawfinalmap(mapclass & map);
|
||||||
|
|
||||||
|
colourTransform ct;
|
||||||
|
|
||||||
|
std::string tempstring;
|
||||||
|
|
||||||
|
int bcol, bcol2, rcol;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int j, k, m;
|
||||||
|
|
||||||
|
std::vector <SDL_Surface*> backgrounds;
|
||||||
|
std::vector <SDL_Surface*> images;
|
||||||
|
|
||||||
|
std::vector <SDL_Surface*> tele;
|
||||||
|
std::vector <SDL_Surface*> tiles;
|
||||||
|
std::vector <SDL_Surface*> tiles2;
|
||||||
|
std::vector <SDL_Surface*> tiles3;
|
||||||
|
std::vector <SDL_Surface*> entcolours;
|
||||||
|
std::vector <SDL_Surface*> sprites;
|
||||||
|
std::vector <SDL_Surface*> flipsprites;
|
||||||
|
std::vector <SDL_Surface*> bfont;
|
||||||
|
std::vector <SDL_Surface*> bfontmask;
|
||||||
|
std::vector <SDL_Surface*> flipbfont;
|
||||||
|
std::vector <SDL_Surface*> flipbfontmask;
|
||||||
|
std::vector <int> bfontlen;
|
||||||
|
|
||||||
|
bool flipmode;
|
||||||
|
bool setflipmode;
|
||||||
|
point tl;
|
||||||
|
//buffer objects. //TODO refactor buffer objects
|
||||||
|
SDL_Surface* backBuffer;
|
||||||
|
Screen* screenbuffer;
|
||||||
|
SDL_Surface* menubuffer;
|
||||||
|
SDL_Surface* towerbuffer;
|
||||||
|
SDL_Surface* forgroundBuffer;
|
||||||
|
SDL_Surface* tempBuffer;
|
||||||
|
|
||||||
|
SDL_Rect bfont_rect;
|
||||||
|
SDL_Rect tiles_rect;
|
||||||
|
SDL_Rect sprites_rect;
|
||||||
|
SDL_Rect bfontmask_rect;
|
||||||
|
SDL_Rect images_rect;
|
||||||
|
SDL_Rect bg_rect;
|
||||||
|
SDL_Rect line_rect;
|
||||||
|
SDL_Rect tele_rect;
|
||||||
|
|
||||||
|
SDL_Rect foot_rect;
|
||||||
|
SDL_Rect prect;
|
||||||
|
SDL_Rect footerrect;
|
||||||
|
|
||||||
|
int linestate, linedelay;
|
||||||
|
int backoffset;
|
||||||
|
bool backgrounddrawn, foregrounddrawn;
|
||||||
|
|
||||||
|
int menuoffset;
|
||||||
|
bool resumegamemode;
|
||||||
|
|
||||||
|
SDL_Rect warprect;
|
||||||
|
|
||||||
|
int crewframe;
|
||||||
|
int crewframedelay;
|
||||||
|
|
||||||
|
int fademode;
|
||||||
|
int fadeamount;
|
||||||
|
std::vector <int> fadebars;
|
||||||
|
|
||||||
|
bool trinketcolset;
|
||||||
|
int trinketr, trinketg, trinketb;
|
||||||
|
|
||||||
|
std::vector <textboxclass> textbox;
|
||||||
|
int ntextbox;
|
||||||
|
|
||||||
|
bool showcutscenebars;
|
||||||
|
int cutscenebarspos;
|
||||||
|
|
||||||
|
std::vector<SDL_Rect> stars;
|
||||||
|
std::vector<int> starsspeed;
|
||||||
|
|
||||||
|
int spcol, spcoldel;
|
||||||
|
std::vector<SDL_Rect> backboxes;
|
||||||
|
std::vector<int> backboxvx;
|
||||||
|
std::vector<int> backboxvy;
|
||||||
|
std::vector<float> backboxint;
|
||||||
|
SDL_Rect backboxrect;
|
||||||
|
|
||||||
|
int warpskip, warpfcol, warpbcol;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* GRAPHICS_H */
|
||||||
113
desktop_version/src/GraphicsResources.cpp
Normal file
113
desktop_version/src/GraphicsResources.cpp
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
#include "GraphicsResources.h"
|
||||||
|
#include "FileSystemUtils.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// Used to load PNG data
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
extern unsigned lodepng_decode24(
|
||||||
|
unsigned char** out,
|
||||||
|
unsigned* w,
|
||||||
|
unsigned* h,
|
||||||
|
const unsigned char* in,
|
||||||
|
size_t insize
|
||||||
|
);
|
||||||
|
extern unsigned lodepng_decode32(
|
||||||
|
unsigned char** out,
|
||||||
|
unsigned* w,
|
||||||
|
unsigned* h,
|
||||||
|
const unsigned char* in,
|
||||||
|
size_t insize
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface* LoadImage(const char *filename, bool noBlend = true, bool noAlpha = false)
|
||||||
|
{
|
||||||
|
//Temporary storage for the image that's loaded
|
||||||
|
SDL_Surface* loadedImage = NULL;
|
||||||
|
//The optimized image that will be used
|
||||||
|
SDL_Surface* optimizedImage = NULL;
|
||||||
|
|
||||||
|
unsigned char *data;
|
||||||
|
unsigned int width, height;
|
||||||
|
|
||||||
|
unsigned char *fileIn = NULL;
|
||||||
|
size_t length = 0;
|
||||||
|
FILESYSTEM_loadFileToMemory(filename, &fileIn, &length);
|
||||||
|
if (noAlpha)
|
||||||
|
{
|
||||||
|
lodepng_decode24(&data, &width, &height, fileIn, length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lodepng_decode32(&data, &width, &height, fileIn, length);
|
||||||
|
}
|
||||||
|
FILESYSTEM_freeMemory(&fileIn);
|
||||||
|
|
||||||
|
loadedImage = SDL_CreateRGBSurfaceFrom(
|
||||||
|
data,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
noAlpha ? 24 : 32,
|
||||||
|
width * (noAlpha ? 3 : 4),
|
||||||
|
0x000000FF,
|
||||||
|
0x0000FF00,
|
||||||
|
0x00FF0000,
|
||||||
|
noAlpha ? 0x00000000 : 0xFF000000
|
||||||
|
);
|
||||||
|
|
||||||
|
if (loadedImage != NULL)
|
||||||
|
{
|
||||||
|
optimizedImage = SDL_ConvertSurfaceFormat(
|
||||||
|
loadedImage,
|
||||||
|
SDL_PIXELFORMAT_ABGR8888, // FIXME: Format? -flibit
|
||||||
|
0
|
||||||
|
);
|
||||||
|
SDL_FreeSurface( loadedImage );
|
||||||
|
free(data);
|
||||||
|
if (noBlend)
|
||||||
|
{
|
||||||
|
SDL_SetSurfaceBlendMode(optimizedImage, SDL_BLENDMODE_BLEND);
|
||||||
|
}
|
||||||
|
return optimizedImage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr,"Image not found: %s\n", filename);
|
||||||
|
SDL_assert(0 && "Image not found! See stderr.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphicsResources::GraphicsResources(void)
|
||||||
|
{
|
||||||
|
im_tiles = LoadImage("graphics/tiles.png");
|
||||||
|
im_tiles2 = LoadImage("graphics/tiles2.png");
|
||||||
|
im_tiles3 = LoadImage("graphics/tiles3.png");
|
||||||
|
im_entcolours = LoadImage("graphics/entcolours.png");
|
||||||
|
im_sprites = LoadImage("graphics/sprites.png");
|
||||||
|
im_flipsprites = LoadImage("graphics/flipsprites.png");
|
||||||
|
im_bfont = LoadImage("graphics/font.png");
|
||||||
|
im_bfontmask = LoadImage("graphics/fontmask.png");
|
||||||
|
im_teleporter = LoadImage("graphics/teleporter.png");
|
||||||
|
|
||||||
|
im_image0 = LoadImage("graphics/levelcomplete.png", false);
|
||||||
|
im_image1 = LoadImage("graphics/minimap.png", true, true);
|
||||||
|
im_image2 = LoadImage("graphics/covered.png", true, true);
|
||||||
|
im_image3 = LoadImage("graphics/elephant.png");
|
||||||
|
im_image4 = LoadImage("graphics/gamecomplete.png", false);
|
||||||
|
im_image5 = LoadImage("graphics/fliplevelcomplete.png", false);
|
||||||
|
im_image6 = LoadImage("graphics/flipgamecomplete.png", false);
|
||||||
|
im_image7 = LoadImage("graphics/site.png", false);
|
||||||
|
im_image8 = LoadImage("graphics/site2.png");
|
||||||
|
im_image9 = LoadImage("graphics/site3.png");
|
||||||
|
im_image10 = LoadImage("graphics/ending.png");
|
||||||
|
im_image11 = LoadImage("graphics/site4.png");
|
||||||
|
im_image12 = LoadImage("graphics/minimap.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GraphicsResources::~GraphicsResources(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
36
desktop_version/src/GraphicsResources.h
Normal file
36
desktop_version/src/GraphicsResources.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef GRAPHICSRESOURCES_H
|
||||||
|
#define GRAPHICSRESOURCES_H
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
|
||||||
|
class GraphicsResources
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GraphicsResources(void);
|
||||||
|
~GraphicsResources(void);
|
||||||
|
|
||||||
|
SDL_Surface* im_tiles;
|
||||||
|
SDL_Surface* im_tiles2;
|
||||||
|
SDL_Surface* im_tiles3;
|
||||||
|
SDL_Surface* im_entcolours;
|
||||||
|
SDL_Surface* im_sprites;
|
||||||
|
SDL_Surface* im_flipsprites;
|
||||||
|
SDL_Surface* im_bfont;
|
||||||
|
SDL_Surface* im_bfontmask;
|
||||||
|
SDL_Surface* im_teleporter;
|
||||||
|
SDL_Surface* im_image0;
|
||||||
|
SDL_Surface* im_image1;
|
||||||
|
SDL_Surface* im_image2;
|
||||||
|
SDL_Surface* im_image3;
|
||||||
|
SDL_Surface* im_image4;
|
||||||
|
SDL_Surface* im_image5;
|
||||||
|
SDL_Surface* im_image6;
|
||||||
|
SDL_Surface* im_image7;
|
||||||
|
SDL_Surface* im_image8;
|
||||||
|
SDL_Surface* im_image9;
|
||||||
|
SDL_Surface* im_image10;
|
||||||
|
SDL_Surface* im_image11;
|
||||||
|
SDL_Surface* im_image12;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* GRAPHICSRESOURCES_H */
|
||||||
525
desktop_version/src/GraphicsUtil.cpp
Normal file
525
desktop_version/src/GraphicsUtil.cpp
Normal file
@@ -0,0 +1,525 @@
|
|||||||
|
#include "Graphics.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void setRect( SDL_Rect& _r, int x, int y, int w, int h )
|
||||||
|
{
|
||||||
|
_r.x = x;
|
||||||
|
_r.y = y;
|
||||||
|
_r.w = w;
|
||||||
|
_r.h = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int endian_swap( unsigned int x )
|
||||||
|
{
|
||||||
|
return (x>>24) |
|
||||||
|
((x<<8) & 0x00FF0000) |
|
||||||
|
((x>>8) & 0x0000FF00) |
|
||||||
|
(x<<24);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void endian_swap(T *objp)
|
||||||
|
{
|
||||||
|
unsigned char *memp = reinterpret_cast<unsigned char*>(objp);
|
||||||
|
std::reverse(memp, memp + sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SDL_Surface* GetSubSurface( SDL_Surface* metaSurface, int x, int y, int width, int height )
|
||||||
|
{
|
||||||
|
// Create an SDL_Rect with the area of the _surface
|
||||||
|
SDL_Rect area;
|
||||||
|
area.x = x;
|
||||||
|
area.y = y;
|
||||||
|
area.w = width;
|
||||||
|
area.h = height;
|
||||||
|
|
||||||
|
// Set the RGBA mask values.
|
||||||
|
Uint32 r, g, b, a;
|
||||||
|
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||||
|
r = 0xff000000;
|
||||||
|
g = 0x00ff0000;
|
||||||
|
b = 0x0000ff00;
|
||||||
|
a = 0x000000ff;
|
||||||
|
#else
|
||||||
|
r = 0x000000ff;
|
||||||
|
g = 0x0000ff00;
|
||||||
|
b = 0x00ff0000;
|
||||||
|
a = 0xff000000;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Convert to the correct display format after nabbing the new _surface or we will slow things down.
|
||||||
|
SDL_Surface* preSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, r, g, b, a);
|
||||||
|
//SDL_Surface* subSurface = SDL_DisplayFormatAlpha(preSurface);
|
||||||
|
|
||||||
|
//SDL_FreeSurface(preSurface);
|
||||||
|
|
||||||
|
// Lastly, apply the area from the meta _surface onto the whole of the sub _surface.
|
||||||
|
SDL_BlitSurface(metaSurface, &area, preSurface, 0);
|
||||||
|
|
||||||
|
// Return the new Bitmap _surface
|
||||||
|
return preSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawPixel( SDL_Surface *_surface, int x, int y, Uint32 pixel )
|
||||||
|
{
|
||||||
|
int bpp = _surface->format->BytesPerPixel;
|
||||||
|
/* Here p is the address to the pixel we want to set */
|
||||||
|
Uint8 *p = (Uint8 *)_surface->pixels + y * _surface->pitch + x * bpp;
|
||||||
|
|
||||||
|
switch(bpp)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
*p = pixel;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
*(Uint16 *)p = pixel;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if(SDL_BYTEORDER != SDL_BIG_ENDIAN)
|
||||||
|
{
|
||||||
|
p[0] = (pixel >> 16) & 0xff;
|
||||||
|
p[1] = (pixel >> 8) & 0xff;
|
||||||
|
p[2] = pixel & 0xff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p[0] = pixel & 0xff;
|
||||||
|
p[1] = (pixel >> 8) & 0xff;
|
||||||
|
p[2] = (pixel >> 16) & 0xff;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
*(Uint32 *)p = pixel;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint32 ReadPixel( SDL_Surface *_surface, int x, int y )
|
||||||
|
{
|
||||||
|
int bpp = _surface->format->BytesPerPixel;
|
||||||
|
/* Here p is the address to the pixel we want to retrieve */
|
||||||
|
Uint8 *p = (Uint8 *)_surface->pixels + y * _surface->pitch + x * bpp;
|
||||||
|
|
||||||
|
switch(bpp)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
return *p;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
return *(Uint16 *)p;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||||
|
return p[0] << 16 | p[1] << 8 | p[2];
|
||||||
|
else
|
||||||
|
return p[0] | p[1] << 8 | p[2] << 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
return *(Uint32 *)p;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0; /* shouldn't happen, but avoids warnings */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface * ScaleSurface( SDL_Surface *_surface, int Width, int Height, SDL_Surface * Dest )
|
||||||
|
{
|
||||||
|
if(!_surface || !Width || !Height)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
SDL_Surface *_ret;
|
||||||
|
if(Dest == NULL)
|
||||||
|
{
|
||||||
|
_ret = SDL_CreateRGBSurface(_surface->flags, Width, Height, _surface->format->BitsPerPixel,
|
||||||
|
_surface->format->Rmask, _surface->format->Gmask, _surface->format->Bmask, _surface->format->Amask);
|
||||||
|
if(_ret == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_ret = Dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
float _stretch_factor_x = (static_cast<double>(Width) / static_cast<double>(_surface->w)), _stretch_factor_y = (static_cast<double>(Height) / static_cast<double>(_surface->h));
|
||||||
|
|
||||||
|
|
||||||
|
SDL_Rect gigantoPixel;
|
||||||
|
for(Sint32 y = 0; y < _surface->h; y++)
|
||||||
|
for(Sint32 x = 0; x < _surface->w; x++)
|
||||||
|
{
|
||||||
|
setRect(gigantoPixel, static_cast<Sint32>((float(x)*_stretch_factor_x) -1), static_cast<Sint32>((float(y) *_stretch_factor_y)-1), static_cast<Sint32>(_stretch_factor_x +1.0),static_cast<Sint32>( _stretch_factor_y+1.0)) ;
|
||||||
|
SDL_FillRect(_ret, &gigantoPixel, ReadPixel(_surface, x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// DrawPixel(_ret, static_cast<Sint32>(_stretch_factor_x * x) + o_x,
|
||||||
|
//static_cast<Sint32>(_stretch_factor_y * y) + o_y, ReadPixel(_surface, x, y));
|
||||||
|
|
||||||
|
return _ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface * ScaleSurfaceSlow( SDL_Surface *_surface, int Width, int Height)
|
||||||
|
{
|
||||||
|
if(!_surface || !Width || !Height)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
SDL_Surface *_ret;
|
||||||
|
|
||||||
|
_ret = SDL_CreateRGBSurface(_surface->flags, Width, Height, _surface->format->BitsPerPixel,
|
||||||
|
_surface->format->Rmask, _surface->format->Gmask, _surface->format->Bmask, _surface->format->Amask);
|
||||||
|
if(_ret == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float _stretch_factor_x = (static_cast<double>(Width) / static_cast<double>(_surface->w)), _stretch_factor_y = (static_cast<double>(Height) / static_cast<double>(_surface->h));
|
||||||
|
|
||||||
|
|
||||||
|
for(Sint32 y = 0; y < _surface->h; y++)
|
||||||
|
for(Sint32 x = 0; x < _surface->w; x++)
|
||||||
|
for(Sint32 o_y = 0; o_y < _stretch_factor_y; ++o_y)
|
||||||
|
for(Sint32 o_x = 0; o_x < _stretch_factor_x; ++o_x)
|
||||||
|
DrawPixel(_ret, static_cast<Sint32>(_stretch_factor_x * x) + o_x,
|
||||||
|
static_cast<Sint32>(_stretch_factor_y * y) + o_y, ReadPixel(_surface, x, y));
|
||||||
|
|
||||||
|
// DrawPixel(_ret, static_cast<Sint32>(_stretch_factor_x * x) + o_x,
|
||||||
|
//static_cast<Sint32>(_stretch_factor_y * y) + o_y, ReadPixel(_surface, x, y));
|
||||||
|
|
||||||
|
return _ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface * FlipSurfaceHorizontal(SDL_Surface* _src)
|
||||||
|
{
|
||||||
|
SDL_Surface * ret = SDL_CreateRGBSurface(_src->flags, _src->w, _src->h, _src->format->BitsPerPixel,
|
||||||
|
_src->format->Rmask, _src->format->Gmask, _src->format->Bmask, _src->format->Amask);
|
||||||
|
if(ret == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Sint32 y = 0; y < _src->h; y++)
|
||||||
|
{
|
||||||
|
for(Sint32 x = 0; x < _src->w; x++)
|
||||||
|
{
|
||||||
|
DrawPixel(ret,(_src->w -1) -x,y,ReadPixel(_src, x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface * FlipSurfaceVerticle(SDL_Surface* _src)
|
||||||
|
{
|
||||||
|
SDL_Surface * ret = SDL_CreateRGBSurface(_src->flags, _src->w, _src->h, _src->format->BitsPerPixel,
|
||||||
|
_src->format->Rmask, _src->format->Gmask, _src->format->Bmask, _src->format->Amask);
|
||||||
|
if(ret == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Sint32 y = 0; y < _src->h; y++)
|
||||||
|
{
|
||||||
|
for(Sint32 x = 0; x < _src->w; x++)
|
||||||
|
{
|
||||||
|
DrawPixel(ret, x ,(_src->h-1) - y ,ReadPixel(_src, x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlitSurfaceStandard( SDL_Surface* _src, SDL_Rect* _srcRect, SDL_Surface* _dest, SDL_Rect* _destRect )
|
||||||
|
{
|
||||||
|
//SDL_Rect tempRect = *_destRect;
|
||||||
|
//tempRect.w ;
|
||||||
|
//tempRect.h ;
|
||||||
|
//tempRect.x *=globalScale;
|
||||||
|
//tempRect.y *=globalScale;
|
||||||
|
|
||||||
|
|
||||||
|
//if(globalScale != 1)
|
||||||
|
//{
|
||||||
|
// SDL_Surface* tempScaled = ScaleSurface(_src, tempRect.w, tempRect.h);
|
||||||
|
|
||||||
|
// SDL_BlitSurface( tempScaled, _srcRect, _dest, &tempRect );
|
||||||
|
|
||||||
|
// SDL_FreeSurface(tempScaled);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
SDL_BlitSurface( _src, _srcRect, _dest, _destRect );
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlitSurfaceColoured(
|
||||||
|
SDL_Surface* _src,
|
||||||
|
SDL_Rect* _srcRect,
|
||||||
|
SDL_Surface* _dest,
|
||||||
|
SDL_Rect* _destRect,
|
||||||
|
colourTransform& ct
|
||||||
|
) {
|
||||||
|
SDL_Rect *tempRect = _destRect;
|
||||||
|
|
||||||
|
const SDL_PixelFormat& fmt = *(_src->format);
|
||||||
|
// const SDL_PixelFormat& destfmt = *(_dest->format);
|
||||||
|
|
||||||
|
SDL_Surface* tempsurface = SDL_CreateRGBSurface(
|
||||||
|
SDL_SWSURFACE,
|
||||||
|
_src->w,
|
||||||
|
_src->h,
|
||||||
|
fmt.BitsPerPixel,
|
||||||
|
fmt.Rmask,
|
||||||
|
fmt.Gmask,
|
||||||
|
fmt.Bmask,
|
||||||
|
fmt.Amask
|
||||||
|
);
|
||||||
|
|
||||||
|
for(int x = 0; x < tempsurface->w; x++)
|
||||||
|
{
|
||||||
|
for(int y = 0; y < tempsurface->h; y++)
|
||||||
|
{
|
||||||
|
Uint32 pixel = ReadPixel(_src, x, y);
|
||||||
|
Uint32 Alpha = pixel & fmt.Amask;
|
||||||
|
Uint32 result = ct.colour & 0x00FFFFFF;
|
||||||
|
DrawPixel(tempsurface, x, y, result | Alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_BlitSurface(tempsurface, _srcRect, _dest, tempRect);
|
||||||
|
SDL_FreeSurface(tempsurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int scrollamount = 0;
|
||||||
|
bool isscrolling = 0;
|
||||||
|
SDL_Surface* ApplyFilter( SDL_Surface* _src )
|
||||||
|
{
|
||||||
|
SDL_Surface* _ret = SDL_CreateRGBSurface(_src->flags, _src->w, _src->h, 32,
|
||||||
|
_src->format->Rmask, _src->format->Gmask, _src->format->Bmask, _src->format->Amask);
|
||||||
|
|
||||||
|
if (rand() % 4000 < 8)
|
||||||
|
{
|
||||||
|
isscrolling = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isscrolling == true)
|
||||||
|
{
|
||||||
|
scrollamount += 20;
|
||||||
|
if(scrollamount > 240)
|
||||||
|
{
|
||||||
|
scrollamount = 0;
|
||||||
|
isscrolling = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int redOffset = rand() % 4;
|
||||||
|
|
||||||
|
for(int x = 0; x < _src->w; x++)
|
||||||
|
{
|
||||||
|
for(int y = 0; y < _src->h; y++)
|
||||||
|
{
|
||||||
|
int sampley = (y + scrollamount )% 240;
|
||||||
|
|
||||||
|
Uint32 pixel = ReadPixel(_src, x,sampley);
|
||||||
|
|
||||||
|
Uint8 green = (pixel & _src->format->Gmask) >> 8;
|
||||||
|
Uint8 blue = (pixel & _src->format->Bmask) >> 0;
|
||||||
|
|
||||||
|
Uint32 pixelOffset = ReadPixel(_src, std::min(x+redOffset, 319), sampley) ;
|
||||||
|
Uint8 red = (pixelOffset & _src->format->Rmask) >> 16 ;
|
||||||
|
|
||||||
|
if(isscrolling && sampley > 220 && ((rand() %10) < 4))
|
||||||
|
{
|
||||||
|
red = std::min(int(red+(fRandom() * 0.6) * 254) , 255);
|
||||||
|
green = std::min(int(green+(fRandom() * 0.6) * 254) , 255);
|
||||||
|
blue = std::min(int(blue+(fRandom() * 0.6) * 254) , 255);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
red = std::min(int(red+(fRandom() * 0.2) * 254) , 255);
|
||||||
|
green = std::min(int(green+(fRandom() * 0.2) * 254) , 255);
|
||||||
|
blue = std::min(int(blue+(fRandom() * 0.2) * 254) , 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(y % 2 == 0)
|
||||||
|
{
|
||||||
|
red = static_cast<Uint8>(red / 1.2f);
|
||||||
|
green = static_cast<Uint8>(green / 1.2f);
|
||||||
|
blue = static_cast<Uint8>(blue / 1.2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int distX = static_cast<int>((abs (160.0f -x ) / 160.0f) *16);
|
||||||
|
int distY = static_cast<int>((abs (120.0f -y ) / 120.0f)*32);
|
||||||
|
|
||||||
|
red = std::max(red - ( distX +distY), 0);
|
||||||
|
green = std::max(green - ( distX +distY), 0);
|
||||||
|
blue = std::max(blue - ( distX +distY), 0);
|
||||||
|
|
||||||
|
Uint32 finalPixel = ((red<<16) + (green<<8) + (blue<<0)) | (pixel &_src->format->Amask);
|
||||||
|
DrawPixel(_ret,x,y, finalPixel);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillRect( SDL_Surface* _surface, const int _x, const int _y, const int _w, const int _h, const int r, int g, int b )
|
||||||
|
{
|
||||||
|
SDL_Rect rect = {Sint16(_x),Sint16(_y),Sint16(_w),Sint16(_h)};
|
||||||
|
Uint32 color;
|
||||||
|
color = SDL_MapRGB(_surface->format, r, g, b);
|
||||||
|
SDL_FillRect(_surface, &rect, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillRect( SDL_Surface* _surface, const int r, int g, int b )
|
||||||
|
{
|
||||||
|
SDL_Rect rect = {0,0,Uint16(_surface->w) ,Uint16(_surface->h) };
|
||||||
|
Uint32 color;
|
||||||
|
color = SDL_MapRGB(_surface->format, r, g, b);
|
||||||
|
SDL_FillRect(_surface, &rect, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillRect( SDL_Surface* _surface, const int color )
|
||||||
|
{
|
||||||
|
SDL_Rect rect = {0,0,Uint16(_surface->w) ,Uint16(_surface->h) };
|
||||||
|
SDL_FillRect(_surface, &rect, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillRect( SDL_Surface* _surface, const int x, const int y, const int w, const int h, int rgba )
|
||||||
|
{
|
||||||
|
SDL_Rect rect = {Sint16(x) ,Sint16(y) ,Sint16(w) ,Sint16(h) };
|
||||||
|
SDL_FillRect(_surface, &rect, rgba);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillRect( SDL_Surface* _surface, SDL_Rect& _rect, const int r, int g, int b )
|
||||||
|
{
|
||||||
|
Uint32 color;
|
||||||
|
color = SDL_MapRGB(_surface->format, r, g, b);
|
||||||
|
SDL_FillRect(_surface, &_rect, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillRect( SDL_Surface* _surface, SDL_Rect rect, int rgba )
|
||||||
|
{
|
||||||
|
SDL_FillRect(_surface, &rect, rgba);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool intersectRect( float left1, float right1, float bottom1, float top1, float left2, float right2, float bottom2, float top2 )
|
||||||
|
{
|
||||||
|
return !( left2 > right1 || right2 < left1 || top2 < bottom1 || bottom2 > top1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlaySurfaceKeyed( SDL_Surface* _src, SDL_Surface* _dest, Uint32 _key )
|
||||||
|
{
|
||||||
|
// const SDL_PixelFormat& fmt = *(_src->format);
|
||||||
|
for(int x = 0; x < _src->w; x++)
|
||||||
|
{
|
||||||
|
for(int y = 0; y < _src->h; y++)
|
||||||
|
{
|
||||||
|
Uint32 pixel = ReadPixel(_src, x,y);
|
||||||
|
//endian_swap(pixel);
|
||||||
|
if (( pixel != _key))
|
||||||
|
{
|
||||||
|
DrawPixel(_dest,x,y, pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScrollSurface( SDL_Surface* _src, int _pX, int _pY )
|
||||||
|
{
|
||||||
|
SDL_Surface* part1 = NULL;
|
||||||
|
|
||||||
|
SDL_Rect rect1;
|
||||||
|
SDL_Rect rect2;
|
||||||
|
//scrolling up;
|
||||||
|
if(_pY < 0)
|
||||||
|
{
|
||||||
|
setRect(rect2, 0, 0, _src->w, _src->h - _pY);
|
||||||
|
|
||||||
|
part1 = GetSubSurface(_src, rect2.x, rect2.y, rect2.w, rect2.h);
|
||||||
|
|
||||||
|
SDL_Rect destrect1;
|
||||||
|
|
||||||
|
SDL_SetSurfaceBlendMode(part1, SDL_BLENDMODE_NONE);
|
||||||
|
|
||||||
|
setRect(destrect1, 0, _pY, _pX, _src->h);
|
||||||
|
|
||||||
|
SDL_BlitSurface (part1, NULL, _src, &destrect1);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(_pY > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
setRect(rect1, 0, 0, _src->w, _src->h - _pY);
|
||||||
|
|
||||||
|
part1 = GetSubSurface(_src, rect1.x, rect1.y, rect1.w, rect1.h);
|
||||||
|
|
||||||
|
SDL_Rect destrect1;
|
||||||
|
|
||||||
|
SDL_SetSurfaceBlendMode(part1, SDL_BLENDMODE_NONE);
|
||||||
|
|
||||||
|
setRect(destrect1, _pX, _pY, _src->w, _src->h - _pY);
|
||||||
|
|
||||||
|
SDL_BlitSurface (part1, NULL, _src, &destrect1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Right
|
||||||
|
else if(_pX <= 0)
|
||||||
|
{
|
||||||
|
setRect(rect2, 0, 0, _src->w - _pX, _src->h );
|
||||||
|
|
||||||
|
part1 = GetSubSurface(_src, rect2.x, rect2.y, rect2.w, rect2.h);
|
||||||
|
|
||||||
|
SDL_Rect destrect1;
|
||||||
|
|
||||||
|
SDL_SetSurfaceBlendMode(part1, SDL_BLENDMODE_NONE);
|
||||||
|
|
||||||
|
setRect(destrect1, _pX, 0, _src->w - _pX, _src->h);
|
||||||
|
|
||||||
|
SDL_BlitSurface (part1, NULL, _src, &destrect1);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(_pX > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
setRect(rect1, _pX, 0, _src->w - _pX, _src->h );
|
||||||
|
|
||||||
|
part1 = GetSubSurface(_src, rect1.x, rect1.y, rect1.w, rect1.h);
|
||||||
|
|
||||||
|
SDL_Rect destrect1;
|
||||||
|
|
||||||
|
SDL_SetSurfaceBlendMode(part1, SDL_BLENDMODE_NONE);
|
||||||
|
|
||||||
|
setRect(destrect1, 0, 0, _src->w - _pX, _src->h);
|
||||||
|
|
||||||
|
SDL_BlitSurface (part1, NULL, _src, &destrect1);
|
||||||
|
|
||||||
|
}
|
||||||
|
//Cleanup temp surface
|
||||||
|
if (part1)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(part1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
51
desktop_version/src/GraphicsUtil.h
Normal file
51
desktop_version/src/GraphicsUtil.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#ifndef GRAPHICSUTIL_H
|
||||||
|
#define GRAPHICSUTIL_H
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
|
||||||
|
struct colourTransform
|
||||||
|
{
|
||||||
|
Uint32 colour;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void setRect(SDL_Rect& _r, int x, int y, int w, int h);
|
||||||
|
|
||||||
|
unsigned int endian_swap(unsigned int x);
|
||||||
|
|
||||||
|
SDL_Surface* GetSubSurface( SDL_Surface* metaSurface, int x, int y, int width, int height );
|
||||||
|
|
||||||
|
void DrawPixel( SDL_Surface *surface, int x, int y, Uint32 pixel );
|
||||||
|
|
||||||
|
Uint32 ReadPixel( SDL_Surface *surface, int x, int y );
|
||||||
|
|
||||||
|
SDL_Surface * ScaleSurface( SDL_Surface *Surface, int Width, int Height, SDL_Surface * Dest = NULL );
|
||||||
|
|
||||||
|
void BlitSurfaceStandard( SDL_Surface* _src, SDL_Rect* _srcRect, SDL_Surface* _dest, SDL_Rect* _destRect );
|
||||||
|
|
||||||
|
void BlitSurfaceColoured( SDL_Surface* _src, SDL_Rect* _srcRect, SDL_Surface* _dest, SDL_Rect* _destRect, colourTransform& ct );
|
||||||
|
|
||||||
|
void FillRect( SDL_Surface* surface, const int x, const int y, const int w, const int h, const int r, int g, int b );
|
||||||
|
|
||||||
|
void FillRect( SDL_Surface* surface, const int r, int g, int b );
|
||||||
|
|
||||||
|
void FillRect( SDL_Surface* surface, const int color );
|
||||||
|
|
||||||
|
void FillRect( SDL_Surface* surface, const int x, const int y, const int w, const int h, int rgba );
|
||||||
|
|
||||||
|
void FillRect( SDL_Surface* surface, SDL_Rect& rect, const int r, int g, int b );
|
||||||
|
|
||||||
|
void FillRect( SDL_Surface* surface, SDL_Rect rect, int rgba );
|
||||||
|
|
||||||
|
bool intersectRect(float left1, float right1, float bottom1, float top1, float left2, float right2, float bottom2, float top2);
|
||||||
|
|
||||||
|
void OverlaySurfaceKeyed(SDL_Surface* _src, SDL_Surface* _dest, Uint32 _key);
|
||||||
|
|
||||||
|
void ScrollSurface(SDL_Surface* _src, int pX, int py);
|
||||||
|
|
||||||
|
SDL_Surface * FlipSurfaceHorizontal(SDL_Surface* _src);
|
||||||
|
SDL_Surface * FlipSurfaceVerticle(SDL_Surface* _src);
|
||||||
|
SDL_Surface * ScaleSurfaceSlow( SDL_Surface *_surface, int Width, int Height );
|
||||||
|
SDL_Surface* ApplyFilter( SDL_Surface* _src );
|
||||||
|
|
||||||
|
#endif /* GRAPHICSUTIL_H */
|
||||||
2546
desktop_version/src/Input.cpp
Normal file
2546
desktop_version/src/Input.cpp
Normal file
File diff suppressed because it is too large
Load Diff
30
desktop_version/src/Input.h
Normal file
30
desktop_version/src/Input.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#ifndef INPUT_H
|
||||||
|
#define INPUT_H
|
||||||
|
|
||||||
|
#include "KeyPoll.h"
|
||||||
|
#include "Graphics.h"
|
||||||
|
#include "Game.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "UtilityClass.h"
|
||||||
|
#include "Music.h"
|
||||||
|
#include "Map.h"
|
||||||
|
|
||||||
|
void titleinput(KeyPoll& key, Graphics& dwgfx, mapclass& map, Game& game,
|
||||||
|
entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
void gameinput(KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map,
|
||||||
|
entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
void mapinput(KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map,
|
||||||
|
entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
void teleporterinput(KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map,
|
||||||
|
entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
void gamecompleteinput(KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map,
|
||||||
|
entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
void gamecompleteinput2(KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map,
|
||||||
|
entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
#endif /* INPUT_H */
|
||||||
333
desktop_version/src/KeyPoll.cpp
Normal file
333
desktop_version/src/KeyPoll.cpp
Normal file
@@ -0,0 +1,333 @@
|
|||||||
|
#include "KeyPoll.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void KeyPoll::setSensitivity(int _value)
|
||||||
|
{
|
||||||
|
switch (_value)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
sensitivity = 28000;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
sensitivity = 16000;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sensitivity = 8000;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
sensitivity = 4000;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
sensitivity = 2000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyPoll::KeyPoll()
|
||||||
|
{
|
||||||
|
xVel = 0;
|
||||||
|
yVel = 0;
|
||||||
|
setSensitivity(2);
|
||||||
|
|
||||||
|
quitProgram = 0;
|
||||||
|
textentrymode=true;
|
||||||
|
keybuffer="";
|
||||||
|
leftbutton=0; rightbutton=0; middlebutton=0;
|
||||||
|
mx=0; my=0;
|
||||||
|
resetWindow = 0;
|
||||||
|
toggleFullscreen = false;
|
||||||
|
pressedbackspace=false;
|
||||||
|
|
||||||
|
useFullscreenSpaces = false;
|
||||||
|
if (strcmp(SDL_GetPlatform(), "Mac OS X") == 0)
|
||||||
|
{
|
||||||
|
useFullscreenSpaces = true;
|
||||||
|
const char *hint = SDL_GetHint(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES);
|
||||||
|
if (hint != NULL)
|
||||||
|
{
|
||||||
|
useFullscreenSpaces = (strcmp(hint, "1") == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyPoll::enabletextentry()
|
||||||
|
{
|
||||||
|
keybuffer="";
|
||||||
|
textentrymode = true;
|
||||||
|
SDL_StartTextInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyPoll::disabletextentry()
|
||||||
|
{
|
||||||
|
textentrymode = false;
|
||||||
|
SDL_StopTextInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyPoll::Poll()
|
||||||
|
{
|
||||||
|
SDL_Event evt;
|
||||||
|
while (SDL_PollEvent(&evt))
|
||||||
|
{
|
||||||
|
/* Keyboard Input */
|
||||||
|
if (evt.type == SDL_KEYDOWN)
|
||||||
|
{
|
||||||
|
keymap[evt.key.keysym.sym] = true;
|
||||||
|
if (evt.key.keysym.sym == SDLK_BACKSPACE)
|
||||||
|
{
|
||||||
|
pressedbackspace = true;
|
||||||
|
}
|
||||||
|
else if ( ( evt.key.keysym.sym == SDLK_RETURN ||
|
||||||
|
evt.key.keysym.sym == SDLK_f ) &&
|
||||||
|
#ifdef __APPLE__ /* OSX prefers the command key over the alt keys. -flibit */
|
||||||
|
keymap[SDLK_LGUI] )
|
||||||
|
#else
|
||||||
|
( keymap[SDLK_LALT] ||
|
||||||
|
keymap[SDLK_RALT] ) )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
toggleFullscreen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textentrymode)
|
||||||
|
{
|
||||||
|
if (evt.key.keysym.sym == SDLK_BACKSPACE)
|
||||||
|
{
|
||||||
|
keybuffer = keybuffer.substr(0, keybuffer.length() - 1);
|
||||||
|
}
|
||||||
|
else if ( evt.key.keysym.sym == SDLK_v &&
|
||||||
|
keymap[SDLK_LCTRL] )
|
||||||
|
{
|
||||||
|
keybuffer += SDL_GetClipboardText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (evt.type == SDL_KEYUP)
|
||||||
|
{
|
||||||
|
keymap[evt.key.keysym.sym] = false;
|
||||||
|
if (evt.key.keysym.sym == SDLK_BACKSPACE)
|
||||||
|
{
|
||||||
|
pressedbackspace = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (evt.type == SDL_TEXTINPUT)
|
||||||
|
{
|
||||||
|
keybuffer += evt.text.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mouse Input */
|
||||||
|
else if (evt.type == SDL_MOUSEMOTION)
|
||||||
|
{
|
||||||
|
mx = evt.motion.x;
|
||||||
|
my = evt.motion.y;
|
||||||
|
}
|
||||||
|
else if (evt.type == SDL_MOUSEBUTTONDOWN)
|
||||||
|
{
|
||||||
|
if (evt.button.button == SDL_BUTTON_LEFT)
|
||||||
|
{
|
||||||
|
mx = evt.button.x;
|
||||||
|
my = evt.button.y;
|
||||||
|
leftbutton = 1;
|
||||||
|
}
|
||||||
|
else if (evt.button.button == SDL_BUTTON_RIGHT)
|
||||||
|
{
|
||||||
|
mx = evt.button.x;
|
||||||
|
my = evt.button.y;
|
||||||
|
rightbutton = 1;
|
||||||
|
}
|
||||||
|
else if (evt.button.button == SDL_BUTTON_MIDDLE)
|
||||||
|
{
|
||||||
|
mx = evt.button.x;
|
||||||
|
my = evt.button.y;
|
||||||
|
middlebutton = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (evt.type == SDL_MOUSEBUTTONUP)
|
||||||
|
{
|
||||||
|
if (evt.button.button == SDL_BUTTON_LEFT)
|
||||||
|
{
|
||||||
|
mx = evt.button.x;
|
||||||
|
my = evt.button.y;
|
||||||
|
leftbutton=0;
|
||||||
|
}
|
||||||
|
else if (evt.button.button == SDL_BUTTON_RIGHT)
|
||||||
|
{
|
||||||
|
mx = evt.button.x;
|
||||||
|
my = evt.button.y;
|
||||||
|
rightbutton=0;
|
||||||
|
}
|
||||||
|
else if (evt.button.button == SDL_BUTTON_MIDDLE)
|
||||||
|
{
|
||||||
|
mx = evt.button.x;
|
||||||
|
my = evt.button.y;
|
||||||
|
middlebutton=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Controller Input */
|
||||||
|
else if (evt.type == SDL_CONTROLLERBUTTONDOWN)
|
||||||
|
{
|
||||||
|
buttonmap[(SDL_GameControllerButton) evt.cbutton.button] = true;
|
||||||
|
}
|
||||||
|
else if (evt.type == SDL_CONTROLLERBUTTONUP)
|
||||||
|
{
|
||||||
|
buttonmap[(SDL_GameControllerButton) evt.cbutton.button] = false;
|
||||||
|
}
|
||||||
|
else if (evt.type == SDL_CONTROLLERAXISMOTION)
|
||||||
|
{
|
||||||
|
if (evt.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX)
|
||||||
|
{
|
||||||
|
if ( evt.caxis.value > -sensitivity &&
|
||||||
|
evt.caxis.value < sensitivity )
|
||||||
|
{
|
||||||
|
xVel = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xVel = (evt.caxis.value > 0) ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (evt.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY)
|
||||||
|
{
|
||||||
|
if ( evt.caxis.value > -sensitivity &&
|
||||||
|
evt.caxis.value < sensitivity )
|
||||||
|
{
|
||||||
|
yVel = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yVel = (evt.caxis.value > 0) ? 1 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (evt.type == SDL_CONTROLLERDEVICEADDED)
|
||||||
|
{
|
||||||
|
SDL_GameController *toOpen = SDL_GameControllerOpen(evt.cdevice.which);
|
||||||
|
printf(
|
||||||
|
"Opened SDL_GameController ID #%i, %s\n",
|
||||||
|
evt.cdevice.which,
|
||||||
|
SDL_GameControllerName(toOpen)
|
||||||
|
);
|
||||||
|
controllers[SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(toOpen))] = toOpen;
|
||||||
|
}
|
||||||
|
else if (evt.type == SDL_CONTROLLERDEVICEREMOVED)
|
||||||
|
{
|
||||||
|
SDL_GameController *toClose = controllers[evt.cdevice.which];
|
||||||
|
controllers.erase(evt.cdevice.which);
|
||||||
|
printf("Closing %s\n", SDL_GameControllerName(toClose));
|
||||||
|
SDL_GameControllerClose(toClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Window Events */
|
||||||
|
else if (evt.type == SDL_WINDOWEVENT)
|
||||||
|
{
|
||||||
|
/* Window Resize */
|
||||||
|
if (evt.window.event == SDL_WINDOWEVENT_RESIZED)
|
||||||
|
{
|
||||||
|
resetWindow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Window Focus */
|
||||||
|
else if (evt.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
||||||
|
{
|
||||||
|
isActive = true;
|
||||||
|
if (!useFullscreenSpaces)
|
||||||
|
{
|
||||||
|
SDL_Window *window = SDL_GetWindowFromID(evt.window.windowID);
|
||||||
|
wasFullscreen = SDL_GetWindowFlags(window);
|
||||||
|
SDL_SetWindowFullscreen(window, 0);
|
||||||
|
}
|
||||||
|
SDL_DisableScreenSaver();
|
||||||
|
}
|
||||||
|
else if (evt.window.event == SDL_WINDOWEVENT_FOCUS_LOST)
|
||||||
|
{
|
||||||
|
isActive = false;
|
||||||
|
if (!useFullscreenSpaces)
|
||||||
|
{
|
||||||
|
SDL_SetWindowFullscreen(
|
||||||
|
SDL_GetWindowFromID(evt.window.windowID),
|
||||||
|
wasFullscreen
|
||||||
|
);
|
||||||
|
}
|
||||||
|
SDL_EnableScreenSaver();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mouse Focus */
|
||||||
|
else if (evt.window.event == SDL_WINDOWEVENT_ENTER)
|
||||||
|
{
|
||||||
|
SDL_DisableScreenSaver();
|
||||||
|
}
|
||||||
|
else if (evt.window.event == SDL_WINDOWEVENT_LEAVE)
|
||||||
|
{
|
||||||
|
SDL_EnableScreenSaver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Quit Event */
|
||||||
|
else if (evt.type == SDL_QUIT)
|
||||||
|
{
|
||||||
|
quitProgram = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyPoll::isDown(SDL_Keycode key)
|
||||||
|
{
|
||||||
|
return keymap[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyPoll::isUp(SDL_Keycode key)
|
||||||
|
{
|
||||||
|
return !keymap[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyPoll::isDown(std::vector<SDL_GameControllerButton> buttons)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < buttons.size(); i += 1)
|
||||||
|
{
|
||||||
|
if (buttonmap[buttons[i]])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyPoll::isDown(SDL_GameControllerButton button)
|
||||||
|
{
|
||||||
|
return buttonmap[button];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyPoll::controllerButtonDown()
|
||||||
|
{
|
||||||
|
for (
|
||||||
|
SDL_GameControllerButton button = SDL_CONTROLLER_BUTTON_A;
|
||||||
|
button < SDL_CONTROLLER_BUTTON_DPAD_UP;
|
||||||
|
button = (SDL_GameControllerButton) (button + 1)
|
||||||
|
) {
|
||||||
|
if (isDown(button))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyPoll::controllerWantsLeft(bool includeVert)
|
||||||
|
{
|
||||||
|
return ( buttonmap[SDL_CONTROLLER_BUTTON_DPAD_LEFT] ||
|
||||||
|
xVel < 0 ||
|
||||||
|
( includeVert &&
|
||||||
|
( buttonmap[SDL_CONTROLLER_BUTTON_DPAD_UP] ||
|
||||||
|
yVel < 0 ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyPoll::controllerWantsRight(bool includeVert)
|
||||||
|
{
|
||||||
|
return ( buttonmap[SDL_CONTROLLER_BUTTON_DPAD_RIGHT] ||
|
||||||
|
xVel > 0 ||
|
||||||
|
( includeVert &&
|
||||||
|
( buttonmap[SDL_CONTROLLER_BUTTON_DPAD_DOWN] ||
|
||||||
|
yVel > 0 ) ) );
|
||||||
|
}
|
||||||
83
desktop_version/src/KeyPoll.h
Normal file
83
desktop_version/src/KeyPoll.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#ifndef KEYPOLL_H
|
||||||
|
#define KEYPOLL_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map> // FIXME: I should feel very bad for using C++ -flibit
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
|
||||||
|
enum Kybrd
|
||||||
|
{
|
||||||
|
KEYBOARD_UP = SDLK_UP,
|
||||||
|
KEYBOARD_DOWN = SDLK_DOWN,
|
||||||
|
KEYBOARD_LEFT = SDLK_LEFT,
|
||||||
|
KEYBOARD_RIGHT = SDLK_RIGHT,
|
||||||
|
KEYBOARD_ENTER = SDLK_RETURN,
|
||||||
|
KEYBOARD_SPACE = SDLK_SPACE,
|
||||||
|
|
||||||
|
KEYBOARD_w = SDLK_w,
|
||||||
|
KEYBOARD_s = SDLK_s,
|
||||||
|
KEYBOARD_a = SDLK_a,
|
||||||
|
KEYBOARD_d = SDLK_d,
|
||||||
|
KEYBOARD_m = SDLK_m,
|
||||||
|
|
||||||
|
KEYBOARD_v = SDLK_v,
|
||||||
|
KEYBOARD_z = SDLK_z,
|
||||||
|
|
||||||
|
KEYBOARD_BACKSPACE = SDLK_BACKSPACE
|
||||||
|
};
|
||||||
|
|
||||||
|
class KeyPoll
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::map<SDL_Keycode, bool> keymap;
|
||||||
|
|
||||||
|
bool isActive;
|
||||||
|
|
||||||
|
bool resetWindow;
|
||||||
|
|
||||||
|
bool escapeWasPressedPreviously;
|
||||||
|
bool quitProgram;
|
||||||
|
bool toggleFullscreen;
|
||||||
|
|
||||||
|
int sensitivity;
|
||||||
|
|
||||||
|
void setSensitivity(int _value);
|
||||||
|
|
||||||
|
KeyPoll();
|
||||||
|
|
||||||
|
void enabletextentry();
|
||||||
|
|
||||||
|
void disabletextentry();
|
||||||
|
|
||||||
|
void Poll();
|
||||||
|
|
||||||
|
bool isDown(SDL_Keycode key);
|
||||||
|
|
||||||
|
bool isUp(SDL_Keycode key);
|
||||||
|
|
||||||
|
bool isDown(std::vector<SDL_GameControllerButton> buttons);
|
||||||
|
bool isDown(SDL_GameControllerButton button);
|
||||||
|
bool controllerButtonDown();
|
||||||
|
bool controllerWantsLeft(bool includeVert);
|
||||||
|
bool controllerWantsRight(bool includeVert);
|
||||||
|
|
||||||
|
int leftbutton, rightbutton, middlebutton;
|
||||||
|
int mx, my;
|
||||||
|
|
||||||
|
bool textentrymode;
|
||||||
|
int keyentered, keybufferlen;
|
||||||
|
bool pressedbackspace;
|
||||||
|
std::string keybuffer;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<SDL_JoystickID, SDL_GameController*> controllers;
|
||||||
|
std::map<SDL_GameControllerButton, bool> buttonmap;
|
||||||
|
int xVel, yVel;
|
||||||
|
bool useFullscreenSpaces;
|
||||||
|
Uint32 wasFullscreen;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* KEYPOLL_H */
|
||||||
1862
desktop_version/src/Labclass.cpp
Normal file
1862
desktop_version/src/Labclass.cpp
Normal file
File diff suppressed because it is too large
Load Diff
18
desktop_version/src/Labclass.h
Normal file
18
desktop_version/src/Labclass.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef LABCLASS_H
|
||||||
|
#define LABCLASS_H
|
||||||
|
|
||||||
|
#include "Game.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class labclass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<std::string> loadlevel(int rx, int ry , Game& game, entityclass& obj);
|
||||||
|
|
||||||
|
std::string roomname;
|
||||||
|
int coin, rcol;
|
||||||
|
};
|
||||||
|
#endif /* LABCLASS_H */
|
||||||
1547
desktop_version/src/Logic.cpp
Normal file
1547
desktop_version/src/Logic.cpp
Normal file
File diff suppressed because it is too large
Load Diff
23
desktop_version/src/Logic.h
Normal file
23
desktop_version/src/Logic.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef LOGIC_H
|
||||||
|
#define LOGIC_H
|
||||||
|
|
||||||
|
#include "Graphics.h"
|
||||||
|
#include "Game.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "UtilityClass.h"
|
||||||
|
#include "Music.h"
|
||||||
|
#include "Map.h"
|
||||||
|
|
||||||
|
void titlelogic(Graphics& dwgfx, Game& game, entityclass& obj, UtilityClass& help, musicclass& music, mapclass& map);
|
||||||
|
|
||||||
|
void maplogic(Graphics& dwgfx, Game& game, entityclass& obj, musicclass& music, mapclass& map, UtilityClass& help);
|
||||||
|
|
||||||
|
void gamecompletelogic(Graphics& dwgfx, Game& game, entityclass& obj, musicclass& music, mapclass& map, UtilityClass& help);
|
||||||
|
|
||||||
|
void gamecompletelogic2(Graphics& dwgfx, Game& game, entityclass& obj, musicclass& music, mapclass& map, UtilityClass& help);
|
||||||
|
|
||||||
|
void towerlogic(Graphics& dwgfx, Game& game, entityclass& obj, musicclass& music, mapclass& map, UtilityClass& help);
|
||||||
|
|
||||||
|
void gamelogic(Graphics& dwgfx, Game& game, entityclass& obj, musicclass& music, mapclass& map, UtilityClass& help);
|
||||||
|
|
||||||
|
#endif /* LOGIC_H */
|
||||||
10
desktop_version/src/MakeAndPlay.h
Normal file
10
desktop_version/src/MakeAndPlay.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef MAKEANDPLAY_H
|
||||||
|
#define MAKEANDPLAY_H
|
||||||
|
|
||||||
|
/* This is a cheap way to deal with the MAKEANDPLAY def when recompiling.
|
||||||
|
* It's heaps faster than rebuilding everything, so here we are.
|
||||||
|
* -flibit
|
||||||
|
*/
|
||||||
|
// #define MAKEANDPLAY
|
||||||
|
|
||||||
|
#endif /* MAKEANDPLAY_H */
|
||||||
1997
desktop_version/src/Map.cpp
Normal file
1997
desktop_version/src/Map.cpp
Normal file
File diff suppressed because it is too large
Load Diff
182
desktop_version/src/Map.h
Normal file
182
desktop_version/src/Map.h
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
#ifndef MAPGAME_H
|
||||||
|
#define MAPGAME_H
|
||||||
|
|
||||||
|
#include "Tower.h"
|
||||||
|
#include "WarpClass.h"
|
||||||
|
#include "Finalclass.h"
|
||||||
|
#include "Labclass.h"
|
||||||
|
#include "Spacestation2.h"
|
||||||
|
#include "Otherlevel.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "Graphics.h"
|
||||||
|
#include <vector>
|
||||||
|
#include "Music.h"
|
||||||
|
#include "editor.h"
|
||||||
|
|
||||||
|
extern editorclass ed;
|
||||||
|
|
||||||
|
class mapclass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
mapclass();
|
||||||
|
|
||||||
|
int RGB(int red,int green,int blue);
|
||||||
|
|
||||||
|
int intpol(int a, int b, float c);
|
||||||
|
|
||||||
|
void setteleporter(int t, int x, int y);
|
||||||
|
|
||||||
|
void settrinket(int t, int x, int y);
|
||||||
|
|
||||||
|
void resetmap();
|
||||||
|
|
||||||
|
void resetnames();
|
||||||
|
|
||||||
|
void transformname(int t);
|
||||||
|
|
||||||
|
std::string getglitchname(int x, int y);
|
||||||
|
|
||||||
|
void initmapdata();
|
||||||
|
|
||||||
|
int finalat(int x, int y);
|
||||||
|
|
||||||
|
int maptiletoenemycol(int t);
|
||||||
|
|
||||||
|
void changefinalcol(int t, entityclass& obj, Game& game);
|
||||||
|
|
||||||
|
void setcol(const int r1, const int g1, const int b1 , const int r2, const int g2, const int b2, const int c);
|
||||||
|
|
||||||
|
void updatetowerglow();
|
||||||
|
|
||||||
|
void nexttowercolour();
|
||||||
|
|
||||||
|
void settowercolour(int t);
|
||||||
|
|
||||||
|
bool spikecollide(int x, int y);
|
||||||
|
|
||||||
|
bool collide(int x, int y);
|
||||||
|
|
||||||
|
void fillareamap(std::vector<std::string>& tmap);
|
||||||
|
|
||||||
|
void settile(int xp, int yp, int t);
|
||||||
|
|
||||||
|
void fillcontent(std::vector<std::string>& tmap);
|
||||||
|
|
||||||
|
|
||||||
|
int area(int _rx, int _ry);
|
||||||
|
|
||||||
|
void exploretower();
|
||||||
|
|
||||||
|
void hideship();
|
||||||
|
|
||||||
|
void showship();
|
||||||
|
|
||||||
|
void resetplayer(Graphics& dwgfx, Game& game, entityclass& obj, musicclass& music);
|
||||||
|
|
||||||
|
void warpto(int rx, int ry , int t, int tx, int ty, Graphics& dwgfx, Game& game, entityclass& obj, musicclass& music);
|
||||||
|
|
||||||
|
void gotoroom(int rx, int ry, Graphics& dwgfx, Game& game, entityclass& obj, musicclass& music);
|
||||||
|
|
||||||
|
std::string currentarea(int t);
|
||||||
|
|
||||||
|
void loadlevel(int rx, int ry, Graphics& dwgfx, Game& game, entityclass& obj, musicclass& music);
|
||||||
|
|
||||||
|
|
||||||
|
std::vector <int> roomdeaths;
|
||||||
|
std::vector <int> roomdeathsfinal;
|
||||||
|
std::vector <int> areamap;
|
||||||
|
std::vector <int> contents;
|
||||||
|
std::vector <int> explored;
|
||||||
|
std::vector <int> vmult;
|
||||||
|
std::vector <std::string> tmap;
|
||||||
|
|
||||||
|
int temp;
|
||||||
|
int temp2;
|
||||||
|
int j;
|
||||||
|
int background;
|
||||||
|
int rcol;
|
||||||
|
int tileset;
|
||||||
|
bool warpx;
|
||||||
|
bool warpy;
|
||||||
|
|
||||||
|
|
||||||
|
std::string roomname;
|
||||||
|
|
||||||
|
//Special tower stuff
|
||||||
|
bool towermode;
|
||||||
|
float ypos;
|
||||||
|
int bypos;
|
||||||
|
int cameramode;
|
||||||
|
int cameraseek, cameraseekframe;
|
||||||
|
int resumedelay;
|
||||||
|
bool minitowermode;
|
||||||
|
int scrolldir;
|
||||||
|
|
||||||
|
//This is the old colour cycle
|
||||||
|
int r, g,b;
|
||||||
|
int check, cmode;
|
||||||
|
int towercol;
|
||||||
|
int colstate, colstatedelay;
|
||||||
|
int colsuperstate;
|
||||||
|
int spikeleveltop, spikelevelbottom;
|
||||||
|
bool tdrawback;
|
||||||
|
int bscroll;
|
||||||
|
//final level navigation
|
||||||
|
int finalx;
|
||||||
|
int finaly;
|
||||||
|
bool finalmode;
|
||||||
|
bool finalstretch;
|
||||||
|
|
||||||
|
//Variables for playing custom levels
|
||||||
|
bool custommode;
|
||||||
|
bool custommodeforreal;
|
||||||
|
int customx, customy;
|
||||||
|
int customwidth, customheight;
|
||||||
|
int customtrinkets;
|
||||||
|
int customcrewmates;
|
||||||
|
int custommmxoff, custommmyoff, custommmxsize, custommmysize;
|
||||||
|
int customzoom;
|
||||||
|
bool customshowmm;
|
||||||
|
|
||||||
|
std::vector<std::string> specialnames;
|
||||||
|
int glitchmode;
|
||||||
|
int glitchdelay;
|
||||||
|
std::string glitchname;
|
||||||
|
|
||||||
|
//final level colour cycling stuff
|
||||||
|
bool final_colormode;
|
||||||
|
int final_mapcol;
|
||||||
|
int final_aniframe;
|
||||||
|
int final_aniframedelay;
|
||||||
|
int final_colorframe, final_colorframedelay;
|
||||||
|
|
||||||
|
//Teleporters and Trinkets on the map
|
||||||
|
std::vector<point> teleporters;
|
||||||
|
std::vector<point> shinytrinkets;
|
||||||
|
|
||||||
|
int numteleporters, numshinytrinkets;
|
||||||
|
bool showteleporters, showtargets, showtrinkets;
|
||||||
|
|
||||||
|
//Roomtext
|
||||||
|
int roomtextx[100], roomtexty[100];
|
||||||
|
bool roomtexton;
|
||||||
|
std::vector<std::string> roomtext;
|
||||||
|
int roomtextnumlines;
|
||||||
|
|
||||||
|
//Levels
|
||||||
|
otherlevelclass otherlevel;
|
||||||
|
spacestation2class spacestation2;
|
||||||
|
labclass lablevel;
|
||||||
|
finalclass finallevel;
|
||||||
|
warpclass warplevel;
|
||||||
|
towerclass tower;
|
||||||
|
int extrarow;
|
||||||
|
|
||||||
|
//Accessibility options
|
||||||
|
bool invincibility;
|
||||||
|
|
||||||
|
//Map cursor
|
||||||
|
int cursorstate, cursordelay;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MAPGAME_H */
|
||||||
28
desktop_version/src/Maths.h
Normal file
28
desktop_version/src/Maths.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef MATHGAME_H
|
||||||
|
#define MATHGAME_H
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//// This header holds Maths functions that emulate the functionality of flash's
|
||||||
|
|
||||||
|
|
||||||
|
//random
|
||||||
|
//Returns 0..1
|
||||||
|
float inline fRandom()
|
||||||
|
{
|
||||||
|
return ( float(rand()) / float(RAND_MAX)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int clamp(int x, int a, int b)
|
||||||
|
{
|
||||||
|
return x < a ? a : (x > b ? b : x);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct point
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MATHGAME_H */
|
||||||
454
desktop_version/src/Music.cpp
Normal file
454
desktop_version/src/Music.cpp
Normal file
@@ -0,0 +1,454 @@
|
|||||||
|
#include <SDL.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "Music.h"
|
||||||
|
#include "BinaryBlob.h"
|
||||||
|
|
||||||
|
musicclass::musicclass()
|
||||||
|
{
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/jump.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/jump2.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/hurt.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/souleyeminijingle.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/coin.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/save.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/crumble.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/vanish.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/blip.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/preteleport.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/teleport.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/crew1.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/crew2.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/crew3.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/crew4.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/crew5.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/crew6.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/terminal.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/gamesaved.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/crashing.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/blip2.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/countdown.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/go.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/crash.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/combine.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/newrecord.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/trophy.wav" ));
|
||||||
|
soundTracks.push_back(SoundTrack( "sounds/rescue.wav" ));
|
||||||
|
|
||||||
|
#ifdef VVV_COMPILEMUSIC
|
||||||
|
binaryBlob musicWriteBlob;
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/0levelcomplete.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/1pushingonwards.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/2positiveforce.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/3potentialforanything.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/4passionforexploring.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/5intermission.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/6presentingvvvvvv.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/7gamecomplete.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/8predestinedfate.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/9positiveforcereversed.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/10popularpotpourri.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/11pipedream.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/12pressurecooker.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/13pacedenergy.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/14piercingthesky.ogg");
|
||||||
|
musicWriteBlob.AddFileToBinaryBlob("data/music/predestinedfatefinallevel.ogg");
|
||||||
|
|
||||||
|
musicWriteBlob.writeBinaryBlob("data/BinaryMusic.vvv");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
binaryBlob musicReadBlob;
|
||||||
|
if (!musicReadBlob.unPackBinary("mmmmmm.vvv"))
|
||||||
|
{
|
||||||
|
mmmmmm = false;
|
||||||
|
usingmmmmmm=false;
|
||||||
|
bool ohCrap = musicReadBlob.unPackBinary("vvvvvvmusic.vvv");
|
||||||
|
SDL_assert(ohCrap && "Music not found!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mmmmmm = true;
|
||||||
|
usingmmmmmm = true;
|
||||||
|
int index = musicReadBlob.getIndex("data/music/0levelcomplete.ogg");
|
||||||
|
SDL_RWops *rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/1pushingonwards.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/2positiveforce.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/3potentialforanything.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/4passionforexploring.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/5intermission.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/6presentingvvvvvv.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/7gamecomplete.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/8predestinedfate.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/9positiveforcereversed.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/10popularpotpourri.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/11pipedream.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/12pressurecooker.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/13pacedenergy.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/14piercingthesky.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/predestinedfatefinallevel.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
bool ohCrap = musicReadBlob.unPackBinary("vvvvvvmusic.vvv");
|
||||||
|
SDL_assert(ohCrap && "Music not found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = musicReadBlob.getIndex("data/music/0levelcomplete.ogg");
|
||||||
|
SDL_RWops *rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/1pushingonwards.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/2positiveforce.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/3potentialforanything.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/4passionforexploring.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/5intermission.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/6presentingvvvvvv.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/7gamecomplete.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/8predestinedfate.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/9positiveforcereversed.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/10popularpotpourri.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/11pipedream.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/12pressurecooker.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/13pacedenergy.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/14piercingthesky.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
index = musicReadBlob.getIndex("data/music/predestinedfatefinallevel.ogg");
|
||||||
|
rw = SDL_RWFromMem(musicReadBlob.getAddress(index), musicReadBlob.getSize(index));
|
||||||
|
musicTracks.push_back(MusicTrack( rw ));
|
||||||
|
|
||||||
|
safeToProcessMusic= false;
|
||||||
|
m_doFadeInVol = false;
|
||||||
|
musicVolume = 128;
|
||||||
|
FadeVolAmountPerFrame = 0;
|
||||||
|
|
||||||
|
custompd = false;
|
||||||
|
// currentsong = -1;
|
||||||
|
// nicefade = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::play(int t)
|
||||||
|
{
|
||||||
|
t = (t % 16);
|
||||||
|
|
||||||
|
if(mmmmmm)
|
||||||
|
{
|
||||||
|
if(!usingmmmmmm)
|
||||||
|
{
|
||||||
|
t += 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
safeToProcessMusic = true;
|
||||||
|
Mix_VolumeMusic(128);
|
||||||
|
if (currentsong !=t)
|
||||||
|
{
|
||||||
|
if (currentsong != -1)
|
||||||
|
{
|
||||||
|
// Stop the old song first
|
||||||
|
// musicchannel.stop();
|
||||||
|
if (currentsong != 0)
|
||||||
|
{
|
||||||
|
// musicchannel.removeEventListener(Event.SOUND_COMPLETE, loopmusic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t != -1)
|
||||||
|
{
|
||||||
|
// musicfade = 0;
|
||||||
|
currentsong = t;
|
||||||
|
if (currentsong == 0 || currentsong == 7)
|
||||||
|
{
|
||||||
|
// Level Complete theme, no fade in or repeat
|
||||||
|
// musicchannel = musicchan[currentsong].play(0);
|
||||||
|
// musicchannel.soundTransform = new SoundTransform(1.0);
|
||||||
|
if(Mix_FadeInMusic(musicTracks[t].m_music, 0, 0)==-1)
|
||||||
|
{
|
||||||
|
printf("Mix_PlayMusic: %s\n", Mix_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// musicfadein = 90;
|
||||||
|
// musicchannel = musicchan[currentsong].play(0);
|
||||||
|
// musicchannel.soundTransform = new SoundTransform(0);
|
||||||
|
// musicchannel.addEventListener(Event.SOUND_COMPLETE, loopmusic);
|
||||||
|
if(Mix_FadeInMusic(musicTracks[t].m_music, -1, 3000)==-1)
|
||||||
|
{
|
||||||
|
printf("Mix_FadeInMusic: %s\n", Mix_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentsong = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::loopmusic()
|
||||||
|
{
|
||||||
|
//musicchannel.removeEventListener(Event.SOUND_COMPLETE, loopmusic);
|
||||||
|
//if(currentsong>-1){
|
||||||
|
// musicchannel = musicchan[currentsong].play();
|
||||||
|
// musicchannel.addEventListener(Event.SOUND_COMPLETE, loopmusic);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::stopmusic()
|
||||||
|
{
|
||||||
|
// musicchannel.removeEventListener(Event.SOUND_COMPLETE, stopmusic);
|
||||||
|
// musicchannel.stop();
|
||||||
|
Mix_HaltMusic();
|
||||||
|
currentsong = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::haltdasmusik()
|
||||||
|
{
|
||||||
|
// musicchannel.removeEventListener(Event.SOUND_COMPLETE, stopmusic);
|
||||||
|
// musicchannel.stop();
|
||||||
|
// resumesong = currentsong;
|
||||||
|
Mix_HaltMusic();
|
||||||
|
currentsong = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::silencedasmusik()
|
||||||
|
{
|
||||||
|
//if(currentsong>-1){
|
||||||
|
// musicchannel.soundTransform = new SoundTransform(0);
|
||||||
|
//}
|
||||||
|
Mix_VolumeMusic(0) ;
|
||||||
|
musicVolume = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::fadeMusicVolumeIn(int ms)
|
||||||
|
{
|
||||||
|
m_doFadeInVol = true;
|
||||||
|
FadeVolAmountPerFrame = MIX_MAX_VOLUME / (ms / 33);
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::fadeout()
|
||||||
|
{
|
||||||
|
//if(currentsong>-1){
|
||||||
|
// if (musicfade == 0) {
|
||||||
|
// musicchannel.removeEventListener(Event.SOUND_COMPLETE, stopmusic);
|
||||||
|
// musicfade = 61;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
Mix_FadeOutMusic(2000);
|
||||||
|
currentsong = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::processmusicfade()
|
||||||
|
{
|
||||||
|
//musicfade--;
|
||||||
|
//if (musicfade > 0) {
|
||||||
|
// musicchannel.soundTransform = new SoundTransform(musicfade / 60);
|
||||||
|
//}else {
|
||||||
|
// musicchannel.stop();
|
||||||
|
// currentsong = -1;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::processmusicfadein()
|
||||||
|
{
|
||||||
|
musicVolume += FadeVolAmountPerFrame;
|
||||||
|
Mix_VolumeMusic(musicVolume);
|
||||||
|
if (musicVolume >= MIX_MAX_VOLUME)
|
||||||
|
{
|
||||||
|
m_doFadeInVol = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::processmusic()
|
||||||
|
{
|
||||||
|
if(!safeToProcessMusic)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (musicfade > 0) processmusicfade();
|
||||||
|
//if (musicfadein > 0) processmusicfadein();
|
||||||
|
|
||||||
|
if (nicefade == 1 && Mix_PlayingMusic() == 0)
|
||||||
|
{
|
||||||
|
play(nicechange);
|
||||||
|
nicechange = -1; nicefade = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_doFadeInVol)
|
||||||
|
{
|
||||||
|
processmusicfadein();
|
||||||
|
}
|
||||||
|
|
||||||
|
//musicstopother--;
|
||||||
|
//if (musicstopother == 1) {
|
||||||
|
// musicstopother = 0;
|
||||||
|
// if (currentmusicchan == 0) musicchannel2.stop();
|
||||||
|
// if (currentmusicchan == 1) musicchannel.stop();
|
||||||
|
//}
|
||||||
|
//if (musicstopother < 0) musicstopother = 0;
|
||||||
|
|
||||||
|
//musicchancur--;
|
||||||
|
//if (musicchancur <= 0 && currentsong > -1 && musicchanlen > 0) {
|
||||||
|
// musicchancur = musicchanlen;
|
||||||
|
// if (currentmusicchan == 0) {
|
||||||
|
// musicchannel2 = musicchan[currentsong].play();
|
||||||
|
// musicstopother = 3;
|
||||||
|
// currentmusicchan = 1;
|
||||||
|
// }else {
|
||||||
|
// musicchannel = musicchan[currentsong].play();
|
||||||
|
// musicstopother = 3;
|
||||||
|
// currentmusicchan = 0;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void musicclass::niceplay(int t)
|
||||||
|
{
|
||||||
|
// important: do nothing if the correct song is playing!
|
||||||
|
if(currentsong!=t)
|
||||||
|
{
|
||||||
|
if(currentsong!=-1) fadeout();
|
||||||
|
nicefade = 1;
|
||||||
|
nicechange = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::changemusicarea(int x, int y)
|
||||||
|
{
|
||||||
|
switch(musicroom(x, y))
|
||||||
|
{
|
||||||
|
case musicroom(11, 4):
|
||||||
|
niceplay(2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case musicroom(2, 4):
|
||||||
|
case musicroom(7, 15):
|
||||||
|
niceplay(3);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case musicroom(18, 1):
|
||||||
|
case musicroom(15, 0):
|
||||||
|
niceplay(12);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case musicroom(0, 0):
|
||||||
|
case musicroom(0, 16):
|
||||||
|
case musicroom(2, 11):
|
||||||
|
case musicroom(7, 9):
|
||||||
|
case musicroom(8, 11):
|
||||||
|
case musicroom(13, 2):
|
||||||
|
case musicroom(17, 12):
|
||||||
|
case musicroom(14, 19):
|
||||||
|
case musicroom(17, 17):
|
||||||
|
niceplay(4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
niceplay(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::initefchannels()
|
||||||
|
{
|
||||||
|
// for (var i:int = 0; i < 16; i++) efchannel.push(new SoundChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void musicclass::playef(int t, int offset)
|
||||||
|
{
|
||||||
|
// efchannel[currentefchan] = efchan[t].play(offset);
|
||||||
|
// currentefchan++;
|
||||||
|
// if (currentefchan > 15) currentefchan -= 16;
|
||||||
|
int channel;
|
||||||
|
|
||||||
|
channel = Mix_PlayChannel(-1, soundTracks[t].sound, 0);
|
||||||
|
if(channel == -1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to play WAV file: %s\n", Mix_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
65
desktop_version/src/Music.h
Normal file
65
desktop_version/src/Music.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#ifndef MUSIC_H
|
||||||
|
#define MUSIC_H
|
||||||
|
|
||||||
|
#include "SoundSystem.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define musicroom(rx, ry) ((rx) + ((ry) * 20))
|
||||||
|
|
||||||
|
class musicclass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
musicclass();
|
||||||
|
|
||||||
|
void play(int t);
|
||||||
|
void loopmusic();
|
||||||
|
void stopmusic();
|
||||||
|
void haltdasmusik();
|
||||||
|
void silencedasmusik();
|
||||||
|
void fadeMusicVolumeIn(int ms);
|
||||||
|
void fadeout();
|
||||||
|
void processmusicfade();
|
||||||
|
void processmusicfadein();
|
||||||
|
void processmusic();
|
||||||
|
void niceplay(int t);
|
||||||
|
|
||||||
|
void changemusicarea(int x, int y);
|
||||||
|
|
||||||
|
// public var musicchan:Array = new Array();
|
||||||
|
// public var musicchannel:SoundChannel, musicchannel2:SoundChannel;
|
||||||
|
// public var currentmusicchan:int, musicchanlen:int, musicchancur:int, musicstopother:int, resumesong:int;
|
||||||
|
// public var currentsong:int, musicfade:int, musicfadein:int;
|
||||||
|
int currentsong, musicfade, musicfadein;
|
||||||
|
int resumesong;
|
||||||
|
|
||||||
|
//public var nicefade:int, nicechange:int;
|
||||||
|
|
||||||
|
// Play a sound effect! There are 16 channels, which iterate
|
||||||
|
void initefchannels();
|
||||||
|
|
||||||
|
void playef(int t, int offset = 0);
|
||||||
|
|
||||||
|
std::vector<SoundTrack> soundTracks;
|
||||||
|
std::vector<MusicTrack> musicTracks;
|
||||||
|
SoundSystem soundSystem;
|
||||||
|
bool safeToProcessMusic;
|
||||||
|
|
||||||
|
int nicechange;
|
||||||
|
int nicefade;
|
||||||
|
|
||||||
|
bool m_doFadeInVol;
|
||||||
|
int FadeVolAmountPerFrame;
|
||||||
|
int musicVolume;
|
||||||
|
|
||||||
|
float volume;
|
||||||
|
|
||||||
|
bool custompd;
|
||||||
|
|
||||||
|
// MMMMMM mod settings
|
||||||
|
bool mmmmmm;
|
||||||
|
bool usingmmmmmm;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* MUSIC_H */
|
||||||
28
desktop_version/src/Network.h
Normal file
28
desktop_version/src/Network.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef VNETWORK_H
|
||||||
|
#define VNETWORK_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int NETWORK_init();
|
||||||
|
|
||||||
|
void NETWORK_shutdown();
|
||||||
|
|
||||||
|
void NETWORK_update();
|
||||||
|
|
||||||
|
void NETWORK_unlockAchievement(const char *name);
|
||||||
|
|
||||||
|
int32_t NETWORK_getAchievementProgress(const char *name);
|
||||||
|
|
||||||
|
void NETWORK_setAchievementProgress(const char *name, int32_t stat);
|
||||||
|
|
||||||
|
/* TODO: Steam Workshop? */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* VNETWORK_H */
|
||||||
8099
desktop_version/src/Otherlevel.cpp
Normal file
8099
desktop_version/src/Otherlevel.cpp
Normal file
File diff suppressed because it is too large
Load Diff
38
desktop_version/src/Otherlevel.h
Normal file
38
desktop_version/src/Otherlevel.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef OTHERLEVEL_H
|
||||||
|
#define OTHERLEVEL_H
|
||||||
|
|
||||||
|
#include "Game.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class otherlevelclass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BLOCK = 0,
|
||||||
|
TRIGGER,
|
||||||
|
DAMAGE,
|
||||||
|
DIRECTIONAL,
|
||||||
|
SAFE,
|
||||||
|
ACTIVITY
|
||||||
|
};
|
||||||
|
|
||||||
|
otherlevelclass();
|
||||||
|
void addline(std::string t);
|
||||||
|
std::vector<std::string> loadlevel(int rx, int ry , Game& game, entityclass& obj);
|
||||||
|
|
||||||
|
std::string roomname;
|
||||||
|
|
||||||
|
int roomtileset;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// roomtext thing in other level
|
||||||
|
bool roomtexton;
|
||||||
|
int roomtextx, roomtexty, roomtextnumlines;
|
||||||
|
std::vector<std::string> roomtext;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* OTHERLEVEL_H */
|
||||||
212
desktop_version/src/Screen.cpp
Normal file
212
desktop_version/src/Screen.cpp
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
#include "Screen.h"
|
||||||
|
|
||||||
|
#include "FileSystemUtils.h"
|
||||||
|
#include "GraphicsUtil.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// Used to create the window icon
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
extern unsigned lodepng_decode24(
|
||||||
|
unsigned char** out,
|
||||||
|
unsigned* w,
|
||||||
|
unsigned* h,
|
||||||
|
const unsigned char* in,
|
||||||
|
size_t insize
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Screen::Screen()
|
||||||
|
{
|
||||||
|
m_window = NULL;
|
||||||
|
m_renderer = NULL;
|
||||||
|
m_screenTexture = NULL;
|
||||||
|
m_screen = NULL;
|
||||||
|
isWindowed = true;
|
||||||
|
stretchMode = 0;
|
||||||
|
isFiltered = false;
|
||||||
|
filterSubrect.x = 1;
|
||||||
|
filterSubrect.y = 1;
|
||||||
|
filterSubrect.w = 318;
|
||||||
|
filterSubrect.h = 238;
|
||||||
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
|
||||||
|
|
||||||
|
// Uncomment this next line when you need to debug -flibit
|
||||||
|
// SDL_SetHintWithPriority(SDL_HINT_RENDER_DRIVER, "software", SDL_HINT_OVERRIDE);
|
||||||
|
SDL_CreateWindowAndRenderer(
|
||||||
|
640,
|
||||||
|
480,
|
||||||
|
SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE,
|
||||||
|
&m_window,
|
||||||
|
&m_renderer
|
||||||
|
);
|
||||||
|
SDL_SetWindowTitle(m_window, "VVVVVV");
|
||||||
|
|
||||||
|
unsigned char *fileIn = NULL;
|
||||||
|
size_t length = 0;
|
||||||
|
unsigned char *data;
|
||||||
|
unsigned int width, height;
|
||||||
|
FILESYSTEM_loadFileToMemory("VVVVVV.png", &fileIn, &length);
|
||||||
|
lodepng_decode24(&data, &width, &height, fileIn, length);
|
||||||
|
FILESYSTEM_freeMemory(&fileIn);
|
||||||
|
SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(
|
||||||
|
data,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
24,
|
||||||
|
width * 3,
|
||||||
|
0x000000FF,
|
||||||
|
0x0000FF00,
|
||||||
|
0x00FF0000,
|
||||||
|
0x00000000
|
||||||
|
);
|
||||||
|
SDL_SetWindowIcon(m_window, icon);
|
||||||
|
SDL_FreeSurface(icon);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
// FIXME: This surface should be the actual backbuffer! -flibit
|
||||||
|
m_screen = SDL_CreateRGBSurface(
|
||||||
|
0,
|
||||||
|
320,
|
||||||
|
240,
|
||||||
|
32,
|
||||||
|
0x00FF0000,
|
||||||
|
0x0000FF00,
|
||||||
|
0x000000FF,
|
||||||
|
0xFF000000
|
||||||
|
);
|
||||||
|
m_screenTexture = SDL_CreateTexture(
|
||||||
|
m_renderer,
|
||||||
|
SDL_PIXELFORMAT_ARGB8888,
|
||||||
|
SDL_TEXTUREACCESS_STREAMING,
|
||||||
|
320,
|
||||||
|
240
|
||||||
|
);
|
||||||
|
|
||||||
|
badSignalEffect = false;
|
||||||
|
|
||||||
|
glScreen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::ResizeScreen(int x , int y)
|
||||||
|
{
|
||||||
|
static int resX = 320;
|
||||||
|
static int resY = 240;
|
||||||
|
if (x != -1 && y != -1)
|
||||||
|
{
|
||||||
|
// This is a user resize!
|
||||||
|
resX = x;
|
||||||
|
resY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isWindowed)
|
||||||
|
{
|
||||||
|
SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_SetWindowFullscreen(m_window, 0);
|
||||||
|
if (x != -1 && y != -1)
|
||||||
|
{
|
||||||
|
SDL_SetWindowSize(m_window, resX, resY);
|
||||||
|
SDL_SetWindowPosition(m_window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stretchMode == 1)
|
||||||
|
{
|
||||||
|
int winX, winY;
|
||||||
|
SDL_GetWindowSize(m_window, &winX, &winY);
|
||||||
|
SDL_RenderSetLogicalSize(m_renderer, winX, winY);
|
||||||
|
SDL_RenderSetIntegerScale(m_renderer, SDL_FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_RenderSetLogicalSize(m_renderer, 320, 240);
|
||||||
|
SDL_RenderSetIntegerScale(m_renderer, (SDL_bool) (stretchMode == 2));
|
||||||
|
}
|
||||||
|
SDL_ShowWindow(m_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::GetWindowSize(int* x, int* y)
|
||||||
|
{
|
||||||
|
SDL_GetWindowSize(m_window, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::UpdateScreen(SDL_Surface* buffer, SDL_Rect* rect )
|
||||||
|
{
|
||||||
|
if((buffer == NULL) && (m_screen == NULL) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(badSignalEffect)
|
||||||
|
{
|
||||||
|
buffer = ApplyFilter(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FillRect(m_screen, 0x000);
|
||||||
|
BlitSurfaceStandard(buffer,NULL,m_screen,rect);
|
||||||
|
|
||||||
|
if(badSignalEffect)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const SDL_PixelFormat* Screen::GetFormat()
|
||||||
|
{
|
||||||
|
return m_screen->format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::FlipScreen()
|
||||||
|
{
|
||||||
|
SDL_UpdateTexture(
|
||||||
|
m_screenTexture,
|
||||||
|
NULL,
|
||||||
|
m_screen->pixels,
|
||||||
|
m_screen->pitch
|
||||||
|
);
|
||||||
|
SDL_RenderCopy(
|
||||||
|
m_renderer,
|
||||||
|
m_screenTexture,
|
||||||
|
isFiltered ? &filterSubrect : NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
SDL_RenderPresent(m_renderer);
|
||||||
|
SDL_RenderClear(m_renderer);
|
||||||
|
SDL_FillRect(m_screen, NULL, 0x00000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::toggleFullScreen()
|
||||||
|
{
|
||||||
|
isWindowed = !isWindowed;
|
||||||
|
ResizeScreen(-1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::toggleStretchMode()
|
||||||
|
{
|
||||||
|
stretchMode = (stretchMode + 1) % 3;
|
||||||
|
ResizeScreen(-1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::toggleLinearFilter()
|
||||||
|
{
|
||||||
|
isFiltered = !isFiltered;
|
||||||
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, isFiltered ? "linear" : "nearest");
|
||||||
|
SDL_DestroyTexture(m_screenTexture);
|
||||||
|
m_screenTexture = SDL_CreateTexture(
|
||||||
|
m_renderer,
|
||||||
|
SDL_PIXELFORMAT_ARGB8888,
|
||||||
|
SDL_TEXTUREACCESS_STREAMING,
|
||||||
|
320,
|
||||||
|
240
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::ClearScreen( int colour )
|
||||||
|
{
|
||||||
|
//FillRect(m_screen, colour) ;
|
||||||
|
}
|
||||||
40
desktop_version/src/Screen.h
Normal file
40
desktop_version/src/Screen.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef SCREEN_H
|
||||||
|
#define SCREEN_H
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
class Screen
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Screen();
|
||||||
|
|
||||||
|
void ResizeScreen(int x, int y);
|
||||||
|
void GetWindowSize(int* x, int* y);
|
||||||
|
|
||||||
|
void UpdateScreen(SDL_Surface* buffer, SDL_Rect* rect);
|
||||||
|
void ClearScreen(int colour);
|
||||||
|
void FlipScreen();
|
||||||
|
|
||||||
|
const SDL_PixelFormat* GetFormat();
|
||||||
|
|
||||||
|
void toggleFullScreen();
|
||||||
|
void toggleStretchMode();
|
||||||
|
void toggleLinearFilter();
|
||||||
|
|
||||||
|
bool isWindowed;
|
||||||
|
bool isFiltered;
|
||||||
|
bool badSignalEffect;
|
||||||
|
bool glScreen;
|
||||||
|
int stretchMode;
|
||||||
|
|
||||||
|
SDL_Window *m_window;
|
||||||
|
SDL_Renderer *m_renderer;
|
||||||
|
SDL_Texture *m_screenTexture;
|
||||||
|
SDL_Surface* m_screen;
|
||||||
|
|
||||||
|
SDL_Rect filterSubrect;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* SCREEN_H */
|
||||||
3545
desktop_version/src/Script.cpp
Normal file
3545
desktop_version/src/Script.cpp
Normal file
File diff suppressed because it is too large
Load Diff
75
desktop_version/src/Script.h
Normal file
75
desktop_version/src/Script.h
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
#ifndef SCRIPT_H
|
||||||
|
#define SCRIPT_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Enums.h"
|
||||||
|
|
||||||
|
|
||||||
|
class KeyPoll; class Graphics; class Game; class mapclass; class entityclass; class UtilityClass;class musicclass;
|
||||||
|
|
||||||
|
|
||||||
|
class scriptclass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
scriptclass();
|
||||||
|
|
||||||
|
void load(std::string t);
|
||||||
|
void loadother(std::string t);
|
||||||
|
|
||||||
|
|
||||||
|
void inline add(std::string t)
|
||||||
|
{
|
||||||
|
commands[scriptlength] = t;
|
||||||
|
scriptlength++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearcustom();
|
||||||
|
|
||||||
|
void tokenize(std::string t);
|
||||||
|
|
||||||
|
void run(KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map,
|
||||||
|
entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
void resetgametomenu(Graphics& dwgfx, Game& game,mapclass& map,
|
||||||
|
entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
void startgamemode(int t, KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map,
|
||||||
|
entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
void teleport(Graphics& dwgfx, Game& game, mapclass& map,
|
||||||
|
entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
void hardreset(KeyPoll& key, Graphics& dwgfx, Game& game,mapclass& map,
|
||||||
|
entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
//Script contents
|
||||||
|
std::vector<std::string> commands;
|
||||||
|
std::vector<std::string> words;
|
||||||
|
std::vector<std::string> txt;
|
||||||
|
std::string scriptname;
|
||||||
|
int position, scriptlength;
|
||||||
|
int looppoint, loopcount;
|
||||||
|
|
||||||
|
int scriptdelay;
|
||||||
|
bool running;
|
||||||
|
std::string tempword;
|
||||||
|
std::string currentletter;
|
||||||
|
|
||||||
|
//Textbox stuff
|
||||||
|
int textx;
|
||||||
|
int texty;
|
||||||
|
int r,g,b;
|
||||||
|
int txtnumlines;
|
||||||
|
|
||||||
|
//Misc
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
|
//Custom level stuff
|
||||||
|
std::vector <std::string> customscript;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SCRIPT_H */
|
||||||
6580
desktop_version/src/Scripts.cpp
Normal file
6580
desktop_version/src/Scripts.cpp
Normal file
File diff suppressed because it is too large
Load Diff
68
desktop_version/src/SoundSystem.cpp
Normal file
68
desktop_version/src/SoundSystem.cpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#include <SDL.h>
|
||||||
|
#include "SoundSystem.h"
|
||||||
|
#include "FileSystemUtils.h"
|
||||||
|
|
||||||
|
MusicTrack::MusicTrack(const char* fileName)
|
||||||
|
{
|
||||||
|
m_music = Mix_LoadMUS(fileName);
|
||||||
|
m_isValid = true;
|
||||||
|
if(m_music == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to load Ogg Music file: %s\n", Mix_GetError());;
|
||||||
|
m_isValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MusicTrack::MusicTrack(SDL_RWops *rw)
|
||||||
|
{
|
||||||
|
m_music = Mix_LoadMUS_RW(rw, 0);
|
||||||
|
m_isValid = true;
|
||||||
|
if(m_music == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to load Magic Binary Music file: %s\n", Mix_GetError());
|
||||||
|
m_isValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundTrack::SoundTrack(const char* fileName)
|
||||||
|
{
|
||||||
|
sound = NULL;
|
||||||
|
|
||||||
|
unsigned char *mem;
|
||||||
|
size_t length = 0;
|
||||||
|
FILESYSTEM_loadFileToMemory(fileName, &mem, &length);
|
||||||
|
SDL_RWops *fileIn = SDL_RWFromMem(mem, length);
|
||||||
|
sound = Mix_LoadWAV_RW(fileIn, 1);
|
||||||
|
FILESYSTEM_freeMemory(&mem);
|
||||||
|
|
||||||
|
if (sound == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to load WAV file: %s\n", Mix_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundSystem::SoundSystem()
|
||||||
|
{
|
||||||
|
int audio_rate = 44100;
|
||||||
|
Uint16 audio_format = AUDIO_S16SYS;
|
||||||
|
int audio_channels = 2;
|
||||||
|
int audio_buffers = 1024;
|
||||||
|
|
||||||
|
if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to initialize audio: %s\n", Mix_GetError());
|
||||||
|
SDL_assert(0 && "Unable to initialize audio!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundSystem::playMusic(MusicTrack* music)
|
||||||
|
{
|
||||||
|
if(!music->m_isValid)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Invalid mix specified: %s\n", Mix_GetError());
|
||||||
|
}
|
||||||
|
if(Mix_PlayMusic(music->m_music, 0) == -1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to play Ogg file: %s\n", Mix_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
29
desktop_version/src/SoundSystem.h
Normal file
29
desktop_version/src/SoundSystem.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef SOUNDSYSTEM_H
|
||||||
|
#define SOUNDSYSTEM_H
|
||||||
|
|
||||||
|
#include <SDL_mixer.h>
|
||||||
|
|
||||||
|
class MusicTrack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MusicTrack(const char* fileName);
|
||||||
|
MusicTrack(SDL_RWops *rw);
|
||||||
|
Mix_Music *m_music;
|
||||||
|
bool m_isValid;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoundTrack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoundTrack(const char* fileName);
|
||||||
|
Mix_Chunk *sound;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoundSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SoundSystem();
|
||||||
|
void playMusic(MusicTrack* music);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SOUNDSYSTEM_H */
|
||||||
3220
desktop_version/src/Spacestation2.cpp
Normal file
3220
desktop_version/src/Spacestation2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
17
desktop_version/src/Spacestation2.h
Normal file
17
desktop_version/src/Spacestation2.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef SPACESTATION2_H
|
||||||
|
#define SPACESTATION2_H
|
||||||
|
|
||||||
|
#include "Game.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class spacestation2class
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<std::string> loadlevel(int rx, int ry, Game& game, entityclass& obj);
|
||||||
|
std::string roomname;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SPACESTATION2_H */
|
||||||
219
desktop_version/src/SteamNetwork.c
Normal file
219
desktop_version/src/SteamNetwork.c
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
#include "Network.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
/* Steamworks interface versions */
|
||||||
|
|
||||||
|
#define VVVVVV_STEAMCLIENT "SteamClient017"
|
||||||
|
#define VVVVVV_STEAMUSERSTATS "STEAMUSERSTATS_INTERFACE_VERSION011"
|
||||||
|
|
||||||
|
/* Shared object file name */
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#define NETWORK_LIBRARY "steam_api.dll"
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#define NETWORK_LIBRARY "libsteam_api.dylib"
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#define NETWORK_LIBRARY "libsteam_api.so"
|
||||||
|
#else
|
||||||
|
#error NETWORK_LIBRARY: Unrecognized platform!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Function Pointer Types */
|
||||||
|
|
||||||
|
typedef uint8_t (*SteamAPI_InitFunc)();
|
||||||
|
typedef void (*SteamAPI_ShutdownFunc)();
|
||||||
|
typedef void (*SteamAPI_RunCallbacksFunc)();
|
||||||
|
typedef intptr_t (*SteamInternal_CreateInterfaceFunc)(const char*);
|
||||||
|
typedef int32_t (*SteamAPI_GetHSteamUserFunc)();
|
||||||
|
typedef int32_t (*SteamAPI_GetHSteamPipeFunc)();
|
||||||
|
typedef intptr_t (*SteamAPI_ISteamClient_GetISteamUserStatsFunc)(
|
||||||
|
intptr_t,
|
||||||
|
int32_t,
|
||||||
|
int32_t,
|
||||||
|
const char*
|
||||||
|
);
|
||||||
|
typedef uint8_t (*SteamAPI_ISteamUserStats_RequestCurrentStatsFunc)(intptr_t);
|
||||||
|
typedef uint8_t (*SteamAPI_ISteamUserStats_StoreStatsFunc)(intptr_t);
|
||||||
|
typedef uint8_t (*SteamAPI_ISteamUserStats_GetStatFunc)(
|
||||||
|
intptr_t,
|
||||||
|
const char*,
|
||||||
|
int32_t*
|
||||||
|
);
|
||||||
|
typedef uint8_t (*SteamAPI_ISteamUserStats_SetStatFunc)(
|
||||||
|
intptr_t,
|
||||||
|
const char*,
|
||||||
|
int32_t
|
||||||
|
);
|
||||||
|
typedef uint8_t (*SteamAPI_ISteamUserStats_SetAchievementFunc)(
|
||||||
|
intptr_t,
|
||||||
|
const char*
|
||||||
|
);
|
||||||
|
|
||||||
|
/* DLL, Entry Points */
|
||||||
|
|
||||||
|
static void *libHandle = NULL;
|
||||||
|
static intptr_t steamUserStats = (intptr_t) NULL;
|
||||||
|
|
||||||
|
#define DEFINE_FUNC(name) static name##Func name = NULL;
|
||||||
|
DEFINE_FUNC(SteamAPI_Init)
|
||||||
|
DEFINE_FUNC(SteamAPI_Shutdown)
|
||||||
|
DEFINE_FUNC(SteamAPI_RunCallbacks)
|
||||||
|
DEFINE_FUNC(SteamInternal_CreateInterface)
|
||||||
|
DEFINE_FUNC(SteamAPI_GetHSteamUser)
|
||||||
|
DEFINE_FUNC(SteamAPI_GetHSteamPipe)
|
||||||
|
DEFINE_FUNC(SteamAPI_ISteamClient_GetISteamUserStats)
|
||||||
|
DEFINE_FUNC(SteamAPI_ISteamUserStats_RequestCurrentStats)
|
||||||
|
DEFINE_FUNC(SteamAPI_ISteamUserStats_StoreStats)
|
||||||
|
DEFINE_FUNC(SteamAPI_ISteamUserStats_GetStat)
|
||||||
|
DEFINE_FUNC(SteamAPI_ISteamUserStats_SetStat)
|
||||||
|
DEFINE_FUNC(SteamAPI_ISteamUserStats_SetAchievement)
|
||||||
|
#undef DEFINE_FUNC
|
||||||
|
|
||||||
|
/* Clean up after ourselves... */
|
||||||
|
|
||||||
|
static void ClearPointers()
|
||||||
|
{
|
||||||
|
SDL_UnloadObject(libHandle);
|
||||||
|
libHandle = NULL;
|
||||||
|
steamUserStats = (intptr_t) NULL;
|
||||||
|
SteamAPI_Init = NULL;
|
||||||
|
SteamAPI_Shutdown = NULL;
|
||||||
|
SteamAPI_RunCallbacks = NULL;
|
||||||
|
SteamInternal_CreateInterface = NULL;
|
||||||
|
SteamAPI_GetHSteamUser = NULL;
|
||||||
|
SteamAPI_GetHSteamPipe = NULL;
|
||||||
|
SteamAPI_ISteamClient_GetISteamUserStats = NULL;
|
||||||
|
SteamAPI_ISteamUserStats_RequestCurrentStats = NULL;
|
||||||
|
SteamAPI_ISteamUserStats_StoreStats = NULL;
|
||||||
|
SteamAPI_ISteamUserStats_GetStat = NULL;
|
||||||
|
SteamAPI_ISteamUserStats_SetStat = NULL;
|
||||||
|
SteamAPI_ISteamUserStats_SetAchievement = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NETWORK API Implementation */
|
||||||
|
|
||||||
|
int NETWORK_init()
|
||||||
|
{
|
||||||
|
intptr_t steamClient;
|
||||||
|
int32_t steamUser, steamPipe;
|
||||||
|
|
||||||
|
libHandle = SDL_LoadObject(NETWORK_LIBRARY);
|
||||||
|
if (!libHandle)
|
||||||
|
{
|
||||||
|
printf("%s not found!\n", NETWORK_LIBRARY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOAD_FUNC(name) \
|
||||||
|
name = (name##Func) SDL_LoadFunction(libHandle, #name); \
|
||||||
|
if (!name) \
|
||||||
|
{ \
|
||||||
|
printf("%s symbol %s not found!\n", NETWORK_LIBRARY, #name); \
|
||||||
|
ClearPointers(); \
|
||||||
|
return 0; \
|
||||||
|
}
|
||||||
|
LOAD_FUNC(SteamAPI_Init)
|
||||||
|
LOAD_FUNC(SteamAPI_Shutdown)
|
||||||
|
LOAD_FUNC(SteamAPI_RunCallbacks)
|
||||||
|
LOAD_FUNC(SteamInternal_CreateInterface)
|
||||||
|
LOAD_FUNC(SteamAPI_GetHSteamUser)
|
||||||
|
LOAD_FUNC(SteamAPI_GetHSteamPipe)
|
||||||
|
LOAD_FUNC(SteamAPI_ISteamClient_GetISteamUserStats)
|
||||||
|
LOAD_FUNC(SteamAPI_ISteamUserStats_RequestCurrentStats)
|
||||||
|
LOAD_FUNC(SteamAPI_ISteamUserStats_StoreStats)
|
||||||
|
LOAD_FUNC(SteamAPI_ISteamUserStats_GetStat)
|
||||||
|
LOAD_FUNC(SteamAPI_ISteamUserStats_SetStat)
|
||||||
|
LOAD_FUNC(SteamAPI_ISteamUserStats_SetAchievement)
|
||||||
|
#undef LOAD_FUNC
|
||||||
|
|
||||||
|
if (!SteamAPI_Init())
|
||||||
|
{
|
||||||
|
printf("Steamworks not initialized!\n");
|
||||||
|
ClearPointers();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
steamClient = SteamInternal_CreateInterface(VVVVVV_STEAMCLIENT);
|
||||||
|
steamUser = SteamAPI_GetHSteamUser();
|
||||||
|
steamPipe = SteamAPI_GetHSteamPipe();
|
||||||
|
if (!steamClient || !steamUser || !steamPipe)
|
||||||
|
{
|
||||||
|
SteamAPI_Shutdown();
|
||||||
|
printf(VVVVVV_STEAMCLIENT " not created!\n");
|
||||||
|
ClearPointers();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
steamUserStats = SteamAPI_ISteamClient_GetISteamUserStats(
|
||||||
|
steamClient,
|
||||||
|
steamUser,
|
||||||
|
steamPipe,
|
||||||
|
VVVVVV_STEAMUSERSTATS
|
||||||
|
);
|
||||||
|
if (!steamUserStats)
|
||||||
|
{
|
||||||
|
SteamAPI_Shutdown();
|
||||||
|
printf(VVVVVV_STEAMUSERSTATS " not created!\n");
|
||||||
|
ClearPointers();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SteamAPI_ISteamUserStats_RequestCurrentStats(steamUserStats);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NETWORK_shutdown()
|
||||||
|
{
|
||||||
|
if (libHandle)
|
||||||
|
{
|
||||||
|
SteamAPI_Shutdown();
|
||||||
|
ClearPointers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NETWORK_update()
|
||||||
|
{
|
||||||
|
if (libHandle)
|
||||||
|
{
|
||||||
|
SteamAPI_RunCallbacks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NETWORK_unlockAchievement(const char *name)
|
||||||
|
{
|
||||||
|
if (libHandle)
|
||||||
|
{
|
||||||
|
SteamAPI_ISteamUserStats_SetAchievement(
|
||||||
|
steamUserStats,
|
||||||
|
name
|
||||||
|
);
|
||||||
|
SteamAPI_ISteamUserStats_StoreStats(steamUserStats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t NETWORK_getAchievementProgress(const char *name)
|
||||||
|
{
|
||||||
|
int32_t result = -1;
|
||||||
|
if (libHandle)
|
||||||
|
{
|
||||||
|
SteamAPI_ISteamUserStats_GetStat(
|
||||||
|
steamUserStats,
|
||||||
|
name,
|
||||||
|
&result
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NETWORK_setAchievementProgress(const char *name, int32_t stat)
|
||||||
|
{
|
||||||
|
if (libHandle)
|
||||||
|
{
|
||||||
|
SteamAPI_ISteamUserStats_SetStat(
|
||||||
|
steamUserStats,
|
||||||
|
name,
|
||||||
|
stat
|
||||||
|
);
|
||||||
|
SteamAPI_ISteamUserStats_StoreStats(steamUserStats);
|
||||||
|
}
|
||||||
|
}
|
||||||
903
desktop_version/src/TerminalScripts.cpp
Normal file
903
desktop_version/src/TerminalScripts.cpp
Normal file
@@ -0,0 +1,903 @@
|
|||||||
|
#ifndef TERMINALSCRIPTS_H
|
||||||
|
#define TERMINALSCRIPTS_H
|
||||||
|
|
||||||
|
#include "Script.h"
|
||||||
|
|
||||||
|
void scriptclass::loadother(std::string t)
|
||||||
|
{
|
||||||
|
//loads script name t into the array
|
||||||
|
if (t == "terminal_station_1")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,60,1)");
|
||||||
|
add(" -= PERSONAL LOG =- ");
|
||||||
|
add("position(centerx)");
|
||||||
|
add("backgroundtext");
|
||||||
|
add("flipme");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("text(gray,0,120,6)");
|
||||||
|
add(" Almost everyone has been ");
|
||||||
|
add(" evacuated from the space ");
|
||||||
|
add(" station now. The rest of us ");
|
||||||
|
add(" are leaving in a couple of ");
|
||||||
|
add(" days, once our research has ");
|
||||||
|
add(" been completed. ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "alreadyvisited")
|
||||||
|
{
|
||||||
|
add("squeak(player)");
|
||||||
|
add("text(cyan,0,0,1)");
|
||||||
|
add("...oh, I've already found this.");
|
||||||
|
add("position(player,above)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_outside_1")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,60,1)");
|
||||||
|
add(" -= Research Notes =- ");
|
||||||
|
add("position(centerx)");
|
||||||
|
add("backgroundtext");
|
||||||
|
add("flipme");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("text(gray,0,114,5)");
|
||||||
|
add(" ... our first breakthrough was ");
|
||||||
|
add(" the creation of the inversion ");
|
||||||
|
add(" plane, which creates a ");
|
||||||
|
add(" mirrored dimension beyond a ");
|
||||||
|
add(" given event horizon ... ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("endtextfast");
|
||||||
|
add("delay(10)");
|
||||||
|
|
||||||
|
add("ifexplored(2,16,alreadyvisited)");
|
||||||
|
|
||||||
|
add("gamemode(teleporter)");
|
||||||
|
add("delay(20)");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("showcoordinates(2,16)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("hidecoordinates(2,16)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("showcoordinates(2,16)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("hidecoordinates(2,16)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("showcoordinates(2,16)");
|
||||||
|
add("delay(45)");
|
||||||
|
|
||||||
|
add("gamemode(game)");
|
||||||
|
add("delay(20)");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_outside_2")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,60,1)");
|
||||||
|
add(" -= Research Notes =- ");
|
||||||
|
add("position(centerx)");
|
||||||
|
add("backgroundtext");
|
||||||
|
add("flipme");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("text(gray,0,114,3)");
|
||||||
|
add("...with just a small modification to");
|
||||||
|
add("the usual parameters, we were able ");
|
||||||
|
add("to stabilise an infinite tunnel! ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("endtextfast");
|
||||||
|
add("delay(10)");
|
||||||
|
|
||||||
|
add("ifexplored(8,9,alreadyvisited)");
|
||||||
|
|
||||||
|
add("gamemode(teleporter)");
|
||||||
|
add("delay(20)");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("showcoordinates(8,9)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("hidecoordinates(8,9)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("showcoordinates(8,9)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("hidecoordinates(8,9)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("showcoordinates(8,9)");
|
||||||
|
add("delay(45)");
|
||||||
|
|
||||||
|
add("gamemode(game)");
|
||||||
|
add("delay(20)");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_outside_3")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,60,1)");
|
||||||
|
add(" -= Research Notes =- ");
|
||||||
|
add("position(centerx)");
|
||||||
|
add("backgroundtext");
|
||||||
|
add("flipme");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("text(gray,0,114,3)");
|
||||||
|
add(" ... the final step in creating ");
|
||||||
|
add(" the dimensional stabiliser was ");
|
||||||
|
add(" to create a feedback loop ... ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("endtextfast");
|
||||||
|
add("delay(10)");
|
||||||
|
|
||||||
|
add("ifexplored(14,1,alreadyvisited)");
|
||||||
|
|
||||||
|
add("gamemode(teleporter)");
|
||||||
|
add("delay(20)");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("showcoordinates(14,1)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("hidecoordinates(14,1)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("showcoordinates(14,1)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("hidecoordinates(14,1)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("showcoordinates(14,1)");
|
||||||
|
add("delay(45)");
|
||||||
|
|
||||||
|
add("gamemode(game)");
|
||||||
|
add("delay(20)");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_outside_4")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,60,1)");
|
||||||
|
add(" -= Research Notes =- ");
|
||||||
|
add("position(centerx)");
|
||||||
|
add("backgroundtext");
|
||||||
|
add("flipme");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add(" ...despite our best efforts, ");
|
||||||
|
add(" the dimensional stabiliser ");
|
||||||
|
add(" won't hold out forever. Its ");
|
||||||
|
add(" collapse is inevitable... ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("endtextfast");
|
||||||
|
add("delay(10)");
|
||||||
|
|
||||||
|
add("squeak(player)");
|
||||||
|
add("text(cyan,0,0,2)");
|
||||||
|
add("Huh? These coordinates aren't");
|
||||||
|
add("even in this dimension!");
|
||||||
|
add("position(player,above)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_outside_5")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,60,1)");
|
||||||
|
add(" -= Personal Log =- ");
|
||||||
|
add("position(centerx)");
|
||||||
|
add("backgroundtext");
|
||||||
|
add("flipme");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("text(gray,0,114,5)");
|
||||||
|
add(" ... I've had to seal off ");
|
||||||
|
add(" access to most of our ");
|
||||||
|
add(" research. Who knows what ");
|
||||||
|
add(" could happen if it fell ");
|
||||||
|
add(" into the wrong hands? ... ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("endtextfast");
|
||||||
|
add("delay(10)");
|
||||||
|
|
||||||
|
add("gamemode(teleporter)");
|
||||||
|
add("delay(20)");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("showsecretlab()");
|
||||||
|
add("delay(10)");
|
||||||
|
add("hidesecretlab()");
|
||||||
|
add("delay(10)");
|
||||||
|
add("showsecretlab()");
|
||||||
|
add("delay(10)");
|
||||||
|
add("hidesecretlab()");
|
||||||
|
add("delay(10)");
|
||||||
|
add("showsecretlab()");
|
||||||
|
add("delay(45)");
|
||||||
|
|
||||||
|
add("gamemode(game)");
|
||||||
|
add("delay(20)");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_outside_6")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,60,1)");
|
||||||
|
add(" -= Research Notes =- ");
|
||||||
|
add("position(centerx)");
|
||||||
|
add("backgroundtext");
|
||||||
|
add("flipme");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("text(gray,0,114,3)");
|
||||||
|
add("... access to the control center");
|
||||||
|
add("is still possible through the ");
|
||||||
|
add("main atmospheric filters ... ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("endtextfast");
|
||||||
|
add("delay(10)");
|
||||||
|
|
||||||
|
add("ifexplored(12,14,alreadyvisited)");
|
||||||
|
|
||||||
|
add("gamemode(teleporter)");
|
||||||
|
add("delay(20)");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("showcoordinates(12,14)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("hidecoordinates(12,14)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("showcoordinates(12,14)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("hidecoordinates(12,14)");
|
||||||
|
add("delay(10)");
|
||||||
|
add("showcoordinates(12,14)");
|
||||||
|
add("delay(45)");
|
||||||
|
|
||||||
|
add("gamemode(game)");
|
||||||
|
add("delay(20)");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_finallevel")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,9)");
|
||||||
|
add("* DIMENSIONAL STABILITY GENERATOR *");
|
||||||
|
add("");
|
||||||
|
add(" [ Currently Generating ] ");
|
||||||
|
add(" Maximum Stability ");
|
||||||
|
add("");
|
||||||
|
add(" [ Status ]");
|
||||||
|
add(" Online");
|
||||||
|
add("");
|
||||||
|
add("READY _");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("endtextfast");
|
||||||
|
add("delay(10)");
|
||||||
|
|
||||||
|
add("squeak(player)");
|
||||||
|
add("text(cyan,0,0,2)");
|
||||||
|
add("Aha! This must be what's" );
|
||||||
|
add("causing the interference!");
|
||||||
|
add("position(player,above)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(player)");
|
||||||
|
add("text(cyan,0,0,1)");
|
||||||
|
add("I wonder if I can turn it off?");
|
||||||
|
add("position(player,above)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add("WARNING: Disabling the Dimensional");
|
||||||
|
add("Stability Generator may lead to");
|
||||||
|
add("instability! Are you sure you want");
|
||||||
|
add("to do this?");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(player)");
|
||||||
|
add("text(cyan,0,0,1)");
|
||||||
|
add("Yes!");
|
||||||
|
add("position(player,above)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,6)");
|
||||||
|
add("Seriously! The whole dimension");
|
||||||
|
add("could collapse! Just think about");
|
||||||
|
add("this for a minute!");
|
||||||
|
add("");
|
||||||
|
add("Are you really sure you want");
|
||||||
|
add("to do this?");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(player)");
|
||||||
|
add("text(cyan,0,0,1)");
|
||||||
|
add("Yes!");
|
||||||
|
add("position(player,above)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("stopmusic");
|
||||||
|
add("gamestate(200)");
|
||||||
|
}
|
||||||
|
else if (t == "finalterminal_finish")
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
//add("delay(15)"); add("flash(5)"); add("shake(20)"); add("playef(9,10)");
|
||||||
|
|
||||||
|
add("text(gray,0,114,3)");
|
||||||
|
add(" -= WARNING =- ");
|
||||||
|
add("");
|
||||||
|
add(" DIMENSIONAL STABILISER OFFLINE ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("squeak(cry)");
|
||||||
|
add("changemood(player,1)");
|
||||||
|
add("text(cyan,0,0,1)");
|
||||||
|
add("Uh oh...");
|
||||||
|
add("position(player,above)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("play(2)");
|
||||||
|
add("changemood(player,0)");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_station_2")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,60,1)");
|
||||||
|
add(" -= Research Notes =- ");
|
||||||
|
add("position(centerx)");
|
||||||
|
add("backgroundtext");
|
||||||
|
add("flipme");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("text(gray,0,114,3)");
|
||||||
|
add(" ...everything collapses, ");
|
||||||
|
add(" eventually. It's the way ");
|
||||||
|
add(" of the universe. ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("endtextfast");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_station_3")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,3)");
|
||||||
|
add("I wonder if the generator we set");
|
||||||
|
add("up in the polar dimension is");
|
||||||
|
add("what's affecting our teleporters?");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,1)");
|
||||||
|
add("No, it's probably just a glitch.");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_station_4")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,60,1)");
|
||||||
|
add(" -= PERSONAL LOG =- ");
|
||||||
|
add("position(centerx)");
|
||||||
|
add("backgroundtext");
|
||||||
|
add("flipme");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("text(gray,0,114,2)");
|
||||||
|
add(" Hah! Nobody will ever ");
|
||||||
|
add(" get this one. ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak");
|
||||||
|
|
||||||
|
add("endtextfast");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_warp_1")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,3)");
|
||||||
|
add("...The other day I was chased");
|
||||||
|
add("down a hallway by a giant cube");
|
||||||
|
add("with the word AVOID on it.");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,1)");
|
||||||
|
add("These security measures go too far!");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_warp_2")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,2)");
|
||||||
|
add("The only way into my private lab");
|
||||||
|
add("anymore is by teleporter.");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,3)");
|
||||||
|
add("I've made sure that it's");
|
||||||
|
add("difficult for unauthorised");
|
||||||
|
add("personnel to gain access.");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_lab_1")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add("... it turns out the key to");
|
||||||
|
add("stabilising this dimension was");
|
||||||
|
add("to create a balancing force");
|
||||||
|
add("outside of it!");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,2)");
|
||||||
|
add("Though it looks like that's just");
|
||||||
|
add("a temporary solution, at best.");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add("I've been working on");
|
||||||
|
add("something more permanent,");
|
||||||
|
add("but it seems it's going");
|
||||||
|
add("to be too late...");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_lab_2")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,1)");
|
||||||
|
add("?SYNTAX ERROR");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_secretlab")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add(" -= WARNING =-");
|
||||||
|
add("");
|
||||||
|
add(" The Super-Gravitron is intended ");
|
||||||
|
add(" for entertainment purposes only. ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add("Anyone found using the Super");
|
||||||
|
add("Gravitron for educational");
|
||||||
|
add("purposes may be asked to");
|
||||||
|
add("stand in the naughty corner.");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_shipcomputer")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,3)");
|
||||||
|
add(" -= D.S.S. SOULEYE =- ");
|
||||||
|
add("");
|
||||||
|
add(" Ship Navigation Controls ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("ifflag(67,terminal_letsgo)");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,3)");
|
||||||
|
add("Error! Error! Cannot isolate");
|
||||||
|
add("dimensional coordinates!");
|
||||||
|
add("Interference detected!");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_letsgo")
|
||||||
|
{
|
||||||
|
add("squeak(player)");
|
||||||
|
add("text(player,0,0,2)");
|
||||||
|
add("Now that the ship is fixed,");
|
||||||
|
add("we can leave anytime we want!");
|
||||||
|
add("position(player,above)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(player)");
|
||||||
|
add("text(player,0,0,3)");
|
||||||
|
add("We've all agreed to");
|
||||||
|
add("keep exploring this");
|
||||||
|
add("dimension, though.");
|
||||||
|
add("position(player,above)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("squeak(player)");
|
||||||
|
add("text(player,0,0,1)");
|
||||||
|
add("Who knows what we'll find?");
|
||||||
|
add("position(player,above)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_radio")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add(" -= SHIP RADIO =- ");
|
||||||
|
add("");
|
||||||
|
add(" [ Status ]");
|
||||||
|
add(" Broadcasting");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_jukebox")
|
||||||
|
{
|
||||||
|
add("cutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,7)");
|
||||||
|
add(" -= JUKEBOX =- ");
|
||||||
|
add("");
|
||||||
|
add(" Songs will continue to play ");
|
||||||
|
add(" until you leave the ship.");
|
||||||
|
add("");
|
||||||
|
add(" Collect trinkets to");
|
||||||
|
add(" unlock new songs!");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("iftrinketsless(5,terminal_jukeunlock1)");
|
||||||
|
add("iftrinketsless(8,terminal_jukeunlock2)");
|
||||||
|
add("iftrinketsless(10,terminal_jukeunlock3)");
|
||||||
|
add("iftrinketsless(12,terminal_jukeunlock4)");
|
||||||
|
add("iftrinketsless(14,terminal_jukeunlock41)");
|
||||||
|
add("iftrinketsless(16,terminal_jukeunlock5)");
|
||||||
|
add("iftrinketsless(18,terminal_jukeunlock6)");
|
||||||
|
add("iftrinketsless(20,terminal_jukeunlock7)");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_jukeunlock1")
|
||||||
|
{
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add(" NEXT UNLOCK: ");
|
||||||
|
add(" 5 Trinkets");
|
||||||
|
add("");
|
||||||
|
add(" Pushing onwards ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_jukeunlock2")
|
||||||
|
{
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add(" NEXT UNLOCK: ");
|
||||||
|
add(" 8 Trinkets");
|
||||||
|
add("");
|
||||||
|
add(" Positive force ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_jukeunlock3")
|
||||||
|
{
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add(" NEXT UNLOCK: ");
|
||||||
|
add(" 10 Trinkets");
|
||||||
|
add("");
|
||||||
|
add(" Presenting VVVVVV ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_jukeunlock4")
|
||||||
|
{
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add(" NEXT UNLOCK: ");
|
||||||
|
add(" 12 Trinkets");
|
||||||
|
add("");
|
||||||
|
add(" Potential for anything ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_jukeunlock41")
|
||||||
|
{
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add(" NEXT UNLOCK: ");
|
||||||
|
add(" 14 Trinkets");
|
||||||
|
add("");
|
||||||
|
add(" Pressure Cooker ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_jukeunlock5")
|
||||||
|
{
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add(" NEXT UNLOCK: ");
|
||||||
|
add(" 16 Trinkets");
|
||||||
|
add("");
|
||||||
|
add(" Predestined fate ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_jukeunlock6")
|
||||||
|
{
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add(" NEXT UNLOCK: ");
|
||||||
|
add(" 18 Trinkets");
|
||||||
|
add("");
|
||||||
|
add(" Popular Potpourri ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_jukeunlock7")
|
||||||
|
{
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("text(gray,0,114,4)");
|
||||||
|
add(" NEXT UNLOCK: ");
|
||||||
|
add(" 20 Trinkets");
|
||||||
|
add("");
|
||||||
|
add(" Pipe Dream ");
|
||||||
|
add("position(center)");
|
||||||
|
add("speak_active");
|
||||||
|
add("endtext");
|
||||||
|
|
||||||
|
add("endcutscene()");
|
||||||
|
add("untilbars()");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_juke1")
|
||||||
|
{
|
||||||
|
add("play(4)");
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("jukebox(1)");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_juke2")
|
||||||
|
{
|
||||||
|
add("play(1)");
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("jukebox(2)");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_juke3")
|
||||||
|
{
|
||||||
|
add("play(2)");
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("jukebox(3)");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_juke4")
|
||||||
|
{
|
||||||
|
add("play(6)");
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("jukebox(4)");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_juke5")
|
||||||
|
{
|
||||||
|
add("play(3)");
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("jukebox(5)");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_juke6")
|
||||||
|
{
|
||||||
|
add("play(8)");
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("jukebox(6)");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_juke7")
|
||||||
|
{
|
||||||
|
add("play(11)");
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("jukebox(7)");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_juke8")
|
||||||
|
{
|
||||||
|
add("play(10)");
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("jukebox(8)");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_juke9")
|
||||||
|
{
|
||||||
|
add("play(12)");
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("jukebox(9)");
|
||||||
|
}
|
||||||
|
else if (t == "terminal_juke10")
|
||||||
|
{
|
||||||
|
add("play(9)");
|
||||||
|
add("squeak(terminal)");
|
||||||
|
add("jukebox(10)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TERMINALSCRIPTS_H */
|
||||||
154
desktop_version/src/Textbox.cpp
Normal file
154
desktop_version/src/Textbox.cpp
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
#include "Textbox.h"
|
||||||
|
|
||||||
|
textboxclass::textboxclass()
|
||||||
|
{
|
||||||
|
firstcreate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void textboxclass::firstcreate()
|
||||||
|
{
|
||||||
|
//Like clear, only it creates the actual arrays, etc
|
||||||
|
for (int iter = 0; iter < 10; iter++)
|
||||||
|
{
|
||||||
|
std::string t;
|
||||||
|
t = "";
|
||||||
|
line.push_back(t);
|
||||||
|
}
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
w = 0;
|
||||||
|
h = 0;
|
||||||
|
numlines = 0;
|
||||||
|
lw = 0;
|
||||||
|
tl = 0;
|
||||||
|
tm = 0;
|
||||||
|
active = false;
|
||||||
|
timer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void textboxclass::clear()
|
||||||
|
{
|
||||||
|
//Set all values to a default, required for creating a new entity
|
||||||
|
for (size_t iter = 0; iter < line.size(); iter++)
|
||||||
|
{
|
||||||
|
line[iter]="";
|
||||||
|
}
|
||||||
|
xp = 0;
|
||||||
|
yp = 0;
|
||||||
|
w = 0;
|
||||||
|
h = 0;
|
||||||
|
numlines = 1;
|
||||||
|
lw = 0;
|
||||||
|
tl = 0;
|
||||||
|
tm = 0;
|
||||||
|
active = true;
|
||||||
|
timer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void textboxclass::centerx()
|
||||||
|
{
|
||||||
|
resize();
|
||||||
|
xp = 160 - (w / 2);
|
||||||
|
resize();
|
||||||
|
}
|
||||||
|
void textboxclass::centery()
|
||||||
|
{
|
||||||
|
resize();
|
||||||
|
yp = 120 - (h / 2);
|
||||||
|
resize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void textboxclass::adjust()
|
||||||
|
{
|
||||||
|
resize();
|
||||||
|
if (xp < 10) xp = 10;
|
||||||
|
if (yp < 10) yp = 10;
|
||||||
|
if (xp + w > 310) xp = 310 - w;
|
||||||
|
if (yp + h > 230) yp = 230 - h;
|
||||||
|
resize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void textboxclass::initcol(int rr, int gg, int bb)
|
||||||
|
{
|
||||||
|
tr = rr;
|
||||||
|
tg = gg;
|
||||||
|
tb = bb;
|
||||||
|
r = 0;
|
||||||
|
g = 0;
|
||||||
|
b = 0;
|
||||||
|
tl = 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void textboxclass::setcol(int rr, int gg, int bb)
|
||||||
|
{
|
||||||
|
r = rr;
|
||||||
|
g = gg;
|
||||||
|
b = bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void textboxclass::update()
|
||||||
|
{
|
||||||
|
if (tm == 0)
|
||||||
|
{
|
||||||
|
tl += .1f;
|
||||||
|
if (tl >= 1)
|
||||||
|
{
|
||||||
|
tl = 1;
|
||||||
|
tm = 1;
|
||||||
|
}
|
||||||
|
setcol(int(tr * tl), int(tg * tl), int(tb * tl));
|
||||||
|
}
|
||||||
|
else if (tm == 2)
|
||||||
|
{
|
||||||
|
tl -= .1f;
|
||||||
|
if (tl <= 0.5)
|
||||||
|
{
|
||||||
|
tl = 0.5;
|
||||||
|
active = false;
|
||||||
|
}
|
||||||
|
setcol(int(tr * tl), int(tg * tl), int(tb * tl));
|
||||||
|
}
|
||||||
|
if (timer > 0)
|
||||||
|
{
|
||||||
|
timer--;
|
||||||
|
if (timer == 0) tm = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void textboxclass::remove()
|
||||||
|
{
|
||||||
|
tm = 2;
|
||||||
|
tl = 1.0f; //Remove mode
|
||||||
|
}
|
||||||
|
|
||||||
|
void textboxclass::removefast()
|
||||||
|
{
|
||||||
|
tm = 2;
|
||||||
|
tl = 0.4f; //Remove mode
|
||||||
|
}
|
||||||
|
|
||||||
|
void textboxclass::resize()
|
||||||
|
{
|
||||||
|
//Set the width and height to the correct sizes
|
||||||
|
max = 0;
|
||||||
|
for (int iter = 0; iter < numlines; iter++)
|
||||||
|
{
|
||||||
|
if (line[iter].length() > (unsigned int)max) max = line[iter].length();
|
||||||
|
}
|
||||||
|
|
||||||
|
lw = max;
|
||||||
|
w = (max +2) * 8;
|
||||||
|
h = (numlines + 2) * 8;
|
||||||
|
textrect.x = xp;
|
||||||
|
textrect.y = yp;
|
||||||
|
textrect.w = w;
|
||||||
|
textrect.h = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
void textboxclass::addline(std::string t)
|
||||||
|
{
|
||||||
|
line[numlines] = t;
|
||||||
|
numlines++;
|
||||||
|
resize();
|
||||||
|
if (numlines >= 12) numlines = 0;
|
||||||
|
}
|
||||||
54
desktop_version/src/Textbox.h
Normal file
54
desktop_version/src/Textbox.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#ifndef TEXTBOX_H
|
||||||
|
#define TEXTBOX_H
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class textboxclass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
textboxclass();
|
||||||
|
|
||||||
|
void firstcreate();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
void centerx();
|
||||||
|
|
||||||
|
void centery();
|
||||||
|
|
||||||
|
void adjust();
|
||||||
|
|
||||||
|
void initcol(int rr, int gg, int bb);
|
||||||
|
|
||||||
|
void setcol(int rr, int gg, int bb);
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
void remove();
|
||||||
|
|
||||||
|
void removefast();
|
||||||
|
|
||||||
|
void resize();
|
||||||
|
|
||||||
|
void addline(std::string t);
|
||||||
|
public:
|
||||||
|
//Fundamentals
|
||||||
|
std::vector<std::string> line;
|
||||||
|
int xp, yp, lw, w, h, numlines;
|
||||||
|
int x,y;
|
||||||
|
int r,g,b;
|
||||||
|
int tr,tg,tb;
|
||||||
|
SDL_Rect textrect;
|
||||||
|
bool active;
|
||||||
|
int timer;
|
||||||
|
|
||||||
|
float tl;
|
||||||
|
int tm;
|
||||||
|
|
||||||
|
int max;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* TEXTBOX_H */
|
||||||
1192
desktop_version/src/Tower.cpp
Normal file
1192
desktop_version/src/Tower.cpp
Normal file
File diff suppressed because it is too large
Load Diff
51
desktop_version/src/Tower.h
Normal file
51
desktop_version/src/Tower.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#ifndef TOWER_H
|
||||||
|
#define TOWER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class towerclass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
towerclass();
|
||||||
|
|
||||||
|
int backat(int xp, int yp, int yoff);
|
||||||
|
|
||||||
|
int at(int xp, int yp, int yoff);
|
||||||
|
|
||||||
|
int miniat(int xp, int yp, int yoff);
|
||||||
|
|
||||||
|
void fillbackground(std::vector<std::string>& tmap);
|
||||||
|
|
||||||
|
void fillminitower(std::vector<std::string>& tmap);
|
||||||
|
|
||||||
|
void loadminitower1();
|
||||||
|
|
||||||
|
void loadminitower2();
|
||||||
|
|
||||||
|
void loadbackground();
|
||||||
|
|
||||||
|
void fillcontents(std::vector<std::string>& tmap);
|
||||||
|
|
||||||
|
void loadmap();
|
||||||
|
|
||||||
|
//public var back:Array = new Array();
|
||||||
|
//public var contents:Array = new Array();
|
||||||
|
//public var minitower:Array = new Array();
|
||||||
|
//public var vmult:Array = new Array();
|
||||||
|
|
||||||
|
std::vector<int> back;
|
||||||
|
std::vector<int> contents;
|
||||||
|
std::vector<int> minitower;
|
||||||
|
std::vector<int> vmult;
|
||||||
|
|
||||||
|
bool minitowermode;
|
||||||
|
int i;
|
||||||
|
int k;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* TOWER_H */
|
||||||
360
desktop_version/src/UtilityClass.cpp
Normal file
360
desktop_version/src/UtilityClass.cpp
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
#include "UtilityClass.h"
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
/* Used by UtilityClass::GCString to generate a button list */
|
||||||
|
const char *GCChar(SDL_GameControllerButton button)
|
||||||
|
{
|
||||||
|
if (button == SDL_CONTROLLER_BUTTON_A)
|
||||||
|
{
|
||||||
|
return "A";
|
||||||
|
}
|
||||||
|
else if (button == SDL_CONTROLLER_BUTTON_B)
|
||||||
|
{
|
||||||
|
return "B";
|
||||||
|
}
|
||||||
|
else if (button == SDL_CONTROLLER_BUTTON_X)
|
||||||
|
{
|
||||||
|
return "X";
|
||||||
|
}
|
||||||
|
else if (button == SDL_CONTROLLER_BUTTON_Y)
|
||||||
|
{
|
||||||
|
return "Y";
|
||||||
|
}
|
||||||
|
else if (button == SDL_CONTROLLER_BUTTON_BACK)
|
||||||
|
{
|
||||||
|
return "BACK";
|
||||||
|
}
|
||||||
|
else if (button == SDL_CONTROLLER_BUTTON_GUIDE)
|
||||||
|
{
|
||||||
|
return "GUIDE";
|
||||||
|
}
|
||||||
|
else if (button == SDL_CONTROLLER_BUTTON_START)
|
||||||
|
{
|
||||||
|
return "START";
|
||||||
|
}
|
||||||
|
else if (button == SDL_CONTROLLER_BUTTON_LEFTSTICK)
|
||||||
|
{
|
||||||
|
return "L3";
|
||||||
|
}
|
||||||
|
else if (button == SDL_CONTROLLER_BUTTON_RIGHTSTICK)
|
||||||
|
{
|
||||||
|
return "R3";
|
||||||
|
}
|
||||||
|
else if (button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER)
|
||||||
|
{
|
||||||
|
return "LB";
|
||||||
|
}
|
||||||
|
else if (button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)
|
||||||
|
{
|
||||||
|
return "RB";
|
||||||
|
}
|
||||||
|
SDL_assert(0 && "Unhandled button!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ss_toi( std::string _s )
|
||||||
|
{
|
||||||
|
std::istringstream i(_s);
|
||||||
|
int x;
|
||||||
|
i >> x;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> split( const std::string &s, char delim, std::vector<std::string> &elems )
|
||||||
|
{
|
||||||
|
std::stringstream ss(s);
|
||||||
|
std::string item;
|
||||||
|
while(std::getline(ss, item, delim))
|
||||||
|
{
|
||||||
|
elems.push_back(item);
|
||||||
|
}
|
||||||
|
return elems;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> split( const std::string &s, char delim )
|
||||||
|
{
|
||||||
|
std::vector<std::string> elems;
|
||||||
|
return split(s, delim, elems);
|
||||||
|
}
|
||||||
|
|
||||||
|
UtilityClass::UtilityClass() :
|
||||||
|
glow(0),
|
||||||
|
glowdir(0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 30; i++)
|
||||||
|
{
|
||||||
|
splitseconds.push_back(int((i * 100) / 30));
|
||||||
|
}
|
||||||
|
|
||||||
|
slowsine = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UtilityClass::String( int _v )
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
os << _v;
|
||||||
|
return(os.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UtilityClass::GCString(std::vector<SDL_GameControllerButton> buttons)
|
||||||
|
{
|
||||||
|
std::string retval = "";
|
||||||
|
for (size_t i = 0; i < buttons.size(); i += 1)
|
||||||
|
{
|
||||||
|
retval += GCChar(buttons[i]);
|
||||||
|
if ((i + 1) < buttons.size())
|
||||||
|
{
|
||||||
|
retval += ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UtilityClass::twodigits( int t )
|
||||||
|
{
|
||||||
|
if (t < 10)
|
||||||
|
{
|
||||||
|
return "0" + String(t);
|
||||||
|
}
|
||||||
|
if (t >= 100)
|
||||||
|
{
|
||||||
|
return "??";
|
||||||
|
}
|
||||||
|
return String(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UtilityClass::timestring( int t )
|
||||||
|
{
|
||||||
|
//given a time t in frames, return a time in seconds
|
||||||
|
tempstring = "";
|
||||||
|
temp = (t - (t % 30)) / 30;
|
||||||
|
if (temp < 60) //less than one minute
|
||||||
|
{
|
||||||
|
t = t % 30;
|
||||||
|
tempstring = String(temp) + ":" + twodigits(splitseconds[t]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp2 = (temp - (temp % 60)) / 60;
|
||||||
|
temp = temp % 60;
|
||||||
|
t = t % 30;
|
||||||
|
tempstring = String(temp2) + ":" + twodigits(temp) + ":" + twodigits(splitseconds[t]);
|
||||||
|
}
|
||||||
|
return tempstring;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string UtilityClass::number( int _t )
|
||||||
|
{
|
||||||
|
switch(_t)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "Zero";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
return "One";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
return "Two";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
return "Three";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
return "Four";
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
return "Five";
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
return "Six";
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
return "Seven";
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
return "Eight";
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
return "Nine";
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
return "Ten";
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
return "Eleven";
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
return "Twelve";
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
return "Thirteen";
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
return "Fourteen";
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
return "Fifteen";
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
return "Sixteen";
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
return "Seventeen";
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
return "Eighteen";
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
return "Nineteen";
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
return "Twenty";
|
||||||
|
break;
|
||||||
|
case 21:
|
||||||
|
return "Twenty One";
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
return "Twenty Two";
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
return "Twenty Three";
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
return "Twenty Four";
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
return "Twenty Five";
|
||||||
|
break;
|
||||||
|
case 26:
|
||||||
|
return "Twenty Six";
|
||||||
|
break;
|
||||||
|
case 27:
|
||||||
|
return "Twenty Seven";
|
||||||
|
break;
|
||||||
|
case 28:
|
||||||
|
return "Twenty Eight";
|
||||||
|
break;
|
||||||
|
case 29:
|
||||||
|
return "Twenty Nine";
|
||||||
|
break;
|
||||||
|
case 30:
|
||||||
|
return "Thirty";
|
||||||
|
break;
|
||||||
|
case 31:
|
||||||
|
return "Thirty One";
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
return "Thirty Two";
|
||||||
|
break;
|
||||||
|
case 33:
|
||||||
|
return "Thirty Three";
|
||||||
|
break;
|
||||||
|
case 34:
|
||||||
|
return "Thirty Four";
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
return "Thirty Five";
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
return "Thirty Six";
|
||||||
|
break;
|
||||||
|
case 37:
|
||||||
|
return "Thirty Seven";
|
||||||
|
break;
|
||||||
|
case 38:
|
||||||
|
return "Thirty Eight";
|
||||||
|
break;
|
||||||
|
case 39:
|
||||||
|
return "Thirty Nine";
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
return "Forty";
|
||||||
|
break;
|
||||||
|
case 41:
|
||||||
|
return "Forty One";
|
||||||
|
break;
|
||||||
|
case 42:
|
||||||
|
return "Forty Two";
|
||||||
|
break;
|
||||||
|
case 43:
|
||||||
|
return "Forty Three";
|
||||||
|
break;
|
||||||
|
case 44:
|
||||||
|
return "Forty Four";
|
||||||
|
break;
|
||||||
|
case 45:
|
||||||
|
return "Forty Five";
|
||||||
|
break;
|
||||||
|
case 46:
|
||||||
|
return "Forty Six";
|
||||||
|
break;
|
||||||
|
case 47:
|
||||||
|
return "Forty Seven";
|
||||||
|
break;
|
||||||
|
case 48:
|
||||||
|
return "Forty Eight";
|
||||||
|
break;
|
||||||
|
case 49:
|
||||||
|
return "Forty Nine";
|
||||||
|
break;
|
||||||
|
case 50:
|
||||||
|
return "Fifty";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "Lots";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UtilityClass::intersects( SDL_Rect A, SDL_Rect B )
|
||||||
|
{
|
||||||
|
int leftA, leftB;
|
||||||
|
int rightA, rightB;
|
||||||
|
int topA, topB;
|
||||||
|
int bottomA, bottomB;
|
||||||
|
//Calculate the sides of rect A
|
||||||
|
leftA = A.x;
|
||||||
|
rightA = A.x + A.w;
|
||||||
|
topA = A.y;
|
||||||
|
bottomA = A.y + A.h;
|
||||||
|
//Calculate the sides of rect B
|
||||||
|
leftB = B.x;
|
||||||
|
rightB = B.x + B.w;
|
||||||
|
topB = B.y;
|
||||||
|
bottomB = B.y + B.h;
|
||||||
|
|
||||||
|
if( bottomA <= topB )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if( topA >= bottomB )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if( rightA <= leftB )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if( leftA >= rightB )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//If none of the sides from A are outside B return true; }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UtilityClass::updateglow()
|
||||||
|
{
|
||||||
|
slowsine++;
|
||||||
|
if (slowsine >= 64) slowsine = 0;
|
||||||
|
|
||||||
|
if (glowdir == 0) {
|
||||||
|
glow+=2;
|
||||||
|
if (glow >= 62) glowdir = 1;
|
||||||
|
}else {
|
||||||
|
glow-=2;
|
||||||
|
if (glow < 2) glowdir = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
46
desktop_version/src/UtilityClass.h
Normal file
46
desktop_version/src/UtilityClass.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef UTILITYCLASS_H
|
||||||
|
#define UTILITYCLASS_H
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
int ss_toi(std::string _s);
|
||||||
|
|
||||||
|
std::vector<std::string> split(const std::string &s, char delim, std::vector<std::string> &elems);
|
||||||
|
|
||||||
|
std::vector<std::string> split(const std::string &s, char delim);
|
||||||
|
|
||||||
|
|
||||||
|
//helperClass
|
||||||
|
class UtilityClass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UtilityClass();
|
||||||
|
|
||||||
|
static std::string String(int _v);
|
||||||
|
|
||||||
|
static std::string GCString(std::vector<SDL_GameControllerButton> buttons);
|
||||||
|
|
||||||
|
std::string twodigits(int t);
|
||||||
|
|
||||||
|
std::string timestring(int t);
|
||||||
|
|
||||||
|
std::string number(int _t);
|
||||||
|
|
||||||
|
|
||||||
|
static bool intersects( SDL_Rect A, SDL_Rect B );
|
||||||
|
|
||||||
|
void updateglow();
|
||||||
|
|
||||||
|
int glow;
|
||||||
|
int slowsine;
|
||||||
|
int glowdir;
|
||||||
|
int globaltemp;
|
||||||
|
int temp;
|
||||||
|
int temp2;
|
||||||
|
std::string tempstring;
|
||||||
|
std::vector<int> splitseconds;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* UTILITYCLASS_H */
|
||||||
1033
desktop_version/src/WarpClass.cpp
Normal file
1033
desktop_version/src/WarpClass.cpp
Normal file
File diff suppressed because it is too large
Load Diff
19
desktop_version/src/WarpClass.h
Normal file
19
desktop_version/src/WarpClass.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef WARPCLASS_H
|
||||||
|
#define WARPCLASS_H
|
||||||
|
|
||||||
|
#include "Game.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class warpclass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<std::string> loadlevel(int rx, int ry , Game& game, entityclass& obj);
|
||||||
|
std::string roomname;
|
||||||
|
int coin, rcol;
|
||||||
|
bool warpx, warpy;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* WARPCLASS_H */
|
||||||
5353
desktop_version/src/editor.cpp
Normal file
5353
desktop_version/src/editor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
262
desktop_version/src/editor.h
Normal file
262
desktop_version/src/editor.h
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
#ifndef EDITOR_H
|
||||||
|
#define EDITOR_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "Script.h"
|
||||||
|
|
||||||
|
class KeyPoll; class Graphics; class Game; class mapclass; class entityclass; class UtilityClass;
|
||||||
|
|
||||||
|
|
||||||
|
class edentities{
|
||||||
|
public:
|
||||||
|
int x, y, t;
|
||||||
|
//parameters
|
||||||
|
int p1, p2, p3, p4, p5, p6;
|
||||||
|
std::string scriptname;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class edlevelclass{
|
||||||
|
public:
|
||||||
|
edlevelclass();
|
||||||
|
int tileset, tilecol;
|
||||||
|
std::string roomname;
|
||||||
|
int warpdir;
|
||||||
|
int platx1, platy1, platx2, platy2, platv;
|
||||||
|
int enemyx1, enemyy1, enemyx2, enemyy2, enemytype;
|
||||||
|
int directmode;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LevelMetaData
|
||||||
|
{
|
||||||
|
std::string title;
|
||||||
|
std::string creator;
|
||||||
|
std::string Desc1;
|
||||||
|
std::string Desc2;
|
||||||
|
std::string Desc3;
|
||||||
|
std::string website;
|
||||||
|
std::string filename;
|
||||||
|
|
||||||
|
std::string modifier;
|
||||||
|
std::string timeCreated;
|
||||||
|
std::string timeModified;
|
||||||
|
|
||||||
|
int version;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern edentities edentity[3000];
|
||||||
|
extern scriptclass script;
|
||||||
|
|
||||||
|
class EditorData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static EditorData& GetInstance()
|
||||||
|
{
|
||||||
|
static EditorData instance; // Guaranteed to be destroyed.
|
||||||
|
// Instantiated on first use.
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int numedentities;
|
||||||
|
std::string title;
|
||||||
|
std::string creator;
|
||||||
|
|
||||||
|
std::string modifier;
|
||||||
|
std::string timeCreated;
|
||||||
|
std::string timeModified;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
EditorData():
|
||||||
|
numedentities(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class editorclass{
|
||||||
|
//Special class to handle ALL editor variables locally
|
||||||
|
public:
|
||||||
|
editorclass();
|
||||||
|
|
||||||
|
std::string Desc1;
|
||||||
|
std::string Desc2;
|
||||||
|
std::string Desc3;
|
||||||
|
std::string website;
|
||||||
|
|
||||||
|
std::vector<std::string> directoryList;
|
||||||
|
std::vector<LevelMetaData> ListOfMetaData;
|
||||||
|
|
||||||
|
void getDirectoryData();
|
||||||
|
bool getLevelMetaData(std::string& filename, LevelMetaData& _data );
|
||||||
|
|
||||||
|
void saveconvertor();
|
||||||
|
void reset();
|
||||||
|
void loadlevel(int rxi, int ryi);
|
||||||
|
|
||||||
|
void placetile(int x, int y, int t);
|
||||||
|
|
||||||
|
void placetilelocal(int x, int y, int t);
|
||||||
|
|
||||||
|
int getenemyframe(int t);
|
||||||
|
int base(int x, int y);
|
||||||
|
|
||||||
|
int backbase(int x, int y);
|
||||||
|
|
||||||
|
int at(int x, int y);
|
||||||
|
|
||||||
|
int freewrap(int x, int y);
|
||||||
|
|
||||||
|
int backonlyfree(int x, int y);
|
||||||
|
|
||||||
|
int backfree(int x, int y);
|
||||||
|
|
||||||
|
int spikefree(int x, int y);
|
||||||
|
int free(int x, int y);
|
||||||
|
int absfree(int x, int y);
|
||||||
|
|
||||||
|
int match(int x, int y);
|
||||||
|
int warpzonematch(int x, int y);
|
||||||
|
int outsidematch(int x, int y);
|
||||||
|
|
||||||
|
int backmatch(int x, int y);
|
||||||
|
|
||||||
|
void load(std::string& _path);
|
||||||
|
void save(std::string& _path);
|
||||||
|
void generatecustomminimap(Graphics& dwgfx, mapclass& map);
|
||||||
|
int edgetile(int x, int y);
|
||||||
|
int warpzoneedgetile(int x, int y);
|
||||||
|
int outsideedgetile(int x, int y);
|
||||||
|
|
||||||
|
int backedgetile(int x, int y);
|
||||||
|
|
||||||
|
int labspikedir(int x, int y, int t);
|
||||||
|
int spikedir(int x, int y);
|
||||||
|
int findtrinket(int t);
|
||||||
|
int findcrewmate(int t);
|
||||||
|
int findwarptoken(int t);
|
||||||
|
void countstuff();
|
||||||
|
void findstartpoint(Game& game);
|
||||||
|
void weirdloadthing(std::string t);
|
||||||
|
int getlevelcol(int t);
|
||||||
|
int getenemycol(int t);
|
||||||
|
int entcol;
|
||||||
|
|
||||||
|
//Colouring stuff
|
||||||
|
int getwarpbackground(int rx, int ry);
|
||||||
|
|
||||||
|
std::vector<std::string> getLevelDirFileNames( );
|
||||||
|
std::vector <int> swapmap;
|
||||||
|
std::vector <int> contents;
|
||||||
|
std::vector <int> vmult;
|
||||||
|
int numtrinkets;
|
||||||
|
int numcrewmates;
|
||||||
|
edlevelclass level[400]; //Maxwidth*maxheight
|
||||||
|
|
||||||
|
int temp;
|
||||||
|
int notedelay;
|
||||||
|
std::string note;
|
||||||
|
std::string keybuffer;
|
||||||
|
std::string filename;
|
||||||
|
|
||||||
|
int drawmode;
|
||||||
|
int tilex, tiley;
|
||||||
|
int keydelay, lclickdelay;
|
||||||
|
bool savekey, loadkey;
|
||||||
|
int levx, levy;
|
||||||
|
int entframe, entframedelay;
|
||||||
|
|
||||||
|
bool roomtextmod;
|
||||||
|
int roomtextent;
|
||||||
|
|
||||||
|
bool scripttextmod;
|
||||||
|
int scripttextent;
|
||||||
|
int scripttexttype;
|
||||||
|
|
||||||
|
bool xmod, zmod, spacemod, warpmod, roomnamemod, textentry, savemod, loadmod;
|
||||||
|
bool titlemod, creatormod, desc1mod, desc2mod, desc3mod, websitemod;
|
||||||
|
|
||||||
|
int roomnamehide;
|
||||||
|
bool saveandquit;
|
||||||
|
bool shiftmenu, shiftkey;
|
||||||
|
int spacemenu;
|
||||||
|
bool settingsmod, settingskey;
|
||||||
|
int warpent;
|
||||||
|
bool updatetiles, changeroom;
|
||||||
|
int deletekeyheld;
|
||||||
|
|
||||||
|
int boundarymod, boundarytype;
|
||||||
|
int boundx1, boundx2, boundy1, boundy2;
|
||||||
|
|
||||||
|
int levmusic;
|
||||||
|
int mapwidth, mapheight; //Actual width and height of stage
|
||||||
|
int maxwidth, maxheight; //Special; the physical max the engine allows
|
||||||
|
|
||||||
|
int version;
|
||||||
|
|
||||||
|
//Script editor stuff
|
||||||
|
void removeline(int t);
|
||||||
|
void insertline(int t);
|
||||||
|
|
||||||
|
bool scripteditmod;
|
||||||
|
int scripthelppage, scripthelppagedelay;
|
||||||
|
std::string sb[500];
|
||||||
|
std::string sbscript;
|
||||||
|
int sblength;
|
||||||
|
int sbx, sby;
|
||||||
|
int pagey;
|
||||||
|
|
||||||
|
std::string author;
|
||||||
|
std::string description;
|
||||||
|
std::string title;
|
||||||
|
|
||||||
|
//Functions for interfacing with the script:
|
||||||
|
void addhook(std::string t);
|
||||||
|
void removehook(std::string t);
|
||||||
|
void addhooktoscript(std::string t);
|
||||||
|
void removehookfromscript(std::string t);
|
||||||
|
void loadhookineditor(std::string t);
|
||||||
|
void clearscriptbuffer();
|
||||||
|
void gethooks();
|
||||||
|
bool checkhook(std::string t);
|
||||||
|
std::string hooklist[500];
|
||||||
|
int numhooks;
|
||||||
|
|
||||||
|
int hookmenupage, hookmenu;
|
||||||
|
|
||||||
|
//Direct Mode variables
|
||||||
|
int dmtile;
|
||||||
|
int dmtileeditor;
|
||||||
|
};
|
||||||
|
|
||||||
|
void addedentity(int xp, int yp, int tp, int p1=0, int p2=0, int p3=0, int p4=0, int p5=320, int p6=240);
|
||||||
|
|
||||||
|
void naddedentity(int xp, int yp, int tp, int p1=0, int p2=0, int p3=0, int p4=0, int p5=320, int p6=240);
|
||||||
|
|
||||||
|
void copyedentity(int a, int b);
|
||||||
|
|
||||||
|
void removeedentity(int t);
|
||||||
|
|
||||||
|
int edentat(int xp, int yp);
|
||||||
|
|
||||||
|
|
||||||
|
bool edentclear(int xp, int yp);
|
||||||
|
|
||||||
|
void fillbox(Graphics& dwgfx, int x, int y, int x2, int y2, int c);
|
||||||
|
|
||||||
|
void fillboxabs(Graphics& dwgfx, int x, int y, int x2, int y2, int c);
|
||||||
|
|
||||||
|
void editorrender(KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map, entityclass& obj, UtilityClass& help);
|
||||||
|
|
||||||
|
void editorlogic(KeyPoll& key, Graphics& dwgfx, Game& game, entityclass& obj, musicclass& music, mapclass& map, UtilityClass& help);
|
||||||
|
|
||||||
|
void editorinput(KeyPoll& key, Graphics& dwgfx, Game& game, mapclass& map,
|
||||||
|
entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
#endif /* EDITOR_H */
|
||||||
539
desktop_version/src/main.cpp
Normal file
539
desktop_version/src/main.cpp
Normal file
@@ -0,0 +1,539 @@
|
|||||||
|
#include <SDL.h>
|
||||||
|
#include "SoundSystem.h"
|
||||||
|
|
||||||
|
#include "UtilityClass.h"
|
||||||
|
#include "Game.h"
|
||||||
|
#include "Graphics.h"
|
||||||
|
#include "KeyPoll.h"
|
||||||
|
#include "titlerender.h"
|
||||||
|
|
||||||
|
#include "Tower.h"
|
||||||
|
#include "WarpClass.h"
|
||||||
|
#include "Labclass.h"
|
||||||
|
#include "Finalclass.h"
|
||||||
|
#include "Map.h"
|
||||||
|
|
||||||
|
#include "Screen.h"
|
||||||
|
|
||||||
|
#include "Script.h"
|
||||||
|
|
||||||
|
#include "Logic.h"
|
||||||
|
|
||||||
|
#include "Input.h"
|
||||||
|
#include "editor.h"
|
||||||
|
#include "preloader.h"
|
||||||
|
|
||||||
|
#include "FileSystemUtils.h"
|
||||||
|
#include "Network.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
scriptclass script;
|
||||||
|
edentities edentity[3000];
|
||||||
|
|
||||||
|
editorclass ed;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
FILESYSTEM_init(argv[0]);
|
||||||
|
SDL_Init(
|
||||||
|
SDL_INIT_VIDEO |
|
||||||
|
SDL_INIT_AUDIO |
|
||||||
|
SDL_INIT_JOYSTICK |
|
||||||
|
SDL_INIT_GAMECONTROLLER
|
||||||
|
);
|
||||||
|
|
||||||
|
if (argc > 2 && strcmp(argv[1], "-renderer") == 0)
|
||||||
|
{
|
||||||
|
SDL_SetHintWithPriority(SDL_HINT_RENDER_DRIVER, argv[2], SDL_HINT_OVERRIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NETWORK_init();
|
||||||
|
|
||||||
|
Screen gameScreen;
|
||||||
|
|
||||||
|
printf("\t\t\n");
|
||||||
|
printf("\t\t\n");
|
||||||
|
printf("\t\t VVVVVV\n");
|
||||||
|
printf("\t\t\n");
|
||||||
|
printf("\t\t\n");
|
||||||
|
printf("\t\t 8888888888888888 \n");
|
||||||
|
printf("\t\t88888888888888888888\n");
|
||||||
|
printf("\t\t888888 8888 88\n");
|
||||||
|
printf("\t\t888888 8888 88\n");
|
||||||
|
printf("\t\t88888888888888888888\n");
|
||||||
|
printf("\t\t88888888888888888888\n");
|
||||||
|
printf("\t\t888888 88\n");
|
||||||
|
printf("\t\t88888888 8888\n");
|
||||||
|
printf("\t\t 8888888888888888 \n");
|
||||||
|
printf("\t\t 88888888 \n");
|
||||||
|
printf("\t\t 8888888888888888 \n");
|
||||||
|
printf("\t\t88888888888888888888\n");
|
||||||
|
printf("\t\t88888888888888888888\n");
|
||||||
|
printf("\t\t88888888888888888888\n");
|
||||||
|
printf("\t\t8888 88888888 8888\n");
|
||||||
|
printf("\t\t8888 88888888 8888\n");
|
||||||
|
printf("\t\t 888888888888 \n");
|
||||||
|
printf("\t\t 8888 8888 \n");
|
||||||
|
printf("\t\t 888888 888888 \n");
|
||||||
|
printf("\t\t 888888 888888 \n");
|
||||||
|
printf("\t\t 888888 888888 \n");
|
||||||
|
printf("\t\t\n");
|
||||||
|
printf("\t\t\n");
|
||||||
|
|
||||||
|
//Set up screen
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
UtilityClass help;
|
||||||
|
// Load Ini
|
||||||
|
|
||||||
|
|
||||||
|
Graphics graphics;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
musicclass music;
|
||||||
|
Game game;
|
||||||
|
game.infocus = true;
|
||||||
|
|
||||||
|
graphics.MakeTileArray();
|
||||||
|
graphics.MakeSpriteArray();
|
||||||
|
graphics.maketelearray();
|
||||||
|
|
||||||
|
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image0);
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image1);
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image2);
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image3);
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image4);
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image5);
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image6);
|
||||||
|
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image7);
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image8);
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image9);
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image10);
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image11);
|
||||||
|
graphics.images.push_back(graphics.grphx.im_image12);
|
||||||
|
|
||||||
|
const SDL_PixelFormat* fmt = gameScreen.GetFormat();
|
||||||
|
graphics.backBuffer = SDL_CreateRGBSurface(SDL_SWSURFACE ,320 ,240 ,32,fmt->Rmask,fmt->Gmask,fmt->Bmask,fmt->Amask ) ;
|
||||||
|
SDL_SetSurfaceBlendMode(graphics.backBuffer, SDL_BLENDMODE_NONE);
|
||||||
|
graphics.Makebfont();
|
||||||
|
|
||||||
|
|
||||||
|
graphics.forgroundBuffer = SDL_CreateRGBSurface(SDL_SWSURFACE ,320 ,240 ,fmt->BitsPerPixel,fmt->Rmask,fmt->Gmask,fmt->Bmask,fmt->Amask );
|
||||||
|
SDL_SetSurfaceBlendMode(graphics.forgroundBuffer, SDL_BLENDMODE_NONE);
|
||||||
|
|
||||||
|
graphics.screenbuffer = &gameScreen;
|
||||||
|
|
||||||
|
graphics.menubuffer = SDL_CreateRGBSurface(SDL_SWSURFACE ,320 ,240 ,fmt->BitsPerPixel,fmt->Rmask,fmt->Gmask,fmt->Bmask,fmt->Amask );
|
||||||
|
SDL_SetSurfaceBlendMode(graphics.menubuffer, SDL_BLENDMODE_NONE);
|
||||||
|
|
||||||
|
graphics.towerbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE ,320 ,240 ,fmt->BitsPerPixel,fmt->Rmask,fmt->Gmask,fmt->Bmask,fmt->Amask );
|
||||||
|
SDL_SetSurfaceBlendMode(graphics.towerbuffer, SDL_BLENDMODE_NONE);
|
||||||
|
|
||||||
|
graphics.tempBuffer = SDL_CreateRGBSurface(SDL_SWSURFACE ,320 ,240 ,fmt->BitsPerPixel,fmt->Rmask,fmt->Gmask,fmt->Bmask,fmt->Amask );
|
||||||
|
SDL_SetSurfaceBlendMode(graphics.tempBuffer, SDL_BLENDMODE_NONE);
|
||||||
|
|
||||||
|
//Make a temporary rectangle to hold the offsets
|
||||||
|
// SDL_Rect offset;
|
||||||
|
//Give the offsets to the rectangle
|
||||||
|
// offset.x = 60;
|
||||||
|
// offset.y = 80;
|
||||||
|
|
||||||
|
//game.gamestate = TITLEMODE;
|
||||||
|
//game.gamestate=EDITORMODE;
|
||||||
|
game.gamestate = PRELOADER; //Remember to uncomment this later!
|
||||||
|
|
||||||
|
game.menustart = false;
|
||||||
|
game.mainmenu = 0;
|
||||||
|
|
||||||
|
KeyPoll key;
|
||||||
|
mapclass map;
|
||||||
|
|
||||||
|
map.ypos = (700-29) * 8;
|
||||||
|
map.bypos = map.ypos / 2;
|
||||||
|
|
||||||
|
//Moved screensetting init here from main menu V2.1
|
||||||
|
game.loadstats(map, graphics);
|
||||||
|
if(game.usingmmmmmm==0) music.usingmmmmmm=false;
|
||||||
|
if(game.usingmmmmmm==1) music.usingmmmmmm=true;
|
||||||
|
if (game.slowdown == 0) game.slowdown = 30;
|
||||||
|
|
||||||
|
switch(game.slowdown){
|
||||||
|
case 30: game.gameframerate=34; break;
|
||||||
|
case 24: game.gameframerate=41; break;
|
||||||
|
case 18: game.gameframerate=55; break;
|
||||||
|
case 12: game.gameframerate=83; break;
|
||||||
|
default: game.gameframerate=34; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check to see if you've already unlocked some achievements here from before the update
|
||||||
|
if (game.swnbestrank > 0){
|
||||||
|
if(game.swnbestrank >= 1) NETWORK_unlockAchievement("vvvvvvsupgrav5");
|
||||||
|
if(game.swnbestrank >= 2) NETWORK_unlockAchievement("vvvvvvsupgrav10");
|
||||||
|
if(game.swnbestrank >= 3) NETWORK_unlockAchievement("vvvvvvsupgrav15");
|
||||||
|
if(game.swnbestrank >= 4) NETWORK_unlockAchievement("vvvvvvsupgrav20");
|
||||||
|
if(game.swnbestrank >= 5) NETWORK_unlockAchievement("vvvvvvsupgrav30");
|
||||||
|
if(game.swnbestrank >= 6) NETWORK_unlockAchievement("vvvvvvsupgrav60");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(game.unlock[5]) NETWORK_unlockAchievement("vvvvvvgamecomplete");
|
||||||
|
if(game.unlock[19]) NETWORK_unlockAchievement("vvvvvvgamecompleteflip");
|
||||||
|
if(game.unlock[20]) NETWORK_unlockAchievement("vvvvvvmaster");
|
||||||
|
|
||||||
|
if (game.bestgamedeaths > -1) {
|
||||||
|
if (game.bestgamedeaths <= 500) {
|
||||||
|
NETWORK_unlockAchievement("vvvvvvcomplete500");
|
||||||
|
}
|
||||||
|
if (game.bestgamedeaths <= 250) {
|
||||||
|
NETWORK_unlockAchievement("vvvvvvcomplete250");
|
||||||
|
}
|
||||||
|
if (game.bestgamedeaths <= 100) {
|
||||||
|
NETWORK_unlockAchievement("vvvvvvcomplete100");
|
||||||
|
}
|
||||||
|
if (game.bestgamedeaths <= 50) {
|
||||||
|
NETWORK_unlockAchievement("vvvvvvcomplete50");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(game.bestrank[0]>=3) NETWORK_unlockAchievement("vvvvvvtimetrial_station1_fixed");
|
||||||
|
if(game.bestrank[1]>=3) NETWORK_unlockAchievement("vvvvvvtimetrial_lab_fixed");
|
||||||
|
if(game.bestrank[2]>=3) NETWORK_unlockAchievement("vvvvvvtimetrial_tower_fixed");
|
||||||
|
if(game.bestrank[3]>=3) NETWORK_unlockAchievement("vvvvvvtimetrial_station2_fixed");
|
||||||
|
if(game.bestrank[4]>=3) NETWORK_unlockAchievement("vvvvvvtimetrial_warp_fixed");
|
||||||
|
if(game.bestrank[5]>=3) NETWORK_unlockAchievement("vvvvvvtimetrial_final_fixed");
|
||||||
|
|
||||||
|
entityclass obj;
|
||||||
|
obj.init();
|
||||||
|
|
||||||
|
//Quick hack to start in final level ---- //Might be useful to leave this commented in for testing
|
||||||
|
/*
|
||||||
|
//game.gamestate=GAMEMODE;
|
||||||
|
//game.start(obj,music);
|
||||||
|
//script.startgamemode(8, key, graphics, game, map, obj, help, music);
|
||||||
|
// map.finalmode = true; //Enable final level mode
|
||||||
|
//map.finalx = 41; map.finaly = 52; //Midpoint
|
||||||
|
//map.finalstretch = true;
|
||||||
|
//map.final_colormode = true;
|
||||||
|
//map.final_mapcol = 0;
|
||||||
|
//map.final_colorframe = 0;
|
||||||
|
|
||||||
|
//game.starttest(obj, music);
|
||||||
|
|
||||||
|
game.savex = 5 * 8; game.savey = 15 * 8; game.saverx = 41; game.savery = 52;
|
||||||
|
game.savegc = 0; game.savedir = 1;
|
||||||
|
game.state = 0; game.deathseq = -1; game.lifeseq = 10;
|
||||||
|
//obj.createentity(game, game.savex, game.savey, 0);
|
||||||
|
map.gotoroom(game.saverx, game.savery, graphics, game, obj, music);
|
||||||
|
//music.play(1);
|
||||||
|
*/
|
||||||
|
//End hack here ----
|
||||||
|
|
||||||
|
volatile Uint32 time, timePrev = 0;
|
||||||
|
game.infocus = true;
|
||||||
|
key.isActive = true;
|
||||||
|
|
||||||
|
while(!key.quitProgram)
|
||||||
|
{
|
||||||
|
//gameScreen.ClearScreen(0x00);
|
||||||
|
|
||||||
|
time = SDL_GetTicks();
|
||||||
|
|
||||||
|
// Update network per frame.
|
||||||
|
NETWORK_update();
|
||||||
|
|
||||||
|
//framerate limit to 30
|
||||||
|
Uint32 timetaken = time - timePrev;
|
||||||
|
if(game.gamestate==EDITORMODE)
|
||||||
|
{
|
||||||
|
if (timetaken < 24)
|
||||||
|
{
|
||||||
|
volatile Uint32 delay = 24 - timetaken;
|
||||||
|
SDL_Delay( delay );
|
||||||
|
time = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
timePrev = time;
|
||||||
|
|
||||||
|
}else{
|
||||||
|
if (timetaken < game.gameframerate)
|
||||||
|
{
|
||||||
|
volatile Uint32 delay = game.gameframerate - timetaken;
|
||||||
|
SDL_Delay( delay );
|
||||||
|
time = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
timePrev = time;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
key.Poll();
|
||||||
|
if(key.toggleFullscreen)
|
||||||
|
{
|
||||||
|
if(!gameScreen.isWindowed)
|
||||||
|
{
|
||||||
|
//SDL_WM_GrabInput(SDL_GRAB_ON);
|
||||||
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
|
SDL_ShowCursor(SDL_ENABLE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_ShowCursor(SDL_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(game.gamestate == EDITORMODE)
|
||||||
|
{
|
||||||
|
SDL_ShowCursor(SDL_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
gameScreen.toggleFullScreen();
|
||||||
|
game.fullscreen = !game.fullscreen;
|
||||||
|
key.toggleFullscreen = false;
|
||||||
|
|
||||||
|
key.keymap.clear(); //we lost the input due to a new window.
|
||||||
|
game.press_left = false;
|
||||||
|
game.press_right = false;
|
||||||
|
game.press_action = true;
|
||||||
|
game.press_map = false;
|
||||||
|
printf("Error: failed: %s\n", SDL_GetError());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/*if(key.quitProgram)
|
||||||
|
{
|
||||||
|
music.playef(2);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
game.infocus = key.isActive;
|
||||||
|
if(!game.infocus)
|
||||||
|
{
|
||||||
|
if(game.getGlobalSoundVol()> 0)
|
||||||
|
{
|
||||||
|
game.setGlobalSoundVol(0);
|
||||||
|
}
|
||||||
|
FillRect(graphics.backBuffer, 0x00000000);
|
||||||
|
graphics.bprint(5, 110, "Game paused", 196 - help.glow, 255 - help.glow, 196 - help.glow, true);
|
||||||
|
graphics.bprint(5, 120, "[click to resume]", 196 - help.glow, 255 - help.glow, 196 - help.glow, true);
|
||||||
|
graphics.bprint(5, 230, "Press M to mute in game", 164 - help.glow, 196 - help.glow, 164 - help.glow, true);
|
||||||
|
graphics.render();
|
||||||
|
//We are minimised, so lets put a bit of a delay to save CPU
|
||||||
|
SDL_Delay(100);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(game.gamestate)
|
||||||
|
{
|
||||||
|
case PRELOADER:
|
||||||
|
//Render
|
||||||
|
preloaderrender(graphics, game, help);
|
||||||
|
break;
|
||||||
|
case EDITORMODE:
|
||||||
|
graphics.flipmode = false;
|
||||||
|
//Input
|
||||||
|
editorinput(key, graphics, game, map, obj, help, music);
|
||||||
|
//Render
|
||||||
|
editorrender(key, graphics, game, map, obj, help);
|
||||||
|
////Logic
|
||||||
|
editorlogic(key, graphics, game, obj, music, map, help);
|
||||||
|
break;
|
||||||
|
case TITLEMODE:
|
||||||
|
//Input
|
||||||
|
titleinput(key, graphics, map, game, obj, help, music);
|
||||||
|
//Render
|
||||||
|
titlerender(graphics, map, game, obj, help, music);
|
||||||
|
////Logic
|
||||||
|
titlelogic(graphics, game, obj, help, music, map);
|
||||||
|
break;
|
||||||
|
case GAMEMODE:
|
||||||
|
if (map.towermode)
|
||||||
|
{
|
||||||
|
gameinput(key, graphics, game, map, obj, help, music);
|
||||||
|
|
||||||
|
//if(game.recording==1)
|
||||||
|
//{
|
||||||
|
// ///recordinput(key, graphics, game, map, obj, help, music);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
//}
|
||||||
|
towerrender(graphics, game, map, obj, help);
|
||||||
|
towerlogic(graphics, game, obj, music, map, help);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
if (game.recording == 1)
|
||||||
|
{
|
||||||
|
//recordinput(key, dwgfx, game, map, obj, help, music);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (script.running)
|
||||||
|
{
|
||||||
|
script.run(key, graphics, game, map, obj, help, music);
|
||||||
|
}
|
||||||
|
|
||||||
|
gameinput(key, graphics, game, map, obj, help, music);
|
||||||
|
//}
|
||||||
|
gamerender(graphics,map, game, obj, help);
|
||||||
|
gamelogic(graphics, game,obj, music, map, help);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MAPMODE:
|
||||||
|
maprender(graphics, game, map, obj, help);
|
||||||
|
if (game.recording == 1)
|
||||||
|
{
|
||||||
|
//recordinput(key, dwgfx, game, map, obj, help, music); //will implement this later if it's actually needed
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mapinput(key, graphics, game, map, obj, help, music);
|
||||||
|
}
|
||||||
|
maplogic(graphics, game, obj ,music , map, help );
|
||||||
|
break;
|
||||||
|
case TELEPORTERMODE:
|
||||||
|
teleporterrender(graphics, game, map, obj, help);
|
||||||
|
if (game.recording == 1)
|
||||||
|
{
|
||||||
|
//recordinput(key, graphics, game, map, obj, help, music);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(game.useteleporter)
|
||||||
|
{
|
||||||
|
teleporterinput(key, graphics, game, map, obj, help, music);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (script.running)
|
||||||
|
{
|
||||||
|
script.run(key, graphics, game, map, obj, help, music);
|
||||||
|
}
|
||||||
|
gameinput(key, graphics, game, map, obj, help, music);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maplogic(graphics, game, obj, music, map, help);
|
||||||
|
break;
|
||||||
|
case GAMECOMPLETE:
|
||||||
|
gamecompleterender(graphics, game, obj, help, map);
|
||||||
|
//Input
|
||||||
|
gamecompleteinput(key, graphics, game, map, obj, help, music);
|
||||||
|
//Logic
|
||||||
|
gamecompletelogic(graphics, game, obj, music, map, help);
|
||||||
|
break;
|
||||||
|
case GAMECOMPLETE2:
|
||||||
|
gamecompleterender2(graphics, game, obj, help);
|
||||||
|
//Input
|
||||||
|
gamecompleteinput2(key, graphics, game, map, obj, help, music);
|
||||||
|
//Logic
|
||||||
|
gamecompletelogic2(graphics, game, obj, music, map, help);
|
||||||
|
break;
|
||||||
|
case CLICKTOSTART:
|
||||||
|
|
||||||
|
//dwgfx.bprint(5, 115, "[Click to start]", 196 - help.glow, 196 - help.glow, 255 - help.glow, true);
|
||||||
|
//dwgfx.drawgui(help);
|
||||||
|
//dwgfx.render();
|
||||||
|
//dwgfx.backbuffer.unlock();
|
||||||
|
|
||||||
|
help.updateglow();
|
||||||
|
// if (key.click) {
|
||||||
|
// dwgfx.textboxremove();
|
||||||
|
// }
|
||||||
|
// if (dwgfx.ntextbox == 0) {
|
||||||
|
// //music.play(6);
|
||||||
|
// map.ypos = (700-29) * 8;
|
||||||
|
// map.bypos = map.ypos / 2;
|
||||||
|
// map.cameramode = 0;
|
||||||
|
|
||||||
|
// game.gamestate = TITLEMODE;
|
||||||
|
// }
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (game.savemystats)
|
||||||
|
{
|
||||||
|
game.savemystats = false;
|
||||||
|
game.savestats(map, graphics);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Mute button
|
||||||
|
if (key.isDown(KEYBOARD_m) && game.mutebutton<=0 && !ed.textentry)
|
||||||
|
{
|
||||||
|
game.mutebutton = 8;
|
||||||
|
if (game.muted)
|
||||||
|
{
|
||||||
|
game.muted = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
game.muted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(game.mutebutton>0)
|
||||||
|
{
|
||||||
|
game.mutebutton--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (game.muted)
|
||||||
|
{
|
||||||
|
//if (game.globalsound == 1)
|
||||||
|
//{
|
||||||
|
game.globalsound = 0;
|
||||||
|
Mix_VolumeMusic(0) ;
|
||||||
|
Mix_Volume(-1,0);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!game.muted && game.globalsound == 0)
|
||||||
|
{
|
||||||
|
game.globalsound = 1;
|
||||||
|
Mix_VolumeMusic(MIX_MAX_VOLUME) ;
|
||||||
|
Mix_Volume(-1,MIX_MAX_VOLUME);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(key.resetWindow)
|
||||||
|
{
|
||||||
|
key.resetWindow = false;
|
||||||
|
gameScreen.ResizeScreen(-1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
music.processmusic();
|
||||||
|
graphics.processfade();
|
||||||
|
game.gameclock();
|
||||||
|
gameScreen.FlipScreen();
|
||||||
|
|
||||||
|
//SDL_FillRect( SDL_GetVideoSurface(), NULL, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//SDL_Delay(300);
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
//Free the loaded image
|
||||||
|
//SDL_FreeSurface( gameScreen );
|
||||||
|
|
||||||
|
//Quit SDL
|
||||||
|
NETWORK_shutdown();
|
||||||
|
SDL_Quit();
|
||||||
|
FILESYSTEM_deinit();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
126
desktop_version/src/preloader.cpp
Normal file
126
desktop_version/src/preloader.cpp
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
#include "preloader.h"
|
||||||
|
|
||||||
|
#include "Enums.h"
|
||||||
|
|
||||||
|
int pre_fakepercent=0, pre_transition=30;
|
||||||
|
bool pre_startgame=false;
|
||||||
|
int pre_darkcol=0, pre_lightcol=0, pre_curcol=0, pre_coltimer=0, pre_offset=0;
|
||||||
|
|
||||||
|
int pre_frontrectx=30, pre_frontrecty=20, pre_frontrectw=260, pre_frontrecth=200;
|
||||||
|
int pre_temprectx=0, pre_temprecty=0, pre_temprectw=320, pre_temprecth=240;
|
||||||
|
|
||||||
|
void preloaderrender(Graphics& dwgfx, Game& game, UtilityClass& help)
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
//dwgfx.backbuffer.lock();
|
||||||
|
|
||||||
|
//Draw grid
|
||||||
|
|
||||||
|
//pre_transition = -10; pre_fakepercent = 100;
|
||||||
|
|
||||||
|
if (pre_transition < 30) pre_transition--;
|
||||||
|
if(pre_transition>=30){
|
||||||
|
pre_fakepercent++;
|
||||||
|
if (pre_fakepercent >= 100) {
|
||||||
|
pre_fakepercent = 100;
|
||||||
|
pre_startgame = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre_offset = (pre_offset + 4 + int(fRandom() * 5.0f))%32;
|
||||||
|
pre_coltimer--;
|
||||||
|
if (pre_coltimer <= 0) {
|
||||||
|
pre_curcol = (pre_curcol + int(fRandom() * 5.0f)) % 6;
|
||||||
|
pre_coltimer = 8;
|
||||||
|
}
|
||||||
|
switch(pre_curcol) {
|
||||||
|
case 0:
|
||||||
|
pre_lightcol = dwgfx.RGBflip(0xBF,0x59,0x6F);
|
||||||
|
pre_darkcol = dwgfx.RGBflip(0x88,0x3E,0x53);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
pre_lightcol = dwgfx.RGBflip(0x6C,0xBC,0x5C);
|
||||||
|
pre_darkcol = dwgfx.RGBflip(0x50,0x86,0x40);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
pre_lightcol = dwgfx.RGBflip(0x5D,0x57,0xAA);
|
||||||
|
pre_darkcol = dwgfx.RGBflip(0x2F,0x2F,0x6C);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
pre_lightcol = dwgfx.RGBflip(0xB7,0xBA,0x5E);
|
||||||
|
pre_darkcol = dwgfx.RGBflip(0x84,0x83,0x42);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
pre_lightcol = dwgfx.RGBflip(0x57,0x90,0xAA);
|
||||||
|
pre_darkcol = dwgfx.RGBflip(0x2F,0x5B,0x6C);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
pre_lightcol = dwgfx.RGBflip(0x90,0x61,0xB1);
|
||||||
|
pre_darkcol = dwgfx.RGBflip(0x58,0x3D,0x71);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pre_lightcol = dwgfx.RGBflip(0x00,0x00,0x00);
|
||||||
|
pre_darkcol = dwgfx.RGBflip(0x08,0x00,0x00);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 18; i++) {
|
||||||
|
pre_temprecty = (i * 16)- pre_offset;
|
||||||
|
if (i % 2 == 0)
|
||||||
|
{
|
||||||
|
FillRect(dwgfx.backBuffer, pre_temprectx, pre_temprecty, pre_temprectw,pre_temprecth, pre_lightcol);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FillRect(dwgfx.backBuffer, pre_temprectx, pre_temprecty, pre_temprectw,pre_temprecth, pre_darkcol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FillRect(dwgfx.backBuffer, pre_frontrectx, pre_frontrecty, pre_frontrectw,pre_frontrecth, dwgfx.getBGR(0x3E,0x31,0xA2));
|
||||||
|
|
||||||
|
if(pre_fakepercent==100){
|
||||||
|
dwgfx.Print(282-(15*8), 204, "LOADING... " + help.String(int(pre_fakepercent))+"%", 124, 112, 218, false);
|
||||||
|
}else{
|
||||||
|
dwgfx.Print(282-(14*8), 204, "LOADING... " + help.String(int(pre_fakepercent))+"%", 124, 112, 218, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Render
|
||||||
|
if (pre_startgame) {
|
||||||
|
pre_transition = 29;
|
||||||
|
}
|
||||||
|
}else if (pre_transition <= -10) {
|
||||||
|
game.gamestate=TITLEMODE;
|
||||||
|
}else if (pre_transition < 5) {
|
||||||
|
FillRect(dwgfx.backBuffer, 0, 0, 320,240, dwgfx.getBGR(0,0,0));
|
||||||
|
}else if (pre_transition < 20) {
|
||||||
|
pre_temprecty = 0;
|
||||||
|
pre_temprecth = 240;
|
||||||
|
FillRect(dwgfx.backBuffer, pre_temprectx, pre_temprecty, pre_temprectw,pre_temprecth, 0x000000);
|
||||||
|
FillRect(dwgfx.backBuffer, pre_frontrectx, pre_frontrecty, pre_frontrectw,pre_frontrecth, dwgfx.getBGR(0x3E,0x31,0xA2));
|
||||||
|
|
||||||
|
dwgfx.Print(282-(15*8), 204, "LOADING... 100%", 124, 112, 218, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (game.test)
|
||||||
|
{
|
||||||
|
dwgfx.Print(5, 5, game.teststring, 196, 196, 255 - help.glow, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
dwgfx.drawfade();
|
||||||
|
|
||||||
|
if (game.flashlight > 0 && !game.noflashingmode)
|
||||||
|
{
|
||||||
|
game.flashlight--;
|
||||||
|
dwgfx.flashlight();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (game.screenshake > 0 && !game.noflashingmode)
|
||||||
|
{
|
||||||
|
game.screenshake--;
|
||||||
|
dwgfx.screenshake();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dwgfx.render();
|
||||||
|
}
|
||||||
|
//dwgfx.backbuffer.unlock();
|
||||||
|
}
|
||||||
10
desktop_version/src/preloader.h
Normal file
10
desktop_version/src/preloader.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef PRELOADER_H
|
||||||
|
#define PRELOADER_H
|
||||||
|
|
||||||
|
#include "Graphics.h"
|
||||||
|
#include "Game.h"
|
||||||
|
#include "UtilityClass.h"
|
||||||
|
|
||||||
|
void preloaderrender(Graphics& dwgfx, Game& game, UtilityClass& help);
|
||||||
|
|
||||||
|
#endif /* PRELOADER_H */
|
||||||
3096
desktop_version/src/titlerender.cpp
Normal file
3096
desktop_version/src/titlerender.cpp
Normal file
File diff suppressed because it is too large
Load Diff
35
desktop_version/src/titlerender.h
Normal file
35
desktop_version/src/titlerender.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef TITLERENDERER_H
|
||||||
|
#define TITLERENDERER_H
|
||||||
|
|
||||||
|
#include "Graphics.h"
|
||||||
|
#include "UtilityClass.h"
|
||||||
|
#include "Maths.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "Map.h"
|
||||||
|
#include "Script.h"
|
||||||
|
|
||||||
|
class Stage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int frameRate;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Stage stage;
|
||||||
|
extern Stage swfStage;
|
||||||
|
extern int temp;
|
||||||
|
|
||||||
|
void titlerender(Graphics& dwgfx, mapclass& map, Game& game, entityclass& obj, UtilityClass& help, musicclass& music);
|
||||||
|
|
||||||
|
void towerrender(Graphics& dwgfx, Game& game, mapclass& map, entityclass& obj, UtilityClass& help);
|
||||||
|
|
||||||
|
void gamerender(Graphics& dwgfx, mapclass& map, Game& game, entityclass& obj, UtilityClass& help);
|
||||||
|
|
||||||
|
void maprender(Graphics& dwgfx, Game& game, mapclass& map, entityclass& obj, UtilityClass& help);
|
||||||
|
|
||||||
|
void teleporterrender(Graphics& dwgfx, Game& game, mapclass& map, entityclass& obj, UtilityClass& help);
|
||||||
|
|
||||||
|
void gamecompleterender(Graphics& dwgfx, Game& game, entityclass& obj, UtilityClass& help, mapclass& map);
|
||||||
|
|
||||||
|
void gamecompleterender2(Graphics& dwgfx, Game& game, entityclass& obj, UtilityClass& help);
|
||||||
|
|
||||||
|
#endif /* TITLERENDERER_H */
|
||||||
530
desktop_version/tinyxml/readme.txt
Normal file
530
desktop_version/tinyxml/readme.txt
Normal file
@@ -0,0 +1,530 @@
|
|||||||
|
/** @mainpage
|
||||||
|
|
||||||
|
<h1> TinyXML </h1>
|
||||||
|
|
||||||
|
TinyXML is a simple, small, C++ XML parser that can be easily
|
||||||
|
integrated into other programs.
|
||||||
|
|
||||||
|
<h2> What it does. </h2>
|
||||||
|
|
||||||
|
In brief, TinyXML parses an XML document, and builds from that a
|
||||||
|
Document Object Model (DOM) that can be read, modified, and saved.
|
||||||
|
|
||||||
|
XML stands for "eXtensible Markup Language." It allows you to create
|
||||||
|
your own document markups. Where HTML does a very good job of marking
|
||||||
|
documents for browsers, XML allows you to define any kind of document
|
||||||
|
markup, for example a document that describes a "to do" list for an
|
||||||
|
organizer application. XML is a very structured and convenient format.
|
||||||
|
All those random file formats created to store application data can
|
||||||
|
all be replaced with XML. One parser for everything.
|
||||||
|
|
||||||
|
The best place for the complete, correct, and quite frankly hard to
|
||||||
|
read spec is at <a href="http://www.w3.org/TR/2004/REC-xml-20040204/">
|
||||||
|
http://www.w3.org/TR/2004/REC-xml-20040204/</a>. An intro to XML
|
||||||
|
(that I really like) can be found at
|
||||||
|
<a href="http://skew.org/xml/tutorial/">http://skew.org/xml/tutorial</a>.
|
||||||
|
|
||||||
|
There are different ways to access and interact with XML data.
|
||||||
|
TinyXML uses a Document Object Model (DOM), meaning the XML data is parsed
|
||||||
|
into a C++ objects that can be browsed and manipulated, and then
|
||||||
|
written to disk or another output stream. You can also construct an XML document
|
||||||
|
from scratch with C++ objects and write this to disk or another output
|
||||||
|
stream.
|
||||||
|
|
||||||
|
TinyXML is designed to be easy and fast to learn. It is two headers
|
||||||
|
and four cpp files. Simply add these to your project and off you go.
|
||||||
|
There is an example file - xmltest.cpp - to get you started.
|
||||||
|
|
||||||
|
TinyXML is released under the ZLib license,
|
||||||
|
so you can use it in open source or commercial code. The details
|
||||||
|
of the license are at the top of every source file.
|
||||||
|
|
||||||
|
TinyXML attempts to be a flexible parser, but with truly correct and
|
||||||
|
compliant XML output. TinyXML should compile on any reasonably C++
|
||||||
|
compliant system. It does not rely on exceptions or RTTI. It can be
|
||||||
|
compiled with or without STL support. TinyXML fully supports
|
||||||
|
the UTF-8 encoding, and the first 64k character entities.
|
||||||
|
|
||||||
|
|
||||||
|
<h2> What it doesn't do. </h2>
|
||||||
|
|
||||||
|
TinyXML doesn't parse or use DTDs (Document Type Definitions) or XSLs
|
||||||
|
(eXtensible Stylesheet Language.) There are other parsers out there
|
||||||
|
(check out www.sourceforge.org, search for XML) that are much more fully
|
||||||
|
featured. But they are also much bigger, take longer to set up in
|
||||||
|
your project, have a higher learning curve, and often have a more
|
||||||
|
restrictive license. If you are working with browsers or have more
|
||||||
|
complete XML needs, TinyXML is not the parser for you.
|
||||||
|
|
||||||
|
The following DTD syntax will not parse at this time in TinyXML:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
<!DOCTYPE Archiv [
|
||||||
|
<!ELEMENT Comment (#PCDATA)>
|
||||||
|
]>
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
because TinyXML sees this as a !DOCTYPE node with an illegally
|
||||||
|
embedded !ELEMENT node. This may be addressed in the future.
|
||||||
|
|
||||||
|
<h2> Tutorials. </h2>
|
||||||
|
|
||||||
|
For the impatient, here is a tutorial to get you going. A great way to get started,
|
||||||
|
but it is worth your time to read this (very short) manual completely.
|
||||||
|
|
||||||
|
- @subpage tutorial0
|
||||||
|
|
||||||
|
<h2> Code Status. </h2>
|
||||||
|
|
||||||
|
TinyXML is mature, tested code. It is very stable. If you find
|
||||||
|
bugs, please file a bug report on the sourceforge web site
|
||||||
|
(www.sourceforge.net/projects/tinyxml). We'll get them straightened
|
||||||
|
out as soon as possible.
|
||||||
|
|
||||||
|
There are some areas of improvement; please check sourceforge if you are
|
||||||
|
interested in working on TinyXML.
|
||||||
|
|
||||||
|
<h2> Related Projects </h2>
|
||||||
|
|
||||||
|
TinyXML projects you may find useful! (Descriptions provided by the projects.)
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li> <b>TinyXPath</b> (http://tinyxpath.sourceforge.net). TinyXPath is a small footprint
|
||||||
|
XPath syntax decoder, written in C++.</li>
|
||||||
|
<li> <b>TinyXML++</b> (http://code.google.com/p/ticpp/). TinyXML++ is a completely new
|
||||||
|
interface to TinyXML that uses MANY of the C++ strengths. Templates,
|
||||||
|
exceptions, and much better error handling.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2> Features </h2>
|
||||||
|
|
||||||
|
<h3> Using STL </h3>
|
||||||
|
|
||||||
|
TinyXML can be compiled to use or not use STL. When using STL, TinyXML
|
||||||
|
uses the std::string class, and fully supports std::istream, std::ostream,
|
||||||
|
operator<<, and operator>>. Many API methods have both 'const char*' and
|
||||||
|
'const std::string&' forms.
|
||||||
|
|
||||||
|
When STL support is compiled out, no STL files are included whatsoever. All
|
||||||
|
the string classes are implemented by TinyXML itself. API methods
|
||||||
|
all use the 'const char*' form for input.
|
||||||
|
|
||||||
|
Use the compile time #define:
|
||||||
|
|
||||||
|
TIXML_USE_STL
|
||||||
|
|
||||||
|
to compile one version or the other. This can be passed by the compiler,
|
||||||
|
or set as the first line of "tinyxml.h".
|
||||||
|
|
||||||
|
Note: If compiling the test code in Linux, setting the environment
|
||||||
|
variable TINYXML_USE_STL=YES/NO will control STL compilation. In the
|
||||||
|
Windows project file, STL and non STL targets are provided. In your project,
|
||||||
|
It's probably easiest to add the line "#define TIXML_USE_STL" as the first
|
||||||
|
line of tinyxml.h.
|
||||||
|
|
||||||
|
<h3> UTF-8 </h3>
|
||||||
|
|
||||||
|
TinyXML supports UTF-8 allowing to manipulate XML files in any language. TinyXML
|
||||||
|
also supports "legacy mode" - the encoding used before UTF-8 support and
|
||||||
|
probably best described as "extended ascii".
|
||||||
|
|
||||||
|
Normally, TinyXML will try to detect the correct encoding and use it. However,
|
||||||
|
by setting the value of TIXML_DEFAULT_ENCODING in the header file, TinyXML
|
||||||
|
can be forced to always use one encoding.
|
||||||
|
|
||||||
|
TinyXML will assume Legacy Mode until one of the following occurs:
|
||||||
|
<ol>
|
||||||
|
<li> If the non-standard but common "UTF-8 lead bytes" (0xef 0xbb 0xbf)
|
||||||
|
begin the file or data stream, TinyXML will read it as UTF-8. </li>
|
||||||
|
<li> If the declaration tag is read, and it has an encoding="UTF-8", then
|
||||||
|
TinyXML will read it as UTF-8. </li>
|
||||||
|
<li> If the declaration tag is read, and it has no encoding specified, then TinyXML will
|
||||||
|
read it as UTF-8. </li>
|
||||||
|
<li> If the declaration tag is read, and it has an encoding="something else", then TinyXML
|
||||||
|
will read it as Legacy Mode. In legacy mode, TinyXML will work as it did before. It's
|
||||||
|
not clear what that mode does exactly, but old content should keep working.</li>
|
||||||
|
<li> Until one of the above criteria is met, TinyXML runs in Legacy Mode.</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
What happens if the encoding is incorrectly set or detected? TinyXML will try
|
||||||
|
to read and pass through text seen as improperly encoded. You may get some strange results or
|
||||||
|
mangled characters. You may want to force TinyXML to the correct mode.
|
||||||
|
|
||||||
|
You may force TinyXML to Legacy Mode by using LoadFile( TIXML_ENCODING_LEGACY ) or
|
||||||
|
LoadFile( filename, TIXML_ENCODING_LEGACY ). You may force it to use legacy mode all
|
||||||
|
the time by setting TIXML_DEFAULT_ENCODING = TIXML_ENCODING_LEGACY. Likewise, you may
|
||||||
|
force it to TIXML_ENCODING_UTF8 with the same technique.
|
||||||
|
|
||||||
|
For English users, using English XML, UTF-8 is the same as low-ASCII. You
|
||||||
|
don't need to be aware of UTF-8 or change your code in any way. You can think
|
||||||
|
of UTF-8 as a "superset" of ASCII.
|
||||||
|
|
||||||
|
UTF-8 is not a double byte format - but it is a standard encoding of Unicode!
|
||||||
|
TinyXML does not use or directly support wchar, TCHAR, or Microsoft's _UNICODE at this time.
|
||||||
|
It is common to see the term "Unicode" improperly refer to UTF-16, a wide byte encoding
|
||||||
|
of unicode. This is a source of confusion.
|
||||||
|
|
||||||
|
For "high-ascii" languages - everything not English, pretty much - TinyXML can
|
||||||
|
handle all languages, at the same time, as long as the XML is encoded
|
||||||
|
in UTF-8. That can be a little tricky, older programs and operating systems
|
||||||
|
tend to use the "default" or "traditional" code page. Many apps (and almost all
|
||||||
|
modern ones) can output UTF-8, but older or stubborn (or just broken) ones
|
||||||
|
still output text in the default code page.
|
||||||
|
|
||||||
|
For example, Japanese systems traditionally use SHIFT-JIS encoding.
|
||||||
|
Text encoded as SHIFT-JIS can not be read by TinyXML.
|
||||||
|
A good text editor can import SHIFT-JIS and then save as UTF-8.
|
||||||
|
|
||||||
|
The <a href="http://skew.org/xml/tutorial/">Skew.org link</a> does a great
|
||||||
|
job covering the encoding issue.
|
||||||
|
|
||||||
|
The test file "utf8test.xml" is an XML containing English, Spanish, Russian,
|
||||||
|
and Simplified Chinese. (Hopefully they are translated correctly). The file
|
||||||
|
"utf8test.gif" is a screen capture of the XML file, rendered in IE. Note that
|
||||||
|
if you don't have the correct fonts (Simplified Chinese or Russian) on your
|
||||||
|
system, you won't see output that matches the GIF file even if you can parse
|
||||||
|
it correctly. Also note that (at least on my Windows machine) console output
|
||||||
|
is in a Western code page, so that Print() or printf() cannot correctly display
|
||||||
|
the file. This is not a bug in TinyXML - just an OS issue. No data is lost or
|
||||||
|
destroyed by TinyXML. The console just doesn't render UTF-8.
|
||||||
|
|
||||||
|
|
||||||
|
<h3> Entities </h3>
|
||||||
|
TinyXML recognizes the pre-defined "character entities", meaning special
|
||||||
|
characters. Namely:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
& &
|
||||||
|
< <
|
||||||
|
> >
|
||||||
|
" "
|
||||||
|
' '
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
These are recognized when the XML document is read, and translated to there
|
||||||
|
UTF-8 equivalents. For instance, text with the XML of:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
Far & Away
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
will have the Value() of "Far & Away" when queried from the TiXmlText object,
|
||||||
|
and will be written back to the XML stream/file as an ampersand. Older versions
|
||||||
|
of TinyXML "preserved" character entities, but the newer versions will translate
|
||||||
|
them into characters.
|
||||||
|
|
||||||
|
Additionally, any character can be specified by its Unicode code point:
|
||||||
|
The syntax " " or " " are both to the non-breaking space characher.
|
||||||
|
|
||||||
|
<h3> Printing </h3>
|
||||||
|
TinyXML can print output in several different ways that all have strengths and limitations.
|
||||||
|
|
||||||
|
- Print( FILE* ). Output to a std-C stream, which includes all C files as well as stdout.
|
||||||
|
- "Pretty prints", but you don't have control over printing options.
|
||||||
|
- The output is streamed directly to the FILE object, so there is no memory overhead
|
||||||
|
in the TinyXML code.
|
||||||
|
- used by Print() and SaveFile()
|
||||||
|
|
||||||
|
- operator<<. Output to a c++ stream.
|
||||||
|
- Integrates with standart C++ iostreams.
|
||||||
|
- Outputs in "network printing" mode without line breaks. Good for network transmission
|
||||||
|
and moving XML between C++ objects, but hard for a human to read.
|
||||||
|
|
||||||
|
- TiXmlPrinter. Output to a std::string or memory buffer.
|
||||||
|
- API is less concise
|
||||||
|
- Future printing options will be put here.
|
||||||
|
- Printing may change slightly in future versions as it is refined and expanded.
|
||||||
|
|
||||||
|
<h3> Streams </h3>
|
||||||
|
With TIXML_USE_STL on TinyXML supports C++ streams (operator <<,>>) streams as well
|
||||||
|
as C (FILE*) streams. There are some differences that you may need to be aware of.
|
||||||
|
|
||||||
|
C style output:
|
||||||
|
- based on FILE*
|
||||||
|
- the Print() and SaveFile() methods
|
||||||
|
|
||||||
|
Generates formatted output, with plenty of white space, intended to be as
|
||||||
|
human-readable as possible. They are very fast, and tolerant of ill formed
|
||||||
|
XML documents. For example, an XML document that contains 2 root elements
|
||||||
|
and 2 declarations, will still print.
|
||||||
|
|
||||||
|
C style input:
|
||||||
|
- based on FILE*
|
||||||
|
- the Parse() and LoadFile() methods
|
||||||
|
|
||||||
|
A fast, tolerant read. Use whenever you don't need the C++ streams.
|
||||||
|
|
||||||
|
C++ style output:
|
||||||
|
- based on std::ostream
|
||||||
|
- operator<<
|
||||||
|
|
||||||
|
Generates condensed output, intended for network transmission rather than
|
||||||
|
readability. Depending on your system's implementation of the ostream class,
|
||||||
|
these may be somewhat slower. (Or may not.) Not tolerant of ill formed XML:
|
||||||
|
a document should contain the correct one root element. Additional root level
|
||||||
|
elements will not be streamed out.
|
||||||
|
|
||||||
|
C++ style input:
|
||||||
|
- based on std::istream
|
||||||
|
- operator>>
|
||||||
|
|
||||||
|
Reads XML from a stream, making it useful for network transmission. The tricky
|
||||||
|
part is knowing when the XML document is complete, since there will almost
|
||||||
|
certainly be other data in the stream. TinyXML will assume the XML data is
|
||||||
|
complete after it reads the root element. Put another way, documents that
|
||||||
|
are ill-constructed with more than one root element will not read correctly.
|
||||||
|
Also note that operator>> is somewhat slower than Parse, due to both
|
||||||
|
implementation of the STL and limitations of TinyXML.
|
||||||
|
|
||||||
|
<h3> White space </h3>
|
||||||
|
The world simply does not agree on whether white space should be kept, or condensed.
|
||||||
|
For example, pretend the '_' is a space, and look at "Hello____world". HTML, and
|
||||||
|
at least some XML parsers, will interpret this as "Hello_world". They condense white
|
||||||
|
space. Some XML parsers do not, and will leave it as "Hello____world". (Remember
|
||||||
|
to keep pretending the _ is a space.) Others suggest that __Hello___world__ should become
|
||||||
|
Hello___world.
|
||||||
|
|
||||||
|
It's an issue that hasn't been resolved to my satisfaction. TinyXML supports the
|
||||||
|
first 2 approaches. Call TiXmlBase::SetCondenseWhiteSpace( bool ) to set the desired behavior.
|
||||||
|
The default is to condense white space.
|
||||||
|
|
||||||
|
If you change the default, you should call TiXmlBase::SetCondenseWhiteSpace( bool )
|
||||||
|
before making any calls to Parse XML data, and I don't recommend changing it after
|
||||||
|
it has been set.
|
||||||
|
|
||||||
|
|
||||||
|
<h3> Handles </h3>
|
||||||
|
|
||||||
|
Where browsing an XML document in a robust way, it is important to check
|
||||||
|
for null returns from method calls. An error safe implementation can
|
||||||
|
generate a lot of code like:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
TiXmlElement* root = document.FirstChildElement( "Document" );
|
||||||
|
if ( root )
|
||||||
|
{
|
||||||
|
TiXmlElement* element = root->FirstChildElement( "Element" );
|
||||||
|
if ( element )
|
||||||
|
{
|
||||||
|
TiXmlElement* child = element->FirstChildElement( "Child" );
|
||||||
|
if ( child )
|
||||||
|
{
|
||||||
|
TiXmlElement* child2 = child->NextSiblingElement( "Child" );
|
||||||
|
if ( child2 )
|
||||||
|
{
|
||||||
|
// Finally do something useful.
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
Handles have been introduced to clean this up. Using the TiXmlHandle class,
|
||||||
|
the previous code reduces to:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
TiXmlHandle docHandle( &document );
|
||||||
|
TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
|
||||||
|
if ( child2 )
|
||||||
|
{
|
||||||
|
// do something useful
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
Which is much easier to deal with. See TiXmlHandle for more information.
|
||||||
|
|
||||||
|
|
||||||
|
<h3> Row and Column tracking </h3>
|
||||||
|
Being able to track nodes and attributes back to their origin location
|
||||||
|
in source files can be very important for some applications. Additionally,
|
||||||
|
knowing where parsing errors occured in the original source can be very
|
||||||
|
time saving.
|
||||||
|
|
||||||
|
TinyXML can tracks the row and column origin of all nodes and attributes
|
||||||
|
in a text file. The TiXmlBase::Row() and TiXmlBase::Column() methods return
|
||||||
|
the origin of the node in the source text. The correct tabs can be
|
||||||
|
configured in TiXmlDocument::SetTabSize().
|
||||||
|
|
||||||
|
|
||||||
|
<h2> Using and Installing </h2>
|
||||||
|
|
||||||
|
To Compile and Run xmltest:
|
||||||
|
|
||||||
|
A Linux Makefile and a Windows Visual C++ .dsw file is provided.
|
||||||
|
Simply compile and run. It will write the file demotest.xml to your
|
||||||
|
disk and generate output on the screen. It also tests walking the
|
||||||
|
DOM by printing out the number of nodes found using different
|
||||||
|
techniques.
|
||||||
|
|
||||||
|
The Linux makefile is very generic and runs on many systems - it
|
||||||
|
is currently tested on mingw and
|
||||||
|
MacOSX. You do not need to run 'make depend'. The dependecies have been
|
||||||
|
hard coded.
|
||||||
|
|
||||||
|
<h3>Windows project file for VC6</h3>
|
||||||
|
<ul>
|
||||||
|
<li>tinyxml: tinyxml library, non-STL </li>
|
||||||
|
<li>tinyxmlSTL: tinyxml library, STL </li>
|
||||||
|
<li>tinyXmlTest: test app, non-STL </li>
|
||||||
|
<li>tinyXmlTestSTL: test app, STL </li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h3>Makefile</h3>
|
||||||
|
At the top of the makefile you can set:
|
||||||
|
|
||||||
|
PROFILE, DEBUG, and TINYXML_USE_STL. Details (such that they are) are in
|
||||||
|
the makefile.
|
||||||
|
|
||||||
|
In the tinyxml directory, type "make clean" then "make". The executable
|
||||||
|
file 'xmltest' will be created.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h3>To Use in an Application:</h3>
|
||||||
|
|
||||||
|
Add tinyxml.cpp, tinyxml.h, tinyxmlerror.cpp, tinyxmlparser.cpp, tinystr.cpp, and tinystr.h to your
|
||||||
|
project or make file. That's it! It should compile on any reasonably
|
||||||
|
compliant C++ system. You do not need to enable exceptions or
|
||||||
|
RTTI for TinyXML.
|
||||||
|
|
||||||
|
|
||||||
|
<h2> How TinyXML works. </h2>
|
||||||
|
|
||||||
|
An example is probably the best way to go. Take:
|
||||||
|
@verbatim
|
||||||
|
<?xml version="1.0" standalone=no>
|
||||||
|
<!-- Our to do list data -->
|
||||||
|
<ToDo>
|
||||||
|
<Item priority="1"> Go to the <bold>Toy store!</bold></Item>
|
||||||
|
<Item priority="2"> Do bills</Item>
|
||||||
|
</ToDo>
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
Its not much of a To Do list, but it will do. To read this file
|
||||||
|
(say "demo.xml") you would create a document, and parse it in:
|
||||||
|
@verbatim
|
||||||
|
TiXmlDocument doc( "demo.xml" );
|
||||||
|
doc.LoadFile();
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
And its ready to go. Now lets look at some lines and how they
|
||||||
|
relate to the DOM.
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
<?xml version="1.0" standalone=no>
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
The first line is a declaration, and gets turned into the
|
||||||
|
TiXmlDeclaration class. It will be the first child of the
|
||||||
|
document node.
|
||||||
|
|
||||||
|
This is the only directive/special tag parsed by TinyXML.
|
||||||
|
Generally directive tags are stored in TiXmlUnknown so the
|
||||||
|
commands wont be lost when it is saved back to disk.
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
<!-- Our to do list data -->
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
A comment. Will become a TiXmlComment object.
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
<ToDo>
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
The "ToDo" tag defines a TiXmlElement object. This one does not have
|
||||||
|
any attributes, but does contain 2 other elements.
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
<Item priority="1">
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
Creates another TiXmlElement which is a child of the "ToDo" element.
|
||||||
|
This element has 1 attribute, with the name "priority" and the value
|
||||||
|
"1".
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
Go to the
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
A TiXmlText. This is a leaf node and cannot contain other nodes.
|
||||||
|
It is a child of the "Item" TiXmlElement.
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
<bold>
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
|
||||||
|
Another TiXmlElement, this one a child of the "Item" element.
|
||||||
|
|
||||||
|
Etc.
|
||||||
|
|
||||||
|
Looking at the entire object tree, you end up with:
|
||||||
|
@verbatim
|
||||||
|
TiXmlDocument "demo.xml"
|
||||||
|
TiXmlDeclaration "version='1.0'" "standalone=no"
|
||||||
|
TiXmlComment " Our to do list data"
|
||||||
|
TiXmlElement "ToDo"
|
||||||
|
TiXmlElement "Item" Attribtutes: priority = 1
|
||||||
|
TiXmlText "Go to the "
|
||||||
|
TiXmlElement "bold"
|
||||||
|
TiXmlText "Toy store!"
|
||||||
|
TiXmlElement "Item" Attributes: priority=2
|
||||||
|
TiXmlText "Do bills"
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
<h2> Documentation </h2>
|
||||||
|
|
||||||
|
The documentation is build with Doxygen, using the 'dox'
|
||||||
|
configuration file.
|
||||||
|
|
||||||
|
<h2> License </h2>
|
||||||
|
|
||||||
|
TinyXML is released under the zlib license:
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any
|
||||||
|
damages arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any
|
||||||
|
purpose, including commercial applications, and to alter it and
|
||||||
|
redistribute it freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must
|
||||||
|
not claim that you wrote the original software. If you use this
|
||||||
|
software in a product, an acknowledgment in the product documentation
|
||||||
|
would be appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and
|
||||||
|
must not be misrepresented as being the original software.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
<h2> References </h2>
|
||||||
|
|
||||||
|
The World Wide Web Consortium is the definitive standard body for
|
||||||
|
XML, and their web pages contain huge amounts of information.
|
||||||
|
|
||||||
|
The definitive spec: <a href="http://www.w3.org/TR/2004/REC-xml-20040204/">
|
||||||
|
http://www.w3.org/TR/2004/REC-xml-20040204/</a>
|
||||||
|
|
||||||
|
I also recommend "XML Pocket Reference" by Robert Eckstein and published by
|
||||||
|
OReilly...the book that got the whole thing started.
|
||||||
|
|
||||||
|
<h2> Contributors, Contacts, and a Brief History </h2>
|
||||||
|
|
||||||
|
Thanks very much to everyone who sends suggestions, bugs, ideas, and
|
||||||
|
encouragement. It all helps, and makes this project fun. A special thanks
|
||||||
|
to the contributors on the web pages that keep it lively.
|
||||||
|
|
||||||
|
So many people have sent in bugs and ideas, that rather than list here
|
||||||
|
we try to give credit due in the "changes.txt" file.
|
||||||
|
|
||||||
|
TinyXML was originally written by Lee Thomason. (Often the "I" still
|
||||||
|
in the documentation.) Lee reviews changes and releases new versions,
|
||||||
|
with the help of Yves Berquin, Andrew Ellerton, and the tinyXml community.
|
||||||
|
|
||||||
|
We appreciate your suggestions, and would love to know if you
|
||||||
|
use TinyXML. Hopefully you will enjoy it and find it useful.
|
||||||
|
Please post questions, comments, file bugs, or contact us at:
|
||||||
|
|
||||||
|
www.sourceforge.net/projects/tinyxml
|
||||||
|
|
||||||
|
Lee Thomason, Yves Berquin, Andrew Ellerton
|
||||||
|
*/
|
||||||
111
desktop_version/tinyxml/tinystr.cpp
Normal file
111
desktop_version/tinyxml/tinystr.cpp
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
www.sourceforge.net/projects/tinyxml
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any
|
||||||
|
damages arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any
|
||||||
|
purpose, including commercial applications, and to alter it and
|
||||||
|
redistribute it freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must
|
||||||
|
not claim that you wrote the original software. If you use this
|
||||||
|
software in a product, an acknowledgment in the product documentation
|
||||||
|
would be appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and
|
||||||
|
must not be misrepresented as being the original software.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source
|
||||||
|
distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TIXML_USE_STL
|
||||||
|
|
||||||
|
#include "tinystr.h"
|
||||||
|
|
||||||
|
// Error value for find primitive
|
||||||
|
const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
|
||||||
|
|
||||||
|
|
||||||
|
// Null rep.
|
||||||
|
TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } };
|
||||||
|
|
||||||
|
|
||||||
|
void TiXmlString::reserve (size_type cap)
|
||||||
|
{
|
||||||
|
if (cap > capacity())
|
||||||
|
{
|
||||||
|
TiXmlString tmp;
|
||||||
|
tmp.init(length(), cap);
|
||||||
|
memcpy(tmp.start(), data(), length());
|
||||||
|
swap(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TiXmlString& TiXmlString::assign(const char* str, size_type len)
|
||||||
|
{
|
||||||
|
size_type cap = capacity();
|
||||||
|
if (len > cap || cap > 3*(len + 8))
|
||||||
|
{
|
||||||
|
TiXmlString tmp;
|
||||||
|
tmp.init(len);
|
||||||
|
memcpy(tmp.start(), str, len);
|
||||||
|
swap(tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memmove(start(), str, len);
|
||||||
|
set_size(len);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TiXmlString& TiXmlString::append(const char* str, size_type len)
|
||||||
|
{
|
||||||
|
size_type newsize = length() + len;
|
||||||
|
if (newsize > capacity())
|
||||||
|
{
|
||||||
|
reserve (newsize + capacity());
|
||||||
|
}
|
||||||
|
memmove(finish(), str, len);
|
||||||
|
set_size(newsize);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
|
||||||
|
{
|
||||||
|
TiXmlString tmp;
|
||||||
|
tmp.reserve(a.length() + b.length());
|
||||||
|
tmp += a;
|
||||||
|
tmp += b;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
TiXmlString operator + (const TiXmlString & a, const char* b)
|
||||||
|
{
|
||||||
|
TiXmlString tmp;
|
||||||
|
TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
|
||||||
|
tmp.reserve(a.length() + b_len);
|
||||||
|
tmp += a;
|
||||||
|
tmp.append(b, b_len);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
TiXmlString operator + (const char* a, const TiXmlString & b)
|
||||||
|
{
|
||||||
|
TiXmlString tmp;
|
||||||
|
TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
|
||||||
|
tmp.reserve(a_len + b.length());
|
||||||
|
tmp.append(a, a_len);
|
||||||
|
tmp += b;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // TIXML_USE_STL
|
||||||
305
desktop_version/tinyxml/tinystr.h
Normal file
305
desktop_version/tinyxml/tinystr.h
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
/*
|
||||||
|
www.sourceforge.net/projects/tinyxml
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any
|
||||||
|
damages arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any
|
||||||
|
purpose, including commercial applications, and to alter it and
|
||||||
|
redistribute it freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must
|
||||||
|
not claim that you wrote the original software. If you use this
|
||||||
|
software in a product, an acknowledgment in the product documentation
|
||||||
|
would be appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and
|
||||||
|
must not be misrepresented as being the original software.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source
|
||||||
|
distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TIXML_USE_STL
|
||||||
|
|
||||||
|
#ifndef TIXML_STRING_INCLUDED
|
||||||
|
#define TIXML_STRING_INCLUDED
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* The support for explicit isn't that universal, and it isn't really
|
||||||
|
required - it is used to check that the TiXmlString class isn't incorrectly
|
||||||
|
used. Be nice to old compilers and macro it here:
|
||||||
|
*/
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
|
||||||
|
// Microsoft visual studio, version 6 and higher.
|
||||||
|
#define TIXML_EXPLICIT explicit
|
||||||
|
#elif defined(__GNUC__) && (__GNUC__ >= 3 )
|
||||||
|
// GCC version 3 and higher.s
|
||||||
|
#define TIXML_EXPLICIT explicit
|
||||||
|
#else
|
||||||
|
#define TIXML_EXPLICIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
TiXmlString is an emulation of a subset of the std::string template.
|
||||||
|
Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
|
||||||
|
Only the member functions relevant to the TinyXML project have been implemented.
|
||||||
|
The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
|
||||||
|
a string and there's no more room, we allocate a buffer twice as big as we need.
|
||||||
|
*/
|
||||||
|
class TiXmlString
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
// The size type used
|
||||||
|
typedef size_t size_type;
|
||||||
|
|
||||||
|
// Error value for find primitive
|
||||||
|
static const size_type npos; // = -1;
|
||||||
|
|
||||||
|
|
||||||
|
// TiXmlString empty constructor
|
||||||
|
TiXmlString () : rep_(&nullrep_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// TiXmlString copy constructor
|
||||||
|
TiXmlString ( const TiXmlString & copy) : rep_(0)
|
||||||
|
{
|
||||||
|
init(copy.length());
|
||||||
|
memcpy(start(), copy.data(), length());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TiXmlString constructor, based on a string
|
||||||
|
TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
|
||||||
|
{
|
||||||
|
init( static_cast<size_type>( strlen(copy) ));
|
||||||
|
memcpy(start(), copy, length());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TiXmlString constructor, based on a string
|
||||||
|
TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
|
||||||
|
{
|
||||||
|
init(len);
|
||||||
|
memcpy(start(), str, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TiXmlString destructor
|
||||||
|
~TiXmlString ()
|
||||||
|
{
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
TiXmlString& operator = (const char * copy)
|
||||||
|
{
|
||||||
|
return assign( copy, (size_type)strlen(copy));
|
||||||
|
}
|
||||||
|
|
||||||
|
TiXmlString& operator = (const TiXmlString & copy)
|
||||||
|
{
|
||||||
|
return assign(copy.start(), copy.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// += operator. Maps to append
|
||||||
|
TiXmlString& operator += (const char * suffix)
|
||||||
|
{
|
||||||
|
return append(suffix, static_cast<size_type>( strlen(suffix) ));
|
||||||
|
}
|
||||||
|
|
||||||
|
// += operator. Maps to append
|
||||||
|
TiXmlString& operator += (char single)
|
||||||
|
{
|
||||||
|
return append(&single, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// += operator. Maps to append
|
||||||
|
TiXmlString& operator += (const TiXmlString & suffix)
|
||||||
|
{
|
||||||
|
return append(suffix.data(), suffix.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Convert a TiXmlString into a null-terminated char *
|
||||||
|
const char * c_str () const { return rep_->str; }
|
||||||
|
|
||||||
|
// Convert a TiXmlString into a char * (need not be null terminated).
|
||||||
|
const char * data () const { return rep_->str; }
|
||||||
|
|
||||||
|
// Return the length of a TiXmlString
|
||||||
|
size_type length () const { return rep_->size; }
|
||||||
|
|
||||||
|
// Alias for length()
|
||||||
|
size_type size () const { return rep_->size; }
|
||||||
|
|
||||||
|
// Checks if a TiXmlString is empty
|
||||||
|
bool empty () const { return rep_->size == 0; }
|
||||||
|
|
||||||
|
// Return capacity of string
|
||||||
|
size_type capacity () const { return rep_->capacity; }
|
||||||
|
|
||||||
|
|
||||||
|
// single char extraction
|
||||||
|
const char& at (size_type index) const
|
||||||
|
{
|
||||||
|
assert( index < length() );
|
||||||
|
return rep_->str[ index ];
|
||||||
|
}
|
||||||
|
|
||||||
|
// [] operator
|
||||||
|
char& operator [] (size_type index) const
|
||||||
|
{
|
||||||
|
assert( index < length() );
|
||||||
|
return rep_->str[ index ];
|
||||||
|
}
|
||||||
|
|
||||||
|
// find a char in a string. Return TiXmlString::npos if not found
|
||||||
|
size_type find (char lookup) const
|
||||||
|
{
|
||||||
|
return find(lookup, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// find a char in a string from an offset. Return TiXmlString::npos if not found
|
||||||
|
size_type find (char tofind, size_type offset) const
|
||||||
|
{
|
||||||
|
if (offset >= length()) return npos;
|
||||||
|
|
||||||
|
for (const char* p = c_str() + offset; *p != '\0'; ++p)
|
||||||
|
{
|
||||||
|
if (*p == tofind) return static_cast< size_type >( p - c_str() );
|
||||||
|
}
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear ()
|
||||||
|
{
|
||||||
|
//Lee:
|
||||||
|
//The original was just too strange, though correct:
|
||||||
|
// TiXmlString().swap(*this);
|
||||||
|
//Instead use the quit & re-init:
|
||||||
|
quit();
|
||||||
|
init(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function to reserve a big amount of data when we know we'll need it. Be aware that this
|
||||||
|
function DOES NOT clear the content of the TiXmlString if any exists.
|
||||||
|
*/
|
||||||
|
void reserve (size_type cap);
|
||||||
|
|
||||||
|
TiXmlString& assign (const char* str, size_type len);
|
||||||
|
|
||||||
|
TiXmlString& append (const char* str, size_type len);
|
||||||
|
|
||||||
|
void swap (TiXmlString& other)
|
||||||
|
{
|
||||||
|
Rep* r = rep_;
|
||||||
|
rep_ = other.rep_;
|
||||||
|
other.rep_ = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void init(size_type sz) { init(sz, sz); }
|
||||||
|
void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
|
||||||
|
char* start() const { return rep_->str; }
|
||||||
|
char* finish() const { return rep_->str + rep_->size; }
|
||||||
|
|
||||||
|
struct Rep
|
||||||
|
{
|
||||||
|
size_type size, capacity;
|
||||||
|
char str[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
void init(size_type sz, size_type cap)
|
||||||
|
{
|
||||||
|
if (cap)
|
||||||
|
{
|
||||||
|
// Lee: the original form:
|
||||||
|
// rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
|
||||||
|
// doesn't work in some cases of new being overloaded. Switching
|
||||||
|
// to the normal allocation, although use an 'int' for systems
|
||||||
|
// that are overly picky about structure alignment.
|
||||||
|
const size_type bytesNeeded = sizeof(Rep) + cap;
|
||||||
|
const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int );
|
||||||
|
rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
|
||||||
|
|
||||||
|
rep_->str[ rep_->size = sz ] = '\0';
|
||||||
|
rep_->capacity = cap;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rep_ = &nullrep_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void quit()
|
||||||
|
{
|
||||||
|
if (rep_ != &nullrep_)
|
||||||
|
{
|
||||||
|
// The rep_ is really an array of ints. (see the allocator, above).
|
||||||
|
// Cast it back before delete, so the compiler won't incorrectly call destructors.
|
||||||
|
delete [] ( reinterpret_cast<int*>( rep_ ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rep * rep_;
|
||||||
|
static Rep nullrep_;
|
||||||
|
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
inline bool operator == (const TiXmlString & a, const TiXmlString & b)
|
||||||
|
{
|
||||||
|
return ( a.length() == b.length() ) // optimization on some platforms
|
||||||
|
&& ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare
|
||||||
|
}
|
||||||
|
inline bool operator < (const TiXmlString & a, const TiXmlString & b)
|
||||||
|
{
|
||||||
|
return strcmp(a.c_str(), b.c_str()) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
|
||||||
|
inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; }
|
||||||
|
inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
|
||||||
|
inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
|
||||||
|
|
||||||
|
inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
|
||||||
|
inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
|
||||||
|
inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
|
||||||
|
inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
|
||||||
|
|
||||||
|
TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
|
||||||
|
TiXmlString operator + (const TiXmlString & a, const char* b);
|
||||||
|
TiXmlString operator + (const char* a, const TiXmlString & b);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
|
||||||
|
Only the operators that we need for TinyXML have been developped.
|
||||||
|
*/
|
||||||
|
class TiXmlOutStream : public TiXmlString
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
// TiXmlOutStream << operator.
|
||||||
|
TiXmlOutStream & operator << (const TiXmlString & in)
|
||||||
|
{
|
||||||
|
*this += in;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TiXmlOutStream << operator.
|
||||||
|
TiXmlOutStream & operator << (const char * in)
|
||||||
|
{
|
||||||
|
*this += in;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#endif // TIXML_STRING_INCLUDED
|
||||||
|
#endif // TIXML_USE_STL
|
||||||
1886
desktop_version/tinyxml/tinyxml.cpp
Normal file
1886
desktop_version/tinyxml/tinyxml.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1805
desktop_version/tinyxml/tinyxml.h
Normal file
1805
desktop_version/tinyxml/tinyxml.h
Normal file
File diff suppressed because it is too large
Load Diff
52
desktop_version/tinyxml/tinyxmlerror.cpp
Normal file
52
desktop_version/tinyxml/tinyxmlerror.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
www.sourceforge.net/projects/tinyxml
|
||||||
|
Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any
|
||||||
|
damages arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any
|
||||||
|
purpose, including commercial applications, and to alter it and
|
||||||
|
redistribute it freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must
|
||||||
|
not claim that you wrote the original software. If you use this
|
||||||
|
software in a product, an acknowledgment in the product documentation
|
||||||
|
would be appreciated but is not required.
|
||||||
|
|
||||||
|
2. Altered source versions must be plainly marked as such, and
|
||||||
|
must not be misrepresented as being the original software.
|
||||||
|
|
||||||
|
3. This notice may not be removed or altered from any source
|
||||||
|
distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tinyxml.h"
|
||||||
|
|
||||||
|
// The goal of the seperate error file is to make the first
|
||||||
|
// step towards localization. tinyxml (currently) only supports
|
||||||
|
// english error messages, but the could now be translated.
|
||||||
|
//
|
||||||
|
// It also cleans up the code a bit.
|
||||||
|
//
|
||||||
|
|
||||||
|
const char* TiXmlBase::errorString[ TiXmlBase::TIXML_ERROR_STRING_COUNT ] =
|
||||||
|
{
|
||||||
|
"No error",
|
||||||
|
"Error",
|
||||||
|
"Failed to open file",
|
||||||
|
"Error parsing Element.",
|
||||||
|
"Failed to read Element name",
|
||||||
|
"Error reading Element value.",
|
||||||
|
"Error reading Attributes.",
|
||||||
|
"Error: empty tag.",
|
||||||
|
"Error reading end tag.",
|
||||||
|
"Error parsing Unknown.",
|
||||||
|
"Error parsing Comment.",
|
||||||
|
"Error parsing Declaration.",
|
||||||
|
"Error document empty.",
|
||||||
|
"Error null (0) or unexpected EOF found in input stream.",
|
||||||
|
"Error parsing CDATA.",
|
||||||
|
"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
|
||||||
|
};
|
||||||
1638
desktop_version/tinyxml/tinyxmlparser.cpp
Normal file
1638
desktop_version/tinyxml/tinyxmlparser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
73
mobile_version/application.xml
Normal file
73
mobile_version/application.xml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<application xmlns="http://ns.adobe.com/air/application/25.0">
|
||||||
|
<id>com.distractionware.vvvvvvmobile</id>
|
||||||
|
<versionNumber>1.02</versionNumber>
|
||||||
|
<supportedProfiles>mobileDevice</supportedProfiles>
|
||||||
|
<filename>VVVVVV</filename>
|
||||||
|
<name>VVVVVV</name>
|
||||||
|
<android>
|
||||||
|
<manifestAdditions><![CDATA[<manifest android:installLocation="auto">
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-feature android:required="true" android:name="android.hardware.touchscreen.multitouch" />
|
||||||
|
</manifest>]]></manifestAdditions>
|
||||||
|
</android>
|
||||||
|
<iPhone>
|
||||||
|
<InfoAdditions><![CDATA[<key>UIStatusBarStyle</key>
|
||||||
|
<string>UIStatusBarStyleBlackOpaque</string>
|
||||||
|
<key>UIRequiresPersistentWiFi</key>
|
||||||
|
<string>NO</string>
|
||||||
|
<key>UIPrerenderedIcon</key>
|
||||||
|
<true />
|
||||||
|
<key>UIApplicationExitsOnSuspend</key>
|
||||||
|
<false />
|
||||||
|
<key>UIDeviceFamily</key>
|
||||||
|
<array>
|
||||||
|
<!-- iPhone support -->
|
||||||
|
<string>1</string>
|
||||||
|
<!-- iPad support -->
|
||||||
|
<string>2</string>
|
||||||
|
</array>]]></InfoAdditions>
|
||||||
|
<requestedDisplayResolution>standard</requestedDisplayResolution>
|
||||||
|
</iPhone>
|
||||||
|
<initialWindow>
|
||||||
|
<title>VVVVVV</title>
|
||||||
|
<content>vvvvvv.swf</content>
|
||||||
|
<visible>true</visible>
|
||||||
|
<aspectRatio>landscape</aspectRatio>
|
||||||
|
<renderMode>gpu</renderMode>
|
||||||
|
<systemChrome>standard</systemChrome>
|
||||||
|
<autoOrients>true</autoOrients>
|
||||||
|
<fullScreen>true</fullScreen>
|
||||||
|
</initialWindow>
|
||||||
|
<icon>
|
||||||
|
<image48x48>icons/icon_48.png</image48x48>
|
||||||
|
<image57x57>icons/icon_57.png</image57x57>
|
||||||
|
<image72x72>icons/icon_72.png</image72x72>
|
||||||
|
<image76x76>icons/icon_76.png</image76x76>
|
||||||
|
<image96x96>icons/icon_96.png</image96x96>
|
||||||
|
<image114x114>icons/icon_114.png</image114x114>
|
||||||
|
<image120x120>icons/icon_120.png</image120x120>
|
||||||
|
<image144x144>icons/icon_144.png</image144x144>
|
||||||
|
<image152x152>icons/icon_152.png</image152x152>
|
||||||
|
<image512x512>icons/icon_512.png</image512x512>
|
||||||
|
<image1024x1024>icons/icon_1024.png</image1024x1024>
|
||||||
|
</icon>
|
||||||
|
<!--
|
||||||
|
AIR options:
|
||||||
|
http://livedocs.adobe.com/flex/3/html/File_formats_1.html#1043413
|
||||||
|
|
||||||
|
AIR mobile options:
|
||||||
|
http://help.adobe.com/en_US/air/build/WSfffb011ac560372f-5d0f4f25128cc9cd0cb-7ffe.html
|
||||||
|
|
||||||
|
Android manifest documentation:
|
||||||
|
http://developer.android.com/guide/topics/manifest/manifest-intro.html
|
||||||
|
-->
|
||||||
|
<extensions>
|
||||||
|
<extensionID>com.milkmangames.extensions.GameCenter</extensionID>
|
||||||
|
<!--
|
||||||
|
<extensionID>com.sticksports.nativeExtensions.SilentSwitch</extensionID>
|
||||||
|
<extensionID>com.mesmotronic.ane.fullscreen</extensionID>
|
||||||
|
-->
|
||||||
|
</extensions>
|
||||||
|
</application>
|
||||||
7792
mobile_version/levels/eurogamer fork/eurogamerotherlevelclass.as
Normal file
7792
mobile_version/levels/eurogamer fork/eurogamerotherlevelclass.as
Normal file
File diff suppressed because it is too large
Load Diff
2300
mobile_version/levels/finalclass.as
Normal file
2300
mobile_version/levels/finalclass.as
Normal file
File diff suppressed because it is too large
Load Diff
1864
mobile_version/levels/labclass.as
Normal file
1864
mobile_version/levels/labclass.as
Normal file
File diff suppressed because it is too large
Load Diff
75
mobile_version/levels/newgameclass.as
Normal file
75
mobile_version/levels/newgameclass.as
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
package {
|
||||||
|
import flash.display.*;
|
||||||
|
import flash.geom.*;
|
||||||
|
import flash.events.*;
|
||||||
|
import flash.net.*;
|
||||||
|
|
||||||
|
public class newgameclass {
|
||||||
|
public function newgameclass():void {
|
||||||
|
tmap.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function changemapsize(xw:int, yh:int):void {
|
||||||
|
mapwidth = xw; mapheight = yh;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadlevel(t:String, obj:entityclass, music:musicclass):void {
|
||||||
|
if(t=="newgame_enter"){
|
||||||
|
changemapsize(40,30);
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,2,1,1,1,2,1,1,2,1,2,1,2,2,2,2,1,1,1,1,1,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,1,1,1,2,2,1,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
|
||||||
|
obj.createdoor(8, 12, "newgame_room2", 4, 10);
|
||||||
|
}else if(t=="newgame_room2"){
|
||||||
|
changemapsize(20,15);
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
tmap.push("2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2");
|
||||||
|
|
||||||
|
obj.createdoor(16, 12, "newgame_enter", 7, 22);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var mapwidth:int, mapheight:int;
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user