- initial support for configure based on scummvm tree (tested mac os x leopard, linux(ubuntu), cygwin with mingwin gcc)

- adopted more common dir code from scummvm for easier multi platform support
- synced some changes from scummvm code
This commit is contained in:
Pawel Kolodziejski 2008-06-12 12:08:15 +00:00
parent 3ce0bfb836
commit 407aee486d
95 changed files with 8389 additions and 818 deletions

340
COPYING.GPL Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -1,11 +1,71 @@
CXX = g++
CC = gcc
AR = ar rcu
CXXFLAGS = -g -W -Wall `sdl-config --cflags` -I. -DUNIX -Wno-multichar -Wno-unknown-pragmas -Wno-unused-parameter # -O2
LDFLAGS = -g -W -Wall
LIBS = `sdl-config --libs` -lz
# $URL$
# $Id$
# Comment this out for Mac OS X ...
LIBS += -lGL -lGLU
#######################################################################
# Default compilation parameters. Normally don't edit these #
#######################################################################
include Makefile.common
srcdir ?= .
DEFINES := -DHAVE_CONFIG_H
LDFLAGS :=
INCLUDES := -I. -I$(srcdir)
LIBS :=
OBJS :=
DEPDIR := .deps
MODULES :=
MODULE_DIRS :=
# Load the make rules generated by configure
-include config.mk
CXXFLAGS:= -Wall $(CXXFLAGS)
# Turn off some annoying and not-so-useful warnings
CXXFLAGS+= -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder -Wno-unused-parameter
# Enable even more warnings...
#CXXFLAGS+= -pedantic -Wpointer-arith -Wcast-qual -Wcast-align
#CXXFLAGS+= -Wimplicit -Wundef -Wnon-virtual-dtor -Wwrite-strings
# Disable RTTI and exceptions, and enabled checking of pointers returned by "new"
#CXXFLAGS+= -fno-rtti -fno-exceptions -fcheck-new
# There is a nice extra warning that flags variables that are potentially
# used before being initialized. Very handy to catch a certain kind of
# bugs. Unfortunately, it only works when optimizations are turned on,
# which is why we normally don't use it.
#CXXFLAGS+= -O -Wuninitialized
#######################################################################
# Default commands - put the necessary replacements in config.mk #
#######################################################################
CAT ?= cat
CP ?= cp
ECHO ?= printf
INSTALL ?= install
MKDIR ?= mkdir -p
RM ?= rm -f
RM_REC ?= $(RM) -r
ZIP ?= zip -q
#######################################################################
# Misc stuff - you should never have to edit this #
#######################################################################
EXECUTABLE := residual$(EXEEXT)
include $(srcdir)/Makefile.common
# check if configure has been run or has been changed since last run
config.h config.mk: $(srcdir)/configure
ifeq "$(findstring config.mk,$(MAKEFILE_LIST))" "config.mk"
@echo "Running $(srcdir)/configure with the last specified parameters"
@sleep 2s
LDFLAGS="$(SAVED_LDFLAGS)" CXX="$(SAVED_CXX)" CXXFLAGS="$(SAVED_CXXFLAGS)" CPPFLAGS="$(SAVED_CPPFLAGS)" \
$(srcdir)/configure $(SAVED_CONFIGFLAGS)
else
$(error You need to run $(srcdir)/configure before you can run make. Check $(srcdir)/configure --help for a list of parameters)
endif
include $(srcdir)/ports.mk

View File

@ -1,110 +1,126 @@
OBJS =\
common/debug.o \
common/matrix3.o \
common/matrix4.o \
common/mutex.o \
mixer/audiostream.o \
mixer/mixer.o \
mixer/rate.o \
engine/lua/lapi.o \
engine/lua/lauxlib.o \
engine/lua/lbuffer.o \
engine/lua/lbuiltin.o \
engine/lua/ldo.o \
engine/lua/lfunc.o \
engine/lua/lgc.o \
engine/lua/liolib.o \
engine/lua/llex.o \
engine/lua/lmathlib.o \
engine/lua/lmem.o \
engine/lua/lobject.o \
engine/lua/lparser.o \
engine/lua/lrestore.o \
engine/lua/lsave.o \
engine/lua/lstate.o \
engine/lua/lstring.o \
engine/lua/lstrlib.o \
engine/lua/ltable.o \
engine/lua/ltask.o \
engine/lua/ltm.o \
engine/lua/lundump.o \
engine/lua/lvm.o \
engine/lua/lzio.o \
engine/imuse/imuse.o \
engine/imuse/imuse_mcmp_mgr.o \
engine/imuse/imuse_music.o \
engine/imuse/imuse_script.o \
engine/imuse/imuse_sndmgr.o \
engine/imuse/imuse_tables.o \
engine/imuse/imuse_track.o \
engine/smush/blocky16.o \
engine/smush/smush.o \
engine/smush/vima.o \
engine/actor.o \
engine/bitmap.o \
engine/costume.o \
engine/engine.o \
engine/savegame.o \
engine/font.o \
engine/keyframe.o \
engine/lab.o \
engine/lipsynch.o \
engine/localize.o \
engine/lua.o \
engine/main.o \
engine/material.o \
engine/model.o \
engine/objectstate.o \
engine/primitives.o \
engine/registry.o \
engine/resource.o \
engine/scene.o \
engine/textobject.o \
engine/textsplit.o \
engine/walkplane.o \
$(DRIVER_OBJS)
# This file is used by Makefile and declares common build rules,
# a list of common object files etc.
#
# $URL$
# $Id$
DRIVER_OBJS ?=\
engine/backend/default-timer.o \
engine/backend/sdl/driver_sdl.o \
engine/backend/sdl/driver_gl.o \
engine/backend/sdl/driver_tinygl.o \
$(TINYGL_OBJS)
######################################################################
# The default build target: just build the scummvm executable
######################################################################
TINYGL_OBJS =\
engine/tinygl/api.o \
engine/tinygl/arrays.o \
engine/tinygl/clear.o \
engine/tinygl/clip.o \
engine/tinygl/error.o \
engine/tinygl/get.o \
engine/tinygl/image_util.o \
engine/tinygl/init.o \
engine/tinygl/light.o \
engine/tinygl/list.o \
engine/tinygl/matrix.o \
engine/tinygl/memory.o \
engine/tinygl/misc.o \
engine/tinygl/msghandling.o \
engine/tinygl/select.o \
engine/tinygl/specbuf.o \
engine/tinygl/texture.o \
engine/tinygl/vertex.o \
engine/tinygl/zbuffer.o \
engine/tinygl/zline.o \
engine/tinygl/zmath.o \
engine/tinygl/ztriangle.o
all: $(EXECUTABLE)
DEPS = $(OBJS:.o=.d)
residual: $(OBJS)
$(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
######################################################################
# Module settings
######################################################################
.cpp.o:
@test -d $(*D) || mkdir -p $(*D)
$(CXX) $(CXXFLAGS) -Wp,-MMD,"$*.d",-MQ,"$*.o",-MP -c $(<) -o $*.o
MODULES := $(MODULES)
clean:
-rm -f residual$(EXEEXT) *.o *.d common/*.[od] engine/*.[od] engine/backend/sdl/*.[od] engine/imuse/*.[od] engine/lua/*.[od] engine/smush/*.[od] engine/tinygl/*.[od] mixer/*.[od]
# After the game specific modules follow the shared modules
MODULES += \
engine \
engine/backend \
engine/imuse \
engine/lua \
engine/smush \
engine/tinygl \
common \
mixer
-include $(DEPS)
######################################################################
# The build rules follow - normally you should have no need to
# touch whatever comes after here.
######################################################################
# Concat DEFINES and INCLUDES to form the CPPFLAGS
CPPFLAGS := $(DEFINES) $(INCLUDES)
# Include the build instructions for all modules
-include $(addprefix $(srcdir)/, $(addsuffix /module.mk,$(MODULES)))
# Depdir information
DEPDIRS = $(addsuffix $(DEPDIR),$(MODULE_DIRS))
DEPFILES =
# The build rule for the Residual executable
$(EXECUTABLE): $(OBJS)
$(CXX) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) -o $@
distclean: clean
$(RM) config.h config.mk config.log
clean:
$(RM_REC) $(DEPDIRS)
$(RM) $(OBJS) $(EXECUTABLE)
ifndef HAVE_GCC3
# If you use GCC, disable the above and enable this for intelligent
# dependency tracking.
%.o: %.cpp
$(MKDIR) $(*D)/$(DEPDIR)
$(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d2" $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
$(ECHO) "$(*D)/" > $(*D)/$(DEPDIR)/$(*F).d
$(CAT) "$(*D)/$(DEPDIR)/$(*F).d2" >> "$(*D)/$(DEPDIR)/$(*F).d"
$(RM) "$(*D)/$(DEPDIR)/$(*F).d2"
else
# If you even have GCC 3.x, you can use this build rule, which is safer; the above
# rule can get you into a bad state if you Ctrl-C at the wrong moment.
# Also, with this GCC inserts additional dummy rules for the involved headers,
# which ensures a smooth compilation even if said headers become obsolete.
%.o: %.cpp
$(MKDIR) $(*D)/$(DEPDIR)
$(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
%.o: %.m
$(MKDIR) $(*D)/$(DEPDIR)
$(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(OBJCFLAGS) -c $(<) -o $*.o
endif
# Include the dependency tracking files.
-include $(wildcard $(addsuffix /*.d,$(DEPDIRS)))
######################################################################
# Create the files that depend on the version
######################################################################
######################################################################
# Distribution settings
######################################################################
ifeq ($(VER_EXTRA),svn)
DISTVERSION = $(shell date '+%Y-%m-%d')
else
DISTVERSION = $(VERSION)
endif
DISTNAME := residual-$(DISTVERSION)
DISTDIR := dist
ifeq ($(shell svn stat $(srcdir) 2>&1 | grep "is not a working copy"),)
SVNROOT := $(srcdir)
else
SVNROOT := https://scummvm.svn.sourceforge.net/svnroot/scummvm/residual/trunk/
endif
$(DISTDIR)/$(DISTNAME).tar.gz:
cd $(DISTDIR); tar zcf $(DISTNAME).tar.gz $(DISTNAME)
$(DISTDIR)/$(DISTNAME).tar.bz2:
cd $(DISTDIR); tar jcf $(DISTNAME).tar.bz2 $(DISTNAME)
$(DISTDIR)/$(DISTNAME).zip:
cd $(DISTDIR); zip -qr9 $(DISTNAME).zip $(DISTNAME)
dist-src: \
$(DISTDIR)/$(DISTNAME).tar.gz \
$(DISTDIR)/$(DISTNAME).tar.bz2 \
$(DISTDIR)/$(DISTNAME).zip
@#RPM-src?
@#DEB-src?
.PHONY: all clean distclean dist-src

View File

@ -1,11 +0,0 @@
### Modify these paths if needed
SDL_CFLAGS=-I/usr/i586-mingw32msvc/include/SDL
SDL_LIBS=-L/usr/i586-mingw32msvc/lib -lSDL
CXX = i586-mingw32msvc-g++
CXXFLAGS = -W -Wall -Wno-multichar -I. $(SDL_CFLAGS) # -O2
LDFLAGS = -W -Wall # -O2
LIBS = -lmingw32 -lopengl32 -lglu32 -lgdi32 $(SDL_LIBS) -lz
EXEEXT =.exe
include Makefile.common

View File

@ -1,26 +0,0 @@
# Where residual will be installed
RESIDUALPATH=C:/residual
### Modify these paths
SDL_CFLAGS=`sdl-config --cflags`
SDL_LIBS=`sdl-config --libs`
CXX = g++
CXXFLAGS = -g -W -Wall -Wno-multichar -I. $(SDL_CFLAGS) # -O2
LDFLAGS = -g -W -Wall # -O2
LIBS = -lmingw32 -lopengl32 -lglu32 -lgdi32 $(SDL_LIBS) -lz
EXEEXT =.exe
include Makefile.common
# Some additional targets
install: residual
mkdir -p $(RESIDUALPATH)
strip residual$(EXEEXT) -o $(RESIDUALPATH)/residual$(EXEEXT)
dist: install
cp COPYING $(RESIDUALPATH)/copying.txt
cp README $(RESIDUALPATH)/readme.txt
cp /usr/local/README-SDL.txt $(RESIDUALPATH)
cp /usr/local/bin/SDL.dll $(RESIDUALPATH)
u2d $(RESIDUALPATH)/*.txt

2
README
View File

@ -1,5 +1,5 @@
Residual: A LucasArts 3D game interpreter Version: 0.06a-CVS
(C) 2003-2006 The ScummVM-Residual team Last Updated: 14 May 2006
(C) 2003-2008 The ScummVM-Residual team Last Updated: 14 May 2006
------------------------------------------------------------------------------
What is Residual?

154
common/algorithm.h Normal file
View File

@ -0,0 +1,154 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2006 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef COMMON_ALGORITHM_H
#define COMMON_ALGORITHM_H
#include "common/sys.h"
namespace Common {
template<class In, class Out>
Out copy(In first, In last, Out dst) {
while (first != last)
*dst++ = *first++;
return dst;
}
template<class In, class Out>
Out copy_backward(In first, In last, Out dst) {
while (first != last)
*--dst = *--last;
return dst;
}
template<class In, class Out, class Op>
Out copy_if(In first, In last, Out dst, Op op) {
while (first != last) {
if (op(*first))
*dst++ = *first;
++first;
}
return dst;
}
// Our 'specialized' 'set_to' template for char, signed char and unsigned char arrays.
// Since C++ doesn't support partial specialized template functions (currently) we
// are going this way...
// With this we assure the usage of memset for those, which should be
// faster than a simple loop like for the generic 'set_to'.
template<class Value>
signed char *set_to(signed char *first, signed char *last, Value val) {
memset(first, (val & 0xFF), last - first);
return last;
}
template<class Value>
unsigned char *set_to(unsigned char *first, unsigned char *last, Value val) {
memset(first, (val & 0xFF), last - first);
return last;
}
template<class Value>
char *set_to(char *first, char *last, Value val) {
memset(first, (val & 0xFF), last - first);
return last;
}
template<class In, class Value>
In set_to(In first, In last, Value val) {
while (first != last)
*first++ = val;
return first;
}
template<class In, class T>
In find(In first, In last, const T &v) {
while (first != last) {
if (*first == v)
return first;
++first;
}
return last;
}
template<class In, class Pred>
In find_if(In first, In last, Pred p) {
while (first != last) {
if (p(*first))
return first;
++first;
}
return last;
}
template<class In, class Op>
Op for_each(In first, In last, Op f) {
while (first != last) f(*first++);
return f;
}
// Simple sort function, modeled after std::sort.
// Use it like this: sort(container.begin(), container.end()).
// Also work on plain old int arrays etc.
template<class T>
void sort(T first, T last) {
if (first == last)
return;
// Simple selection sort
T i(first);
for (; i != last; ++i) {
T minElem(i);
T j(i);
++j;
for (; j != last; ++j)
if (*j < *minElem)
minElem = j;
if (minElem != i)
SWAP(*minElem, *i);
}
}
// Using this with: Common::Less from common/func.h
// will give the same results as the function above.
template<class T, class StrictWeakOrdering>
void sort(T first, T last, StrictWeakOrdering comp) {
if (first == last)
return;
// Simple selection sort
T i(first);
for (; i != last; ++i) {
T minElem(i);
T j(i);
++j;
for (; j != last; ++j)
if (comp(*j, *minElem))
minElem = j;
if (minElem != i)
SWAP(*minElem, *i);
}
}
} // end of namespace Common
#endif

180
common/array.h Normal file
View File

@ -0,0 +1,180 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2006 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef COMMON_ARRAY_H
#define COMMON_ARRAY_H
#include "common/sys.h"
#include "common/algorithm.h"
namespace Common {
template<class T>
class Array {
protected:
uint _capacity;
uint _size;
T *_data;
public:
typedef T *iterator;
typedef const T *const_iterator;
typedef T value_type;
public:
Array() : _capacity(0), _size(0), _data(0) {}
Array(const Array<T> &array) : _capacity(0), _size(0), _data(0) {
_size = array._size;
_capacity = _size + 32;
_data = new T[_capacity];
copy(array._data, array._data + _size, _data);
}
~Array() {
delete[] _data;
}
void push_back(const T &element) {
ensureCapacity(_size + 1);
_data[_size++] = element;
}
void push_back(const Array<T> &array) {
ensureCapacity(_size + array._size);
copy(array._data, array._data + array._size, _data + _size);
_size += array._size;
}
void insert_at(int idx, const T &element) {
assert(idx >= 0 && (uint)idx <= _size);
ensureCapacity(_size + 1);
copy_backward(_data + idx, _data + _size, _data + _size + 1);
_data[idx] = element;
_size++;
}
T remove_at(int idx) {
assert(idx >= 0 && (uint)idx < _size);
T tmp = _data[idx];
copy(_data + idx + 1, _data + _size, _data + idx);
_size--;
return tmp;
}
// TODO: insert, remove, ...
T& operator[](int idx) {
assert(idx >= 0 && (uint)idx < _size);
return _data[idx];
}
const T& operator[](int idx) const {
assert(idx >= 0 && (uint)idx < _size);
return _data[idx];
}
Array<T>& operator=(const Array<T> &array) {
if (this == &array)
return *this;
delete[] _data;
_size = array._size;
_capacity = _size + 32;
_data = new T[_capacity];
copy(array._data, array._data + _size, _data);
return *this;
}
uint size() const {
return _size;
}
void clear() {
delete[] _data;
_data = 0;
_size = 0;
_capacity = 0;
}
bool empty() const {
return (_size == 0);
}
iterator begin() {
return _data;
}
iterator end() {
return _data + _size;
}
const_iterator begin() const {
return _data;
}
const_iterator end() const {
return _data + _size;
}
void reserve(uint newCapacity) {
if (newCapacity <= _capacity)
return;
T *old_data = _data;
_capacity = newCapacity;
_data = new T[newCapacity];
if (old_data) {
// Copy old data
copy(old_data, old_data + _size, _data);
delete[] old_data;
}
}
void resize(uint newSize) {
if (newSize == _size)
return;
T *old_data = _data;
_capacity = newSize;
_data = new T[newSize];
if (old_data) {
// Copy old data
int cnt = (_size < newSize ? _size : newSize);
copy(old_data, old_data + cnt, _data);
delete[] old_data;
}
_size = newSize;
}
protected:
void ensureCapacity(uint len) {
if (len >= _capacity)
reserve(len + 32);
}
};
} // End of namespace Common
#endif

View File

@ -87,7 +87,7 @@ void hexdump(const byte * data, int len, int bytesPerLine) {
printf("|\n");
}
void warning(const char *fmt, ...) {
void CDECL warning(const char *fmt, ...) {
std::fprintf(stderr, "WARNING: ");
std::va_list va;
@ -98,7 +98,7 @@ void warning(const char *fmt, ...) {
std::fprintf(stderr, "\n");
}
void error(const char *fmt, ...) {
void CDECL error(const char *fmt, ...) {
std::fprintf(stderr, "ERROR: ");
std::va_list va;

View File

@ -20,7 +20,7 @@
*
*/
#include "common/platform.h"
#include "common/sys.h"
#ifndef COMMON_DEBUG_H
#define COMMON_DEBUG_H

217
common/endian.h Normal file
View File

@ -0,0 +1,217 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2008 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_ENDIAN_H
#define COMMON_ENDIAN_H
#include "common/sys.h"
//
// Endian conversion functions, macros etc., follow from here!
//
/**
* Swap the bytes in a 32 bit word in order to convert LE encoded data to BE
* and vice versa.
*/
FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) {
return ((a >> 24) & 0x000000FF) |
((a >> 8) & 0x0000FF00) |
((a << 8) & 0x00FF0000) |
((a << 24) & 0xFF000000);
}
/**
* Swap the bytes in a 16 bit word in order to convert LE encoded data to BE
* and vice versa.
*/
FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) {
return ((a >> 8) & 0x00FF) + ((a << 8) & 0xFF00);
}
/**
* A wrapper macro used around four character constants, like 'DATA', to
* ensure portability. Typical usage: MKID_BE('DATA').
*
* Why is this necessary? The C/C++ standard does not define the endianess to
* be used for character constants. Hence if one uses multi-byte character
* constants, a potential portability problem opens up.
*
* Fortunately, a semi-standard has been established: On almost all systems
* and compilers, multi-byte character constants are encoded using the big
* endian convention (probably in analogy to the encoding of string constants).
* Still some systems differ. This is why we provide the MKID_BE macro. If
* you wrap your four character constants with it, the result will always be
* BE encoded, even on systems which differ from the default BE encoding.
*
* For the latter systems we provide the INVERSE_MKID override.
*/
#if defined(INVERSE_MKID)
#define MKID_BE(a) ((uint32) \
(((a) >> 24) & 0x000000FF) | \
(((a) >> 8) & 0x0000FF00) | \
(((a) << 8) & 0x00FF0000) | \
(((a) << 24) & 0xFF000000))
#else
# define MKID_BE(a) ((uint32)(a))
#endif
#if defined(SYSTEM_LITTLE_ENDIAN)
#define READ_UINT16(a) READ_LE_UINT16(a)
#define READ_UINT32(a) READ_LE_UINT32(a)
#define WRITE_UINT16(a, v) WRITE_LE_UINT16(a, v)
#define WRITE_UINT32(a, v) WRITE_LE_UINT32(a, v)
#define FROM_LE_32(a) ((uint32)(a))
#define FROM_LE_16(a) ((uint16)(a))
#define FROM_BE_32(a) SWAP_BYTES_32(a)
#define FROM_BE_16(a) SWAP_BYTES_16(a)
#define TO_LE_32(a) ((uint32)(a))
#define TO_LE_16(a) ((uint16)(a))
#define TO_BE_32(a) SWAP_BYTES_32(a)
#define TO_BE_16(a) SWAP_BYTES_16(a)
#elif defined(SYSTEM_BIG_ENDIAN)
#define MKID(a) ((uint32)(a))
#define MKID_BE(a) ((uint32)(a))
#define READ_UINT16(a) READ_BE_UINT16(a)
#define READ_UINT32(a) READ_BE_UINT32(a)
#define WRITE_UINT16(a, v) WRITE_BE_UINT16(a, v)
#define WRITE_UINT32(a, v) WRITE_BE_UINT32(a, v)
#define FROM_LE_32(a) SWAP_BYTES_32(a)
#define FROM_LE_16(a) SWAP_BYTES_16(a)
#define FROM_BE_32(a) ((uint32)(a))
#define FROM_BE_16(a) ((uint16)(a))
#define TO_LE_32(a) SWAP_BYTES_32(a)
#define TO_LE_16(a) SWAP_BYTES_16(a)
#define TO_BE_32(a) ((uint32)(a))
#define TO_BE_16(a) ((uint16)(a))
#else
#error No endianness defined
#endif
#if defined(SYSTEM_NEED_ALIGNMENT) || !defined(SYSTEM_LITTLE_ENDIAN)
FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) {
const byte *b = (const byte *)ptr;
return (b[1] << 8) + b[0];
}
FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) {
const byte *b = (const byte *)ptr;
return (b[3] << 24) + (b[2] << 16) + (b[1] << 8) + (b[0]);
}
FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) {
byte *b = (byte *)ptr;
b[0] = (byte)(value >> 0);
b[1] = (byte)(value >> 8);
}
FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) {
byte *b = (byte *)ptr;
b[0] = (byte)(value >> 0);
b[1] = (byte)(value >> 8);
b[2] = (byte)(value >> 16);
b[3] = (byte)(value >> 24);
}
#else
FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) {
return *(const uint16 *)(ptr);
}
FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) {
return *(const uint32 *)(ptr);
}
FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) {
*(uint16 *)(ptr) = value;
}
FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) {
*(uint32 *)(ptr) = value;
}
#endif
#if defined(SYSTEM_NEED_ALIGNMENT) || !defined(SYSTEM_BIG_ENDIAN)
FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) {
const byte *b = (const byte *)ptr;
return (b[0] << 8) + b[1];
}
FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) {
const byte *b = (const byte*)ptr;
return (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + (b[3]);
}
FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) {
byte *b = (byte *)ptr;
b[0] = (byte)(value >> 8);
b[1] = (byte)(value >> 0);
}
FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) {
byte *b = (byte *)ptr;
b[0] = (byte)(value >> 24);
b[1] = (byte)(value >> 16);
b[2] = (byte)(value >> 8);
b[3] = (byte)(value >> 0);
}
#else
FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) {
return *(const uint16 *)(ptr);
}
FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) {
return *(const uint32 *)(ptr);
}
FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) {
*(uint16 *)(ptr) = value;
}
FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) {
*(uint32 *)(ptr) = value;
}
#endif
FORCEINLINE uint32 READ_LE_UINT24(const void *ptr) {
const byte *b = (const byte *)ptr;
return (b[2] << 16) + (b[1] << 8) + (b[0]);
}
FORCEINLINE uint32 READ_BE_UINT24(const void *ptr) {
const byte *b = (const byte*)ptr;
return (b[0] << 16) + (b[1] << 8) + (b[2]);
}
#endif

303
common/func.h Normal file
View File

@ -0,0 +1,303 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2008 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef COMMON_FUNC_H
#define COMMON_FUNC_H
#include "common/sys.h"
namespace Common {
template<class Arg, class Result>
struct UnaryFunction {
typedef Arg ArgumenType;
typedef Result ResultType;
};
template<class Arg1, class Arg2, class Result>
struct BinaryFunction {
typedef Arg1 FirstArgumentType;
typedef Arg2 SecondArgumentType;
typedef Result ResultType;
};
template<class T>
struct EqualTo : public BinaryFunction<T, T, bool> {
bool operator()(const T &x, const T &y) const { return x == y; }
};
template<class T>
struct Less : public BinaryFunction<T, T, bool> {
bool operator()(const T &x, const T &y) const { return x < y; }
};
template<class T>
struct Greater : public BinaryFunction<T, T, bool> {
bool operator()(const T &x, const T &y) const { return x > y; }
};
template<class Op>
class Binder1st : public UnaryFunction<typename Op::SecondArgumentType, typename Op::ResultType> {
private:
Op _op;
typename Op::FirstArgumentType _arg1;
public:
Binder1st(const Op &op, const typename Op::FirstArgumentType &arg1) : _op(op), _arg1(arg1) {}
typename Op::ResultType operator()(typename Op::SecondArgumentType v) const {
return _op(_arg1, v);
}
};
template<class Op, class T>
inline Binder1st<Op> bind1st(const Op &op, const T &t) {
return Binder1st<Op>(op, t);
}
template<class Op>
class Binder2nd : public UnaryFunction<typename Op::FirstArgumentType, typename Op::ResultType> {
private:
Op _op;
typename Op::SecondArgumentType _arg2;
public:
Binder2nd(const Op &op, const typename Op::SecondArgumentType &arg2) : _op(op), _arg2(arg2) {}
typename Op::ResultType operator()(typename Op::FirstArgumentType v) const {
return _op(v, _arg2);
}
};
template<class Op, class T>
inline Binder2nd<Op> bind2nd(const Op &op, const T &t) {
return Binder2nd<Op>(op, t);
}
template<class Arg, class Result>
class PointerToUnaryFunc : public UnaryFunction<Arg, Result> {
private:
Result (*_func)(Arg);
public:
typedef Result (*FuncType)(Arg);
PointerToUnaryFunc(const FuncType &func) : _func(func) {}
Result operator()(Arg v) const {
return _func(v);
}
};
template<class Arg1, class Arg2, class Result>
class PointerToBinaryFunc : public BinaryFunction<Arg1, Arg2, Result> {
private:
Result (*_func)(Arg1, Arg2);
public:
typedef Result (*FuncType)(Arg1, Arg2);
PointerToBinaryFunc(const FuncType &func) : _func(func) {}
Result operator()(Arg1 v1, Arg2 v2) const {
return _func(v1, v2);
}
};
template<class Arg, class Result>
inline PointerToUnaryFunc<Arg, Result> ptr_fun(Result (*func)(Arg)) {
return PointerToUnaryFunc<Arg, Result>(func);
}
template<class Arg1, class Arg2, class Result>
inline PointerToBinaryFunc<Arg1, Arg2, Result> ptr_fun(Result (*func)(Arg1, Arg2)) {
return PointerToBinaryFunc<Arg1, Arg2, Result>(func);
}
template<class Result, class T>
class MemFunc0 : public UnaryFunction<T*, Result> {
private:
Result (T::*_func)();
public:
typedef Result (T::*FuncType)();
MemFunc0(const FuncType &func) : _func(func) {}
Result operator()(T *v) const {
return (v->*_func)();
}
};
template<class Result, class T>
class ConstMemFunc0 : public UnaryFunction<T*, Result> {
private:
Result (T::*_func)() const;
public:
typedef Result (T::*FuncType)() const;
ConstMemFunc0(const FuncType &func) : _func(func) {}
Result operator()(T *v) const {
return (v->*_func)();
}
};
template<class Result, class Arg, class T>
class MemFunc1 : public BinaryFunction<T*, Arg, Result> {
private:
Result (T::*_func)(Arg);
public:
typedef Result (T::*FuncType)(Arg);
MemFunc1(const FuncType &func) : _func(func) {}
Result operator()(T *v1, Arg v2) const {
return (v1->*_func)(v2);
}
};
template<class Result, class Arg, class T>
class ConstMemFunc1 : public BinaryFunction<T*, Arg, Result> {
private:
Result (T::*_func)(Arg) const;
public:
typedef Result (T::*FuncType)(Arg) const;
ConstMemFunc1(const FuncType &func) : _func(func) {}
Result operator()(T *v1, Arg v2) const {
return (v1->*_func)(v2);
}
};
template<class Result, class T>
inline MemFunc0<Result, T> mem_fun(Result (T::*f)()) {
return MemFunc0<Result, T>(f);
}
template<class Result, class T>
inline ConstMemFunc0<Result, T> mem_fun(Result (T::*f)() const) {
return ConstMemFunc0<Result, T>(f);
}
template<class Result, class Arg, class T>
inline MemFunc1<Result, Arg, T> mem_fun(Result (T::*f)(Arg)) {
return MemFunc1<Result, Arg, T>(f);
}
template<class Result, class Arg, class T>
inline ConstMemFunc1<Result, Arg, T> mem_fun(Result (T::*f)(Arg) const) {
return ConstMemFunc1<Result, Arg, T>(f);
}
// functor code
template<class Res>
struct Functor0 {
virtual ~Functor0() {}
virtual bool isValid() const = 0;
virtual Res operator()() const = 0;
};
template<class Res, class T>
class Functor0Mem : public Functor0<Res> {
public:
typedef Res (T::*FuncType)();
Functor0Mem(T *t, const FuncType &func) : _t(t), _func(func) {}
bool isValid() const { return _func != 0; }
Res operator()() const {
return (_t->*_func)();
}
private:
mutable T *_t;
const FuncType _func;
};
template<class Arg, class Res>
struct Functor1 : public Common::UnaryFunction<Arg, Res> {
virtual ~Functor1() {}
virtual bool isValid() const = 0;
virtual Res operator()(Arg) const = 0;
};
template<class Arg, class Res, class T>
class Functor1Mem : public Functor1<Arg, Res> {
public:
typedef Res (T::*FuncType)(Arg);
Functor1Mem(T *t, const FuncType &func) : _t(t), _func(func) {}
bool isValid() const { return _func != 0; }
Res operator()(Arg v1) const {
return (_t->*_func)(v1);
}
private:
mutable T *_t;
const FuncType _func;
};
template<class Arg1, class Arg2, class Res>
struct Functor2 : public Common::BinaryFunction<Arg1, Arg2, Res> {
virtual ~Functor2() {}
virtual bool isValid() const = 0;
virtual Res operator()(Arg1, Arg2) const = 0;
};
template<class Arg1, class Arg2, class Res, class T>
class Functor2Mem : public Functor2<Arg1, Arg2, Res> {
public:
typedef Res (T::*FuncType)(Arg1, Arg2);
Functor2Mem(T *t, const FuncType &func) : _t(t), _func(func) {}
bool isValid() const { return _func != 0; }
Res operator()(Arg1 v1, Arg2 v2) const {
return (_t->*_func)(v1, v2);
}
private:
mutable T *_t;
const FuncType _func;
};
/**
* Base template for hash functor objects, used by HashMap.
* This needs to be specialized for every type that you need to hash.
*/
template<typename T> struct Hash;
#define GENERATE_TRIVIAL_HASH_FUNCTOR(T) \
template<> struct Hash<T> : public UnaryFunction<T, uint> { \
uint operator()(T val) const { return (uint)val; } \
}
GENERATE_TRIVIAL_HASH_FUNCTOR(bool);
GENERATE_TRIVIAL_HASH_FUNCTOR(char);
GENERATE_TRIVIAL_HASH_FUNCTOR(signed char);
GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned char);
GENERATE_TRIVIAL_HASH_FUNCTOR(short);
GENERATE_TRIVIAL_HASH_FUNCTOR(int);
GENERATE_TRIVIAL_HASH_FUNCTOR(long);
GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned short);
GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned int);
GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned long);
#undef GENERATE_TRIVIAL_HASH_FUNCTOR
} // End of namespace Common
#endif

86
common/hash-str.h Normal file
View File

@ -0,0 +1,86 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2008 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef COMMON_HASH_STR_H
#define COMMON_HASH_STR_H
#include "common/hashmap.h"
#include "common/str.h"
namespace Common {
uint hashit(const char *str);
uint hashit_lower(const char *str); // Generate a hash based on the lowercase version of the string
inline uint hashit(const String &str) { return hashit(str.c_str()); }
inline uint hashit_lower(const String &str) { return hashit_lower(str.c_str()); }
// FIXME: The following functors obviously are not consistently named
struct CaseSensitiveString_EqualTo {
bool operator()(const String& x, const String& y) const { return strcmp(x.c_str(), y.c_str()) == 0; }
};
struct CaseSensitiveString_Hash {
uint operator()(const String& x) const { return hashit(x.c_str()); }
};
struct IgnoreCase_EqualTo {
bool operator()(const String& x, const String& y) const { return strcasecmp(x.c_str(), y.c_str()) == 0; }
};
struct IgnoreCase_Hash {
uint operator()(const String& x) const { return hashit_lower(x.c_str()); }
};
// Specalization of the Hash functor for String objects.
// We do case sensitve hashing here, because that is what
// the default EqualTo is compatible with. If one wants to use
// case insensitve hashing, then only because one wants to use
// IgnoreCase_EqualTo, and then one has to specify a custom
// hash anyway.
template <>
struct Hash<String> {
uint operator()(const String& s) const {
return hashit(s.c_str());
}
};
template <>
struct Hash<const char *> {
uint operator()(const char *s) const {
return hashit(s);
}
};
// String map -- by default case insensitive
typedef HashMap<String, String, IgnoreCase_Hash, IgnoreCase_EqualTo> StringMap;
} // End of namespace Common
#endif

90
common/hashmap.cpp Normal file
View File

@ -0,0 +1,90 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2008 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
// The hash map (associative array) implementation in this file is
// based on code by Andrew Y. Ng, 1996:
/*
* Copyright (c) 1998-2003 Massachusetts Institute of Technology.
* This code was developed as part of the Haystack research project
* (http://haystack.lcs.mit.edu/). Permission is hereby granted,
* free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 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 OR COPYRIGHT
* HOLDERS 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.
*/
#include "common/hashmap.h"
namespace Common {
// const char *:
uint hashit(const char *p) {
uint hash = 0;
byte c;
while ((c = *p++))
hash = (hash * 31 + c);
return hash;
}
uint hashit_lower(const char *p) {
uint hash = 0;
byte c;
while ((c = *p++))
hash = (hash * 31 + tolower(c));
return hash;
}
// The following table is taken from the GNU ISO C++ Library's hashtable.h file.
static const uint primes[] = {
53ul, 97ul, 193ul, 389ul, 769ul,
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
1610612741ul, 3221225473ul, 4294967291ul
};
uint nextTableSize(uint x) {
int i = 0;
while (x >= primes[i])
i++;
return primes[i];
}
} // End of namespace Common

541
common/hashmap.h Normal file
View File

@ -0,0 +1,541 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2008 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
// The hash map (associative array) implementation in this file is
// based on code by Andrew Y. Ng, 1996:
/*
* Copyright (c) 1998-2003 Massachusetts Institute of Technology.
* This code was developed as part of the Haystack research project
* (http://haystack.lcs.mit.edu/). Permission is hereby granted,
* free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 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 OR COPYRIGHT
* HOLDERS 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.
*/
#ifndef COMMON_HASHMAP_H
#define COMMON_HASHMAP_H
#include "common/func.h"
#include "common/str.h"
#include "common/util.h"
#define USE_HASHMAP_MEMORY_POOL
#ifdef USE_HASHMAP_MEMORY_POOL
#include "common/memorypool.h"
// FIXME: we sadly can't assume standard C++ to be present
// on every system we support, so we should get rid of this.
// The solution should be to write a simple placement new
// on our own.
#include <new>
#endif
namespace Common {
// The table sizes ideally are primes. We use a helper function to find
// suitable table sizes.
uint nextTableSize(uint x);
// Enable the following #define if you want to check how many collisions the
// code produces (many collisions indicate either a bad hash function, or a
// hash table that is too small).
//#define DEBUG_HASH_COLLISIONS
/**
* HashMap<Key,Val> maps objects of type Key to objects of type Val.
* For each used Key type, we need an "uint hashit(Key,uint)" function
* that computes a hash for the given Key object and returns it as an
* an integer from 0 to hashsize-1, and also an "equality functor".
* that returns true if if its two arguments are to be considered
* equal. Also, we assume that "=" works on Val objects for assignment.
*
* If aa is an HashMap<Key,Val>, then space is allocated each time aa[key] is
* referenced, for a new key. If the object is const, then an assertion is
* triggered instead. Hence if you are not sure whether a key is contained in
* the map, use contains() first to check for its presence.
*/
template<class Key, class Val, class HashFunc = Hash<Key>, class EqualFunc = EqualTo<Key> >
class HashMap {
private:
#if defined (PALMOS_MODE)
public:
#endif
typedef HashMap<Key, Val, HashFunc, EqualFunc> HM_t;
struct Node {
const Key _key;
Val _value;
Node(const Key &key) : _key(key), _value() {}
};
#ifdef USE_HASHMAP_MEMORY_POOL
MemoryPool _nodePool;
Node *allocNode(const Key &key) {
void* mem = _nodePool.malloc();
return new (mem) Node(key);
}
void freeNode(Node *node) {
node->~Node();
_nodePool.free(node);
}
#else
Node* allocNode(const Key &key) {
return new Node(key);
}
void freeNode(Node *node) {
delete node;
}
#endif
Node **_arr; // hashtable of size arrsize.
uint _arrsize, _nele;
HashFunc _hash;
EqualFunc _equal;
// Default value, returned by the const getVal.
const Val _defaultVal;
#ifdef DEBUG_HASH_COLLISIONS
mutable int _collisions, _lookups;
#endif
void assign(const HM_t &map);
int lookup(const Key &key) const;
int lookupAndCreateIfMissing(const Key &key);
void expand_array(uint newsize);
template<class T> friend class IteratorImpl;
/**
* Simple HashMap iterator implementation.
*/
template<class NodeType>
class IteratorImpl {
friend class HashMap;
template<class T> friend class IteratorImpl;
protected:
typedef const HashMap hashmap_t;
uint _idx;
hashmap_t *_hashmap;
protected:
IteratorImpl(uint idx, hashmap_t *hashmap) : _idx(idx), _hashmap(hashmap) {}
NodeType *deref() const {
assert(_hashmap != 0);
assert(_idx < _hashmap->_arrsize);
Node *node = _hashmap->_arr[_idx];
assert(node != 0);
return node;
}
public:
IteratorImpl() : _idx(0), _hashmap(0) {}
template<class T>
IteratorImpl(const IteratorImpl<T> &c) : _idx(c._idx), _hashmap(c._hashmap) {}
NodeType &operator*() const { return *deref(); }
NodeType *operator->() const { return deref(); }
bool operator==(const IteratorImpl &iter) const { return _idx == iter._idx && _hashmap == iter._hashmap; }
bool operator!=(const IteratorImpl &iter) const { return !(*this == iter); }
IteratorImpl &operator++() {
assert(_hashmap);
do {
_idx++;
} while (_idx < _hashmap->_arrsize && _hashmap->_arr[_idx] == 0);
if (_idx >= _hashmap->_arrsize)
_idx = (uint)-1;
return *this;
}
IteratorImpl operator++(int) {
IteratorImpl old = *this;
operator ++();
return old;
}
};
public:
typedef IteratorImpl<Node> iterator;
typedef IteratorImpl<const Node> const_iterator;
HashMap();
HashMap(const HM_t &map);
~HashMap();
HM_t &operator=(const HM_t &map) {
if (this == &map)
return *this;
// Remove the previous content and ...
clear();
delete[] _arr;
// ... copy the new stuff.
assign(map);
return *this;
}
bool contains(const Key &key) const;
Val &operator[](const Key &key);
const Val &operator[](const Key &key) const;
Val &getVal(const Key &key);
const Val &getVal(const Key &key) const;
void setVal(const Key &key, const Val &val);
void clear(bool shrinkArray = 0);
void erase(const Key &key);
uint size() const { return _nele; }
iterator begin() {
// Find and return the _key non-empty entry
for (uint ctr = 0; ctr < _arrsize; ++ctr) {
if (_arr[ctr])
return iterator(ctr, this);
}
return end();
}
iterator end() {
return iterator((uint)-1, this);
}
const_iterator begin() const {
// Find and return the first non-empty entry
for (uint ctr = 0; ctr < _arrsize; ++ctr) {
if (_arr[ctr])
return const_iterator(ctr, this);
}
return end();
}
const_iterator end() const {
return const_iterator((uint)-1, this);
}
iterator find(const Key &key) {
uint ctr = lookup(key);
if (_arr[ctr])
return iterator(ctr, this);
return end();
}
const_iterator find(const Key &key) const {
uint ctr = lookup(key);
if (_arr[ctr])
return const_iterator(ctr, this);
return end();
}
// TODO: insert() method?
bool empty() const {
return (_nele == 0);
}
};
//-------------------------------------------------------
// HashMap functions
/**
* Base constructor, creates an empty hashmap.
*/
template<class Key, class Val, class HashFunc, class EqualFunc>
HashMap<Key, Val, HashFunc, EqualFunc>::HashMap() :
#ifdef USE_HASHMAP_MEMORY_POOL
_nodePool(sizeof(Node)),
#endif
_defaultVal() {
_arrsize = nextTableSize(0);
_arr = new Node *[_arrsize];
assert(_arr != NULL);
memset(_arr, 0, _arrsize * sizeof(Node *));
_nele = 0;
#ifdef DEBUG_HASH_COLLISIONS
_collisions = 0;
_lookups = 0;
#endif
}
/**
* Copy constructor, creates a full copy of the given hashmap.
* We must provide a custom copy constructor as we use pointers
* to heap buffers for the internal storage.
*/
template<class Key, class Val, class HashFunc, class EqualFunc>
HashMap<Key, Val, HashFunc, EqualFunc>::HashMap(const HM_t &map) :
#ifdef USE_HASHMAP_MEMORY_POOL
_nodePool(sizeof(Node)),
#endif
_defaultVal() {
assign(map);
}
/**
* Destructor, frees all used memory.
*/
template<class Key, class Val, class HashFunc, class EqualFunc>
HashMap<Key, Val, HashFunc, EqualFunc>::~HashMap() {
for (uint ctr = 0; ctr < _arrsize; ++ctr)
if (_arr[ctr] != NULL)
freeNode(_arr[ctr]);
delete[] _arr;
}
/**
* Internal method for assigning the content of another HashMap
* to this one.
*
* @note We do *not* deallocate the previous storage here -- the caller is
* responsible for doing that!
*/
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::assign(const HM_t &map) {
_arrsize = map._arrsize;
_arr = new Node *[_arrsize];
assert(_arr != NULL);
memset(_arr, 0, _arrsize * sizeof(Node *));
// Simply clone the map given to us, one by one.
_nele = 0;
for (uint ctr = 0; ctr < _arrsize; ++ctr) {
if (map._arr[ctr] != NULL) {
_arr[ctr] = allocNode(map._arr[ctr]->_key);
_arr[ctr]->_value = map._arr[ctr]->_value;
_nele++;
}
}
// Perform a sanity check (to help track down hashmap corruption)
assert(_nele == map._nele);
}
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::clear(bool shrinkArray) {
for (uint ctr = 0; ctr < _arrsize; ++ctr) {
if (_arr[ctr] != NULL) {
freeNode(_arr[ctr]);
_arr[ctr] = NULL;
}
}
if (shrinkArray && _arrsize > nextTableSize(0)) {
delete[] _arr;
_arrsize = nextTableSize(0);
_arr = new Node *[_arrsize];
assert(_arr != NULL);
memset(_arr, 0, _arrsize * sizeof(Node *));
}
_nele = 0;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::expand_array(uint newsize) {
assert(newsize > _arrsize);
uint ctr, dex;
const uint old_nele = _nele;
const uint old_arrsize = _arrsize;
Node **old_arr = _arr;
// allocate a new array
_nele = 0;
_arrsize = newsize;
_arr = new Node *[_arrsize];
assert(_arr != NULL);
memset(_arr, 0, _arrsize * sizeof(Node *));
// rehash all the old elements
for (ctr = 0; ctr < old_arrsize; ++ctr) {
if (old_arr[ctr] == NULL)
continue;
// Insert the element from the old table into the new table.
// Since we know that no key exists twice in the old table, we
// can do this slightly better than by calling lookup, since we
// don't have to call _equal().
dex = _hash(old_arr[ctr]->_key) % _arrsize;
while (_arr[dex] != NULL) {
dex = (dex + 1) % _arrsize;
}
_arr[dex] = old_arr[ctr];
_nele++;
}
// Perform a sanity check: Old number of elements should match the new one!
// This check will fail if some previous operation corrupted this hashmap.
assert(_nele == old_nele);
delete[] old_arr;
return;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
int HashMap<Key, Val, HashFunc, EqualFunc>::lookup(const Key &key) const {
uint ctr = _hash(key) % _arrsize;
while (_arr[ctr] != NULL && !_equal(_arr[ctr]->_key, key)) {
ctr = (ctr + 1) % _arrsize;
#ifdef DEBUG_HASH_COLLISIONS
_collisions++;
#endif
}
#ifdef DEBUG_HASH_COLLISIONS
_lookups++;
fprintf(stderr, "collisions %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d\n",
_collisions, _lookups, ((double) _collisions / (double)_lookups),
(const void *)this, _arrsize, _nele);
#endif
return ctr;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
int HashMap<Key, Val, HashFunc, EqualFunc>::lookupAndCreateIfMissing(const Key &key) {
uint ctr = lookup(key);
if (_arr[ctr] == NULL) {
_arr[ctr] = allocNode(key);
_nele++;
// Keep the load factor below 75%.
if (_nele > _arrsize * 75 / 100) {
expand_array(nextTableSize(_arrsize));
ctr = lookup(key);
}
}
return ctr;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
bool HashMap<Key, Val, HashFunc, EqualFunc>::contains(const Key &key) const {
uint ctr = lookup(key);
return (_arr[ctr] != NULL);
}
template<class Key, class Val, class HashFunc, class EqualFunc>
Val &HashMap<Key, Val, HashFunc, EqualFunc>::operator[](const Key &key) {
return getVal(key);
}
template<class Key, class Val, class HashFunc, class EqualFunc>
const Val &HashMap<Key, Val, HashFunc, EqualFunc>::operator[](const Key &key) const {
return getVal(key);
}
template<class Key, class Val, class HashFunc, class EqualFunc>
Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) {
uint ctr = lookupAndCreateIfMissing(key);
assert(_arr[ctr] != NULL);
return _arr[ctr]->_value;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
const Val &HashMap<Key, Val, HashFunc, EqualFunc>::getVal(const Key &key) const {
uint ctr = lookup(key);
if (_arr[ctr] != NULL)
return _arr[ctr]->_value;
else
return _defaultVal;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::setVal(const Key &key, const Val &val) {
uint ctr = lookupAndCreateIfMissing(key);
assert(_arr[ctr] != NULL);
_arr[ctr]->_value = val;
}
template<class Key, class Val, class HashFunc, class EqualFunc>
void HashMap<Key, Val, HashFunc, EqualFunc>::erase(const Key &key) {
// This is based on code in the Wikipedia article on Hash tables.
uint i = lookup(key);
if (_arr[i] == NULL)
return; // key wasn't present, so no work has to be done
// If we remove a key, we must check all subsequent keys and possibly
// reinsert them.
uint j = i;
freeNode(_arr[i]);
_arr[i] = NULL;
while (true) {
// Look at the next table slot
j = (j + 1) % _arrsize;
// If the next slot is empty, we are done
if (_arr[j] == NULL)
break;
// Compute the slot where the content of the next slot should normally be,
// assuming an empty table, and check whether we have to move it.
uint k = _hash(_arr[j]->_key) % _arrsize;
if ((j > i && (k <= i || k > j)) ||
(j < i && (k <= i && k > j)) ) {
_arr[i] = _arr[j];
i = j;
}
}
_arr[i] = NULL;
_nele--;
return;
}
} // End of namespace Common
#endif

View File

@ -29,9 +29,9 @@ namespace Common {
/**
* Simple double linked list, modeled after the list template of the standard
* C++ library.
* C++ library.
*/
template <class t_T>
template<class t_T>
class List {
protected:
#if defined (_WIN32_WCE) || defined (_MSC_VER)
@ -42,16 +42,17 @@ public:
NodeBase *_prev;
NodeBase *_next;
};
template <class t_T2>
struct Node : public NodeBase {
t_T2 _data;
Node(const t_T2 &x) : _data(x) {}
};
template <class t_T2>
template<class t_T2>
class Iterator {
template<class T> friend class Iterator;
friend class List<t_T>;
NodeBase *_node;
@ -63,6 +64,14 @@ public:
public:
Iterator() : _node(0) {}
template<class T>
Iterator(const Iterator<T> &c) : _node(c._node) {}
template<class T>
Iterator<t_T2> &operator=(const Iterator<T> &c) {
_node = c._node;
return *this;
}
// Prefix inc
Iterator<t_T2> &operator++() {
@ -88,28 +97,30 @@ public:
--(*this);
return tmp;
}
t_T2& operator*() const {
t_T2 &operator*() const {
assert(_node);
#if (__GNUC__ == 2) && (__GNUC_MINOR__ >= 95)
return static_cast<List<t_T>::Node<t_T2> *>(_node)->_data;
#else
return static_cast<Node<t_T2>*>(_node)->_data;
return static_cast<Node<t_T2> *>(_node)->_data;
#endif
}
t_T2* operator->() const {
t_T2 *operator->() const {
return &(operator*());
}
bool operator==(const Iterator<t_T2>& x) const {
template<class T>
bool operator==(const Iterator<T> &x) const {
return _node == x._node;
}
bool operator!=(const Iterator<t_T2>& x) const {
template<class T>
bool operator!=(const Iterator<T> &x) const {
return _node != x._node;
}
};
NodeBase *_anchor;
NodeBase _anchor;
public:
typedef Iterator<t_T> iterator;
@ -119,41 +130,38 @@ public:
public:
List() {
_anchor = new NodeBase;
_anchor->_prev = _anchor;
_anchor->_next = _anchor;
_anchor._prev = &_anchor;
_anchor._next = &_anchor;
}
List(const List<t_T>& list) {
_anchor = new NodeBase;
_anchor->_prev = _anchor;
_anchor->_next = _anchor;
List(const List<t_T> &list) {
_anchor._prev = &_anchor;
_anchor._next = &_anchor;
insert(begin(), list.begin(), list.end());
}
~List() {
clear();
delete _anchor;
}
void push_front(const t_T& element) {
void push_front(const t_T &element) {
insert(begin(), element);
}
void push_back(const t_T& element) {
void push_back(const t_T &element) {
insert(end(), element);
}
void insert(iterator pos, const t_T& element) {
void insert(iterator pos, const t_T &element) {
NodeBase *newNode = new Node<t_T>(element);
newNode->_next = pos._node;
newNode->_prev = pos._node->_prev;
newNode->_prev->_next = newNode;
newNode->_next->_prev = newNode;
}
template <typename iterator2>
template<typename iterator2>
void insert(iterator pos, iterator2 first, iterator2 last) {
for (; first != last; ++first)
insert(pos, *first);
@ -200,7 +208,7 @@ public:
}
List<t_T>& operator =(const List<t_T>& list) {
List<t_T> &operator=(const List<t_T> &list) {
if (this != &list) {
iterator i;
const_iterator j;
@ -214,7 +222,7 @@ public:
else
erase(i, end());
}
return *this;
}
@ -228,34 +236,34 @@ public:
void clear() {
erase(begin(), end());
}
bool empty() const {
return (_anchor == _anchor->_next);
bool empty() const {
return (&_anchor == _anchor._next);
}
iterator begin() {
return iterator(_anchor->_next);
return iterator(_anchor._next);
}
iterator reverse_begin() {
return iterator(_anchor->_prev);
return iterator(_anchor._prev);
}
iterator end() {
return iterator(_anchor);
return iterator(&_anchor);
}
const_iterator begin() const {
return const_iterator(_anchor->_next);
return const_iterator(_anchor._next);
}
const_iterator reverse_begin() const {
return const_iterator(_anchor->_prev);
return const_iterator(_anchor._prev);
}
const_iterator end() const {
return const_iterator(_anchor);
return const_iterator(const_cast<NodeBase*>(&_anchor));
}
};

View File

@ -43,9 +43,8 @@ void Matrix3::buildFromPitchYawRoll(float pitch, float yaw, float roll) {
(*this) *= temp2;
}
#define MYPI 3.14159265358979323846
#define DEGTORAD(a) (a * MYPI / 180.0)
#define RADTODEG(a) (a * 180.0 / MYPI)
#define DEGTORAD(a) (a * LOCAL_PI / 180.0)
#define RADTODEG(a) (a * 180.0 / LOCAL_PI)
float RadianToDegree(float rad) {
return (float)RADTODEG(rad);

118
common/memorypool.cpp Normal file
View File

@ -0,0 +1,118 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2008 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "common/memorypool.h"
#include "common/util.h"
namespace Common {
static const size_t CHUNK_PAGE_SIZE = 32;
void* MemoryPool::allocPage() {
void* result = ::malloc(CHUNK_PAGE_SIZE * _chunkSize);
_pages.push_back(result);
void* current = result;
for (size_t i = 1; i < CHUNK_PAGE_SIZE; ++i) {
void* next = ((char*)current + _chunkSize);
*(void**)current = next;
current = next;
}
*(void**)current = NULL;
return result;
}
MemoryPool::MemoryPool(size_t chunkSize) {
// You must at least fit the pointer in the node (technically unneeded considering the next rounding statement)
_chunkSize = MAX(chunkSize, sizeof(void*));
// There might be an alignment problem on some platforms when trying to load a void* on a non natural boundary
// so we round to the next sizeof(void*)
_chunkSize = (_chunkSize + sizeof(void*) - 1) & (~(sizeof(void*) - 1));
_next = NULL;
}
MemoryPool::~MemoryPool() {
for (size_t i = 0; i<_pages.size(); ++i)
::free(_pages[i]);
}
void* MemoryPool::malloc() {
#if 1
if (!_next)
_next = allocPage();
void* result = _next;
_next = *(void**)result;
return result;
#else
return ::malloc(_chunkSize);
#endif
}
void MemoryPool::free(void* ptr) {
#if 1
*(void**)ptr = _next;
_next = ptr;
#else
::free(ptr);
#endif
}
// Technically not compliant C++ to compare unrelated pointers. In practice...
bool MemoryPool::isPointerInPage(void* ptr, void* page) {
return (ptr >= page) && (ptr < (char*)page + CHUNK_PAGE_SIZE * _chunkSize);
}
void MemoryPool::freeUnusedPages() {
//std::sort(_pages.begin(), _pages.end());
Array<size_t> numberOfFreeChunksPerPage;
numberOfFreeChunksPerPage.resize(_pages.size());
for (size_t i = 0; i < numberOfFreeChunksPerPage.size(); ++i) {
numberOfFreeChunksPerPage[i] = 0;
}
void* iterator = _next;
while (iterator) {
// This should be a binary search
for (size_t i = 0; i < _pages.size(); ++i) {
if (isPointerInPage(iterator, _pages[i])) {
++numberOfFreeChunksPerPage[i];
break;
}
}
iterator = *(void**)iterator;
}
size_t freedPagesCount = 0;
for (size_t i = 0; i < _pages.size(); ++i) {
if (numberOfFreeChunksPerPage[i] == CHUNK_PAGE_SIZE) {
::free(_pages[i]);
_pages[i] = NULL; // TODO : Remove NULL values
++freedPagesCount;
}
}
//printf("%d freed pages\n", freedPagesCount);
}
} // End of namespace Common

54
common/memorypool.h Normal file
View File

@ -0,0 +1,54 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2008 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_MEMORYPOOL_H
#define COMMON_MEMORYPOOL_H
#include "common/sys.h"
#include "common/array.h"
namespace Common {
class MemoryPool {
private:
MemoryPool(const MemoryPool&);
MemoryPool& operator=(const MemoryPool&);
size_t _chunkSize;
Array<void*> _pages;
void* _next;
void* allocPage();
bool isPointerInPage(void* ptr, void* page);
public:
MemoryPool(size_t chunkSize);
~MemoryPool();
void* malloc();
void free(void* ptr);
void freeUnusedPages();
};
} // End of namespace Common
#endif

14
common/module.mk Normal file
View File

@ -0,0 +1,14 @@
MODULE := common
MODULE_OBJS := \
debug.o \
hashmap.o \
matrix3.o \
matrix4.o \
memorypool.o \
str.o \
mutex.o \
zlib.o
# Include common rules
include $(srcdir)/rules.mk

View File

@ -1,388 +0,0 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2006 The ScummVM-Residual Team (www.scummvm.org)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_PLATFORM_H
#define COMMON_PLATFORM_H
#include "common/sys.h"
#include "common/vector3d.h"
#include <stdlib.h>
#include <stdio.h>
#ifndef __DC__
#include <SDL_byteorder.h>
#endif
// Use config.h, generated by configure
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#ifndef PI
#define PI 3.14159265358979323846
#endif
#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
template<typename T> inline T ABS (T x) { return (x>=0) ? x : -x; }
template<typename T> inline T MIN (T a, T b) { return (a<b) ? a : b; }
template<typename T> inline T MAX (T a, T b) { return (a>b) ? a : b; }
#ifndef round
#define round(x) ((x > 0.0) ? floor((x) + 0.5) : ceil((x) - 0.5))
#endif
#if defined(_MSC_VER)
#define snprintf _snprintf
#if defined(CHECK_HEAP)
#undef CHECK_HEAP
#define CHECK_HEAP checkHeap();
#else
#define CHECK_HEAP
#endif
#define SYSTEM_LITTLE_ENDIAN
#define FORCEINLINE __forceinline
#define NORETURN _declspec(noreturn)
typedef unsigned char byte;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned long uint32;
typedef unsigned int uint;
typedef signed char int8;
typedef signed short int16;
typedef signed long int32;
#define START_PACK_STRUCTS pack(push, 1)
#define END_PACK_STRUCTS pack(pop)
#define GCC_PACK
#elif defined(__MINGW32__)
#define CHECK_HEAP
#define SYSTEM_LITTLE_ENDIAN
#define NORETURN __attribute__((__noreturn__))
#define GCC_PACK __attribute__((packed))
#define _HEAPOK 0
typedef unsigned char byte;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned int uint;
typedef signed char int8;
typedef signed short int16;
typedef signed int int32;
#define START_PACK_STRUCTS pack (push, 1)
#define END_PACK_STRUCTS pack(pop)
#elif defined(UNIX)
#define CHECK_HEAP
#ifdef X11_BACKEND
// You need to set this manually if necessary
// #define SYSTEM_LITTLE_ENDIAN
#else
/* need this for the SDL_BYTEORDER define */
#include <SDL_byteorder.h>
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
#define SYSTEM_LITTLE_ENDIAN
#elif SDL_BYTEORDER == SDL_BIG_ENDIAN
#define SYSTEM_BIG_ENDIAN
#else
#error Neither SDL_BIG_ENDIAN nor SDL_LIL_ENDIAN is set.
#endif
#endif
// You need to set this manually if necessary
// #define SYSTEM_NEED_ALIGNMENT
#define FORCEINLINE inline
#define CDECL
#ifndef HAVE_CONFIG_H
typedef unsigned char byte;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint;
typedef unsigned int uint32;
typedef signed char int8;
typedef signed short int16;
typedef signed int int32;
#endif
#if defined(__DECCXX) // Assume alpha architecture
#define INVERSE_MKID
#define SYSTEM_NEED_ALIGNMENT
#endif
#if defined(__GNUC__)
#define START_PACK_STRUCTS
#define END_PACK_STRUCTS
#define GCC_PACK __attribute__((packed))
#define NORETURN __attribute__((__noreturn__))
#else
#define START_PACK_STRUCTS pack (1)
#define END_PACK_STRUCTS pack ()
#define GCC_PACK
#define NORETURN
#endif
#ifdef __FreeBSD__
#undef ROUND
#define ROUND(x) rint(x)
#endif
#if defined(__APPLE__) && defined(__MACH__)
#define MACOSX
#endif
#elif defined(__MORPHOS__)
#define scumm_stricmp stricmp
#define scumm_strnicmp strnicmp
#define CHECK_HEAP
#define SYSTEM_BIG_ENDIAN
#define SYSTEM_NEED_ALIGNMENT
#define FORCEINLINE inline
#define CDECL
typedef unsigned char byte;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned long uint32;
typedef unsigned int uint;
typedef signed char int8;
typedef signed short int16;
typedef signed long int32;
#if defined(__GNUC__)
#define START_PACK_STRUCTS
#define END_PACK_STRUCTS
#define GCC_PACK __attribute__((packed))
#define NORETURN __attribute__((__noreturn__))
#else
#define START_PACK_STRUCTS pack (1)
#define END_PACK_STRUCTS pack ()
#define GCC_PACK
#define NORETURN
#endif
#define main morphos_main
#elif defined(__DC__)
#define CHECK_HEAP
#define SYSTEM_LITTLE_ENDIAN
#define SYSTEM_NEED_ALIGNMENT
#define FORCEINLINE inline
#define NORETURN __attribute__((__noreturn__))
#define GCC_PACK __attribute__((packed))
#define CDECL
typedef unsigned char byte;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned long uint32;
typedef unsigned int uint;
typedef signed char int8;
typedef signed short int16;
typedef signed long int32;
#define START_PACK_STRUCTS pack (push, 1)
#define END_PACK_STRUCTS pack(pop)
#else
#error No system type defined
#endif
FORCEINLINE uint32 SWAP_BYTES_32(uint32 a) {
return ((a >> 24) & 0x000000FF) |
((a >> 8) & 0x0000FF00) |
((a << 8) & 0x00FF0000) |
((a << 24) & 0xFF000000);
}
FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) {
return ((a >> 8) & 0x00FF) + ((a << 8) & 0xFF00);
}
#if defined(SYSTEM_LITTLE_ENDIAN)
#define PROTO_MKID(a) ((uint32) \
(((a) >> 24) & 0x000000FF) | \
(((a) >> 8) & 0x0000FF00) | \
(((a) << 8) & 0x00FF0000) | \
(((a) << 24) & 0xFF000000))
#define PROTO_MKID_BE(a) ((uint32)(a))
#if defined(INVERSE_MKID)
# define MKID(a) PROTO_MKID_BE(a)
# define MKID_BE(a) PROTO_MKID(a)
#else
# define MKID(a) PROTO_MKID(a)
# define MKID_BE(a) PROTO_MKID_BE(a)
#endif
#define READ_UINT32(a) READ_LE_UINT32(a)
#define FROM_LE_32(a) ((uint32)(a))
#define FROM_LE_16(a) ((uint16)(a))
#define TO_LE_32(a) ((uint32)(a))
#define TO_LE_16(a) ((uint16)(a))
#define TO_BE_32(a) SWAP_BYTES_32(a)
#define TO_BE_16(a) SWAP_BYTES_16(a)
#elif defined(SYSTEM_BIG_ENDIAN)
#define MKID(a) ((uint32)(a))
#define MKID_BE(a) ((uint32)(a))
#define READ_UINT32(a) READ_BE_UINT32(a)
#define FROM_LE_32(a) SWAP_BYTES_32(a)
#define FROM_LE_16(a) SWAP_BYTES_16(a)
#define TO_LE_32(a) SWAP_BYTES_32(a)
#define TO_LE_16(a) SWAP_BYTES_16(a)
#define TO_BE_32(a) ((uint32)(a))
#define TO_BE_16(a) ((uint16)(a))
#else
#error No endianness defined
#endif
#if defined(SYSTEM_NEED_ALIGNMENT) || defined(SYSTEM_BIG_ENDIAN)
FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) {
const byte *b = (const byte *)ptr;
return (b[1] << 8) + b[0];
}
FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) {
const byte *b = (const byte *)ptr;
return (b[3] << 24) + (b[2] << 16) + (b[1] << 8) + (b[0]);
}
FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) {
byte *b = (byte *)ptr;
b[0] = (byte)(value >> 0);
b[1] = (byte)(value >> 8);
}
FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) {
byte *b = (byte *)ptr;
b[0] = (byte)(value >> 0);
b[1] = (byte)(value >> 8);
b[2] = (byte)(value >> 16);
b[3] = (byte)(value >> 24);
}
#else
FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) {
return *(const uint16 *)(ptr);
}
FORCEINLINE uint32 READ_LE_UINT32(const void *ptr) {
return *(const uint32 *)(ptr);
}
FORCEINLINE void WRITE_LE_UINT16(void *ptr, uint16 value) {
*(uint16 *)(ptr) = value;
}
FORCEINLINE void WRITE_LE_UINT32(void *ptr, uint32 value) {
*(uint32 *)(ptr) = value;
}
#endif
#if defined(SYSTEM_NEED_ALIGNMENT) || defined(SYSTEM_LITTLE_ENDIAN)
FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) {
const byte *b = (const byte *)ptr;
return (b[0] << 8) + b[1];
}
FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) {
const byte *b = (const byte*)ptr;
return (b[0] << 24) + (b[1] << 16) + (b[2] << 8) + (b[3]);
}
FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) {
byte *b = (byte *)ptr;
b[0] = (byte)(value >> 8);
b[1] = (byte)(value >> 0);
}
FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) {
byte *b = (byte *)ptr;
b[0] = (byte)(value >> 24);
b[1] = (byte)(value >> 16);
b[2] = (byte)(value >> 8);
b[3] = (byte)(value >> 0);
}
#else
FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) {
return *(const uint16 *)(ptr);
}
FORCEINLINE uint32 READ_BE_UINT32(const void *ptr) {
return *(const uint32 *)(ptr);
}
FORCEINLINE void WRITE_BE_UINT16(void *ptr, uint16 value) {
*(uint16 *)(ptr) = value;
}
FORCEINLINE void WRITE_BE_UINT32(void *ptr, uint32 value) {
*(uint32 *)(ptr) = value;
}
#endif
#if defined(SYSTEM_BIG_ENDIAN)
inline float get_float(const char *data) {
const unsigned char *udata = reinterpret_cast<const unsigned char *>(data);
unsigned char fdata[4];
fdata[0] = udata[3];
fdata[1] = udata[2];
fdata[2] = udata[1];
fdata[3] = udata[0];
return *(reinterpret_cast<const float *>(fdata));
}
#else
inline float get_float(const char *data) {
return *(reinterpret_cast<const float *>(data));
}
#endif
inline Vector3d get_vector3d(const char *data) {
return Vector3d(get_float(data), get_float(data + 4), get_float(data + 8));
}
#endif

484
common/str.cpp Normal file
View File

@ -0,0 +1,484 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2008 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#include "common/str.h"
#include "common/hash-str.h"
#include "common/util.h"
namespace Common {
#if !(defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
const String String::emptyString;
#else
const char *String::emptyString = "";
#endif
static int computeCapacity(int len) {
// By default, for the capacity we use the nearest multiple of 32
// that leaves at least 16 chars of extra space (in case the string
// grows a bit).
// Finally, we subtract 1 to compensate for the trailing zero byte.
len += 16;
return ((len + 32 - 1) & ~0x1F) - 1;
}
String::String(const char *str, uint32 len)
: _len(0), _str(_storage) {
// Init _storage member explicitly (ie. without calling its constructor)
// for GCC 2.95.x compatibility (see also tracker item #1602879).
_storage[0] = 0;
if (str && *str) {
const uint32 tmp = strlen(str);
assert(len <= tmp);
if (len <= 0)
len = tmp;
_len = len;
if (len >= _builtinCapacity) {
// Not enough internal storage, so allocate more
_extern._capacity = computeCapacity(len);
_extern._refCount = 0;
_str = (char *)malloc(_extern._capacity+1);
assert(_str != 0);
}
// Copy the string into the storage area
memcpy(_str, str, len);
_str[len] = 0;
}
}
String::String(const String &str)
: _len(str._len), _str(str.isStorageIntern() ? _storage : str._str) {
if (str.isStorageIntern()) {
// String in internal storage: just copy it
memcpy(_storage, str._storage, _builtinCapacity);
} else {
// String in external storage: use refcount mechanism
str.incRefCount();
_extern._refCount = str._extern._refCount;
_extern._capacity = str._extern._capacity;
}
assert(_str != 0);
}
String::String(char c)
: _len(0), _str(_storage) {
_storage[0] = c;
_storage[1] = 0;
_len = (c == 0) ? 0 : 1;
}
String::~String() {
decRefCount(_extern._refCount);
}
void String::incRefCount() const {
assert(!isStorageIntern());
if (_extern._refCount == 0) {
_extern._refCount = new int(2);
} else {
++(*_extern._refCount);
}
}
void String::decRefCount(int *oldRefCount) {
if (isStorageIntern())
return;
if (oldRefCount) {
--(*oldRefCount);
}
if (!oldRefCount || *oldRefCount <= 0) {
// The ref count reached zero, so we free the string storage
// and the ref count storage.
delete oldRefCount;
free(_str);
// Even though _str points to a freed memory block now,
// we do not change its value, because any code that calls
// decRefCount will have to do this afterwards anyway.
}
}
String& String::operator =(const char *str) {
uint32 len = strlen(str);
ensureCapacity(len, false);
_len = len;
memcpy(_str, str, len + 1);
return *this;
}
String &String::operator =(const String &str) {
if (str.isStorageIntern()) {
decRefCount(_extern._refCount);
_len = str._len;
_str = _storage;
memcpy(_str, str._str, _len + 1);
} else {
str.incRefCount();
decRefCount(_extern._refCount);
_extern._refCount = str._extern._refCount;
_extern._capacity = str._extern._capacity;
_len = str._len;
_str = str._str;
}
return *this;
}
String& String::operator =(char c) {
ensureCapacity(1, false);
_len = 1;
_str[0] = c;
_str[1] = 0;
return *this;
}
String &String::operator +=(const char *str) {
int len = strlen(str);
if (len > 0) {
ensureCapacity(_len + len, true);
memcpy(_str + _len, str, len + 1);
_len += len;
}
return *this;
}
String &String::operator +=(const String &str) {
int len = str._len;
if (len > 0) {
ensureCapacity(_len + len, true);
memcpy(_str + _len, str._str, len + 1);
_len += len;
}
return *this;
}
String &String::operator +=(char c) {
ensureCapacity(_len + 1, true);
_str[_len++] = c;
_str[_len] = 0;
return *this;
}
bool String::hasPrefix(const char *x) const {
assert(x != 0);
// Compare x with the start of _str.
const char *y = c_str();
while (*x && *x == *y) {
++x;
++y;
}
// It's a prefix, if and only if all letters in x are 'used up' before
// _str ends.
return *x == 0;
}
bool String::hasSuffix(const char *x) const {
assert(x != 0);
// Compare x with the end of _str.
const uint32 x_len = strlen(x);
if (x_len > _len)
return false;
const char *y = c_str() + _len - x_len;
while (*x && *x == *y) {
++x;
++y;
}
// It's a suffix, if and only if all letters in x are 'used up' before
// _str ends.
return *x == 0;
}
bool String::contains(const char *x) const {
assert(x != 0);
return strstr(c_str(), x) != NULL;
}
bool String::contains(char x) const {
return strchr(c_str(), x) != NULL;
}
void String::deleteLastChar() {
deleteChar(_len - 1);
}
void String::deleteChar(uint32 p) {
assert(p < _len);
// Call ensureCapacity to make sure we actually *own* the storage
// to which _str points to -- we wouldn't want to modify a storage
// which other string objects are sharing, after all.
ensureCapacity(_len, true);
while (p++ < _len)
_str[p-1] = _str[p];
_len--;
}
void String::clear() {
decRefCount(_extern._refCount);
_len = 0;
_str = _storage;
_storage[0] = 0;
}
void String::setChar(char c, uint32 p) {
assert(p <= _len);
ensureCapacity(_len, true);
_str[p] = c;
}
void String::insertChar(char c, uint32 p) {
assert(p <= _len);
ensureCapacity(_len + 1, true);
_len++;
for (uint32 i = _len; i > p; --i)
_str[i] = _str[i-1];
_str[p] = c;
}
void String::toLowercase() {
ensureCapacity(_len, true);
for (uint32 i = 0; i < _len; ++i)
_str[i] = tolower(_str[i]);
}
void String::toUppercase() {
ensureCapacity(_len, true);
for (uint32 i = 0; i < _len; ++i)
_str[i] = toupper(_str[i]);
}
/**
* Ensure that enough storage is available to store at least new_len
* characters plus a null byte. In addition, if we currently share
* the storage with another string, unshare it, so that we can safely
* write to the storage.
*/
void String::ensureCapacity(uint32 new_len, bool keep_old) {
bool isShared;
uint32 curCapacity, newCapacity;
char *newStorage;
int *oldRefCount = _extern._refCount;
if (isStorageIntern()) {
isShared = false;
curCapacity = _builtinCapacity - 1;
} else {
isShared = (oldRefCount && *oldRefCount > 1);
curCapacity = _extern._capacity;
}
// Special case: If there is enough space, and we do not share
// the storage, then there is nothing to do.
if (!isShared && new_len <= curCapacity)
return;
if (isShared && new_len <= _builtinCapacity - 1) {
// We share the storage, but there is enough internal storage: Use that.
newStorage = _storage;
newCapacity = _builtinCapacity - 1;
} else {
// We need to allocate storage on the heap!
// Compute a suitable new capacity limit
newCapacity = computeCapacity(new_len);
// Allocate new storage
newStorage = (char *)malloc(newCapacity+1);
assert(newStorage);
}
// Copy old data if needed, elsewise reset the new storage.
if (keep_old) {
assert(_len <= newCapacity);
memcpy(newStorage, _str, _len + 1);
} else {
_len = 0;
newStorage[0] = 0;
}
// Release hold on the old storage ...
decRefCount(oldRefCount);
// ... in favor of the new storage
_str = newStorage;
if (!isStorageIntern()) {
// Set the ref count & capacity if we use an external storage.
// It is important to do this *after* copying any old content,
// else we would override data that has not yet been copied!
_extern._refCount = 0;
_extern._capacity = newCapacity;
}
}
uint String::hash() const {
return hashit(c_str());
}
#pragma mark -
bool String::operator ==(const String &x) const {
return equals(x);
}
bool String::operator ==(const char *x) const {
assert(x != 0);
return equals(x);
}
bool String::operator !=(const String &x) const {
return !equals(x);
}
bool String::operator !=(const char *x) const {
assert(x != 0);
return !equals(x);
}
bool String::operator < (const String &x) const {
return compareTo(x) < 0;
}
bool String::operator <= (const String &x) const {
return compareTo(x) <= 0;
}
bool String::operator > (const String &x) const {
return compareTo(x) > 0;
}
bool String::operator >= (const String &x) const {
return compareTo(x) >= 0;
}
#pragma mark -
bool operator == (const char* y, const String &x) {
return (x == y);
}
bool operator != (const char* y, const String &x) {
return x != y;
}
#pragma mark -
bool String::equals(const String &x) const {
return (0 == compareTo(x));
}
bool String::equals(const char *x) const {
assert(x != 0);
return (0 == compareTo(x));
}
bool String::equalsIgnoreCase(const String &x) const {
return (0 == compareToIgnoreCase(x));
}
bool String::equalsIgnoreCase(const char *x) const {
assert(x != 0);
return (0 == compareToIgnoreCase(x));
}
int String::compareTo(const String &x) const {
return compareTo(x.c_str());
}
int String::compareTo(const char *x) const {
assert(x != 0);
return strcmp(c_str(), x);
}
int String::compareToIgnoreCase(const String &x) const {
return compareToIgnoreCase(x.c_str());
}
int String::compareToIgnoreCase(const char *x) const {
assert(x != 0);
return strcasecmp(c_str(), x);
}
#pragma mark -
String operator +(const String &x, const String &y) {
String temp(x);
temp += y;
return temp;
}
String operator +(const char *x, const String &y) {
String temp(x);
temp += y;
return temp;
}
String operator +(const String &x, const char *y) {
String temp(x);
temp += y;
return temp;
}
String operator +(char x, const String &y) {
String temp(x);
temp += y;
return temp;
}
String operator +(const String &x, char y) {
String temp(x);
temp += y;
return temp;
}
char *ltrim(char *t) {
while (isspace(*t))
t++;
return t;
}
char *rtrim(char *t) {
int l = strlen(t) - 1;
while (l >= 0 && isspace(t[l]))
t[l--] = 0;
return t;
}
char *trim(char *t) {
return rtrim(ltrim(t));
}
} // End of namespace Common

224
common/str.h Normal file
View File

@ -0,0 +1,224 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2008 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef COMMON_STRING_H
#define COMMON_STRING_H
#include "common/sys.h"
#include "common/array.h"
namespace Common {
/**
* Simple string class for ScummVM. Provides automatic storage managment,
* and overloads several operators in a 'natural' fashion, mimicking
* the std::string class. Even provides simple iterators.
*
* This class tries to avoid allocating lots of small blocks on the heap,
* since that is inefficient on several platforms supported by ScummVM.
* Instead, small strings are stored 'inside' the string object (i.e. on
* the stack, for stack allocated objects), and only for strings exceeding
* a certain length do we allocate a buffer on the heap.
*/
class String {
protected:
/**
* The size of the internal storage. Increasing this means less heap
* allocations are needed, at the cost of more stack memory usage,
* and of course lots of wasted memory. Empirically, 90% or more of
* all String instances are less than 32 chars long. If a platform
* is very short on stack space, it would be possible to lower this.
* A value of 24 still seems acceptable, though considerably worse,
* while 16 seems to be the lowest you want to go... Anything lower
* than 8 makes no sense, since that's the size of member _extern
* (on 32 bit machines; 12 bytes on systems with 64bit pointers).
*/
static const uint32 _builtinCapacity = 32;
/**
* Length of the string. Stored to avoid having to call strlen
* a lot. Yes, we limit ourselves to strings shorter than 4GB --
* on purpose :-).
*/
uint32 _len;
/**
* Pointer to the actual string storage. Either points to _storage,
* or to a block allocated on the heap via malloc.
*/
char *_str;
union {
/**
* Internal string storage.
*/
char _storage[_builtinCapacity];
/**
* External string storage data -- the refcounter, and the
* capacity of the string _str points to.
*/
struct {
mutable int *_refCount;
uint32 _capacity;
} _extern;
};
inline bool isStorageIntern() const {
return _str == _storage;
}
public:
#if !(defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
static const String emptyString;
#else
static const char *emptyString;
#endif
String() : _len(0), _str(_storage) { _storage[0] = 0; }
String(const char *str, uint32 len = 0);
String(const String &str);
String(char c);
~String();
String &operator =(const char *str);
String &operator =(const String &str);
String &operator =(char c);
String &operator +=(const char *str);
String &operator +=(const String &str);
String &operator +=(char c);
bool operator ==(const String &x) const;
bool operator ==(const char *x) const;
bool operator !=(const String &x) const;
bool operator !=(const char *x) const;
bool operator <(const String &x) const;
bool operator <=(const String &x) const;
bool operator >(const String &x) const;
bool operator >=(const String &x) const;
bool equals(const String &x) const;
bool equalsIgnoreCase(const String &x) const;
int compareTo(const String &x) const; // strcmp clone
int compareToIgnoreCase(const String &x) const; // stricmp clone
bool equals(const char *x) const;
bool equalsIgnoreCase(const char *x) const;
int compareTo(const char *x) const; // strcmp clone
int compareToIgnoreCase(const char *x) const; // stricmp clone
bool hasSuffix(const char *x) const;
bool hasPrefix(const char *x) const;
bool contains(const char *x) const;
bool contains(char x) const;
inline const char *c_str() const { return _str; }
inline uint size() const { return _len; }
inline bool empty() const { return (_len == 0); }
char lastChar() const { return (_len > 0) ? _str[_len-1] : 0; }
char operator [](int idx) const {
assert(_str && idx >= 0 && idx < (int)_len);
return _str[idx];
}
/** Remove the last character from the string. */
void deleteLastChar();
/** Remove the character at position p from the string. */
void deleteChar(uint32 p);
/** Set character c at position p, replacing the previous character there. */
void setChar(char c, uint32 p);
/** Set character c at position p. */
void insertChar(char c, uint32 p);
void clear();
void toLowercase();
void toUppercase();
uint hash() const;
public:
typedef char * iterator;
typedef const char * const_iterator;
iterator begin() {
return _str;
}
iterator end() {
return begin() + size();
}
const_iterator begin() const {
return _str;
}
const_iterator end() const {
return begin() + size();
}
protected:
void ensureCapacity(uint32 new_len, bool keep_old);
void incRefCount() const;
void decRefCount(int *oldRefCount);
};
// Append two strings to form a new (temp) string
String operator +(const String &x, const String &y);
String operator +(const char *x, const String &y);
String operator +(const String &x, const char *y);
String operator +(const String &x, char y);
String operator +(char x, const String &y);
// Some useful additional comparision operators for Strings
bool operator == (const char *x, const String &y);
bool operator != (const char *x, const String &y);
// Utility functions to remove leading and trailing whitespaces
extern char *ltrim(char *t);
extern char *rtrim(char *t);
extern char *trim(char *t);
class StringList : public Array<String> {
public:
void push_back(const char *str) {
ensureCapacity(_size + 1);
_data[_size++] = str;
}
void push_back(const String &str) {
ensureCapacity(_size + 1);
_data[_size++] = str;
}
};
} // End of namespace Common
#endif

View File

@ -23,107 +23,250 @@
#ifndef COMMON_SYS_H
#define COMMON_SYS_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <math.h>
extern "C" int residual_main(int argc, char *argv[]);
#ifndef _MSC_VER
#include <stdint.h>
#include <dirent.h>
#include <unistd.h>
#endif
#if defined(WIN32)
#ifdef _MSC_VER
#pragma once
#pragma warning( disable : 4068 ) // turn off "unknown pragma" warning
#pragma warning( disable : 4244 ) // turn off "conversion type" warning
#endif
#if !defined(_WIN32_WCE)
#ifndef LOCAL_PI
#define LOCAL_PI 3.14159265358979323846
#endif
// Use config.h, generated by configure
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define NOGDICAPMASKS
#define OEMRESOURCE
#define NONLS
#define NOICONS
#define NOMCX
#define NOPROFILER
#define NOKANJI
#define NOSERVICE
#define NOMETAFILE
#define NOCOMM
#define NOCRYPT
#define NOIME
#define NOATOM
#define NOCTLMGR
#define NOCLIPBOARD
#define NOMEMMGR
#define NOSYSMETRICS
#define NOMENUS
#define NOOPENFILE
#define NOWH
#define NOSOUND
#define NODRAWTEXT
// In the following we configure various targets, in particular those
// which can't use our "configure" tool and hence don't use config.h.
//
// Some #defines that occur here frequently:
// SYSTEM_LITTLE_ENDIAN
// - Define this on a little endian target
// SYSTEM_BIG_ENDIAN
// - Define this on a big endian target
// SYSTEM_NEED_ALIGNMENT
// - Define this if your system has problems reading e.g. an int32 from an odd address
// SYSTEM_USE_LONG_INT
// - Define this if your port needs to use 'long' for the int32 datatype
// (i.e. an integer with exactly 32 bits).
// SYSTEM_DONT_DEFINE_TYPES
// - Define this if you need to provide your own typedefs, e.g. because your
// system headers conflict with our typenames, or because you have odd
// type requirements.
// SMALL_SCREEN_DEVICE
// - ...
// ...
// We define all types in config.h, so we don't want to typedef those types
// here again!
#ifdef HAVE_CONFIG_H
#define SYSTEM_DONT_DEFINE_TYPES
#endif
#include <windows.h>
#if defined(ARRAYSIZE)
// VS2005beta2 introduces new stuff in winnt.h
#undef ARRAYSIZE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <stdarg.h>
#include <fcntl.h>
#include <conio.h>
#include <assert.h>
#include <mmsystem.h>
#include <ctype.h>
#include <winuser.h>
#include <direct.h>
#define strcasecmp stricmp
#define M_PI 3.14159265358979323846
#if defined(__SYMBIAN32__)
#ifndef _MSC_VER
#include <stdint.h>
#include <dirent.h>
#define strcasecmp stricmp
#define SYSTEM_LITTLE_ENDIAN
#define SYSTEM_NEED_ALIGNMENT
#define SMALL_SCREEN_DEVICE
// Enable Symbians own datatypes
// This is done for two reasons
// a) uint is already defined by Symbians libc component
// b) Symbian is using its "own" datatyping, and the Scummvm port
// should follow this to ensure the best compability possible.
#define SYSTEM_DONT_DEFINE_TYPES
typedef unsigned char byte;
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned short int uint16;
typedef signed short int int16;
typedef unsigned long int uint32;
typedef signed long int int32;
#elif defined(_WIN32_WCE)
#define strcasecmp stricmp
#define SYSTEM_LITTLE_ENDIAN
#define SYSTEM_NEED_ALIGNMENT
#define SMALL_SCREEN_DEVICE
typedef signed char int8_t;
typedef signed short int16_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
#elif defined(_MSC_VER)
#define strcasecmp stricmp
#define SYSTEM_LITTLE_ENDIAN
typedef signed char int8_t;
typedef signed short int16_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
#elif defined(__MINGW32__)
#define strcasecmp stricmp
#define SYSTEM_LITTLE_ENDIAN
#elif defined(UNIX)
#ifndef CONFIG_H
/* need this for the SDL_BYTEORDER define */
#include <SDL_byteorder.h>
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
#define SCUMM_LITTLE_ENDIAN
#elif SDL_BYTEORDER == SDL_BIG_ENDIAN
#define SCUMM_BIG_ENDIAN
#else
#error Neither SDL_BIG_ENDIAN nor SDL_LIL_ENDIAN is set.
#endif
#endif
// You need to set this manually if necessary
// #define SYSTEM_NEED_ALIGNMENT
#if defined(__DECCXX) // Assume alpha architecture
#define INVERSE_MKID
#define SYSTEM_NEED_ALIGNMENT
#endif
#elif defined(__PALMOS_TRAPS__) || defined (__PALMOS_ARMLET__)
#ifdef __PALMOS_ARMLET__
#include <extras_string.h>
#endif
#define SYSTEM_LITTLE_ENDIAN
#define strcasecmp stricmp
#define SYSTEM_NEED_ALIGNMENT
#define STRINGBUFLEN 256
#elif defined(__DC__)
#define SYSTEM_LITTLE_ENDIAN
#define SYSTEM_NEED_ALIGNMENT
#elif defined(__PLAYSTATION2__)
#define SYSTEM_LITTLE_ENDIAN
#define SYSTEM_NEED_ALIGNMENT
#elif defined(__PSP__)
#define SYSTEM_LITTLE_ENDIAN
#define SYSTEM_NEED_ALIGNMENT
#elif defined(__amigaos4__)
#define SYSTEM_BIG_ENDIAN
#define SYSTEM_NEED_ALIGNMENT
#elif defined (__DS__) //NeilM
#define strcasecmp stricmp
#define SYSTEM_NEED_ALIGNMENT
#define SYSTEM_LITTLE_ENDIAN
#include "nds/jtypes.h"
#define SYSTEM_DONT_DEFINE_TYPES
#define STRINGBUFLEN 256
#define printf(fmt, ...) consolePrintf(fmt, ##__VA_ARGS__)
#elif defined(__WII__)
#define SYSTEM_BIG_ENDIAN
#define SYSTEM_NEED_ALIGNMENT
#else
#if defined(__MORPHOS__)
#include <devices/timer.h>
#undef CMD_INVALID
#endif
#if !defined(macintosh)
#include <sys/types.h>
#if !defined(__DC__)
#include <sys/uio.h>
#endif
#endif
#if !defined (__BEOS__)
#include <unistd.h>
#endif
#if defined(__QNXNTO__)
#include <strings.h> /* For strcasecmp */
#endif
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#if defined(__DC__)
#include <ronin/cdfs.h>
#else
#include <dirent.h>
#endif
#error No system type defined
#endif
//
// Typedef our system types unless SYSTEM_DONT_DEFINE_TYPES is set.
//
#ifndef SYSTEM_DONT_DEFINE_TYPES
typedef unsigned char byte;
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned short uint16;
typedef signed short int16;
#ifdef SYSTEM_USE_LONG_INT
typedef unsigned long uint32;
typedef signed long int32;
typedef unsigned long uint;
#else
typedef unsigned int uint32;
typedef signed int int32;
typedef unsigned int uint;
#endif
#endif
//
// Fallbacks / default values for various special macros
//
#ifndef FORCEINLINE
#define FORCEINLINE inline
#endif
#ifndef NORETURN
#define NORETURN
#endif
#ifndef STRINGBUFLEN
#define STRINGBUFLEN 1024
#endif
#ifndef MAXPATHLEN
#define MAXPATHLEN 256
#endif
#ifndef CDECL
#define CDECL
#endif
#ifndef NORETURN
#define NORETURN
#endif
#endif // COMMON_SYS_H

60
common/util.h Normal file
View File

@ -0,0 +1,60 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef COMMON_UTIL_H
#define COMMON_UTIL_H
#include "common/sys.h"
#ifdef MIN
#undef MIN
#endif
#ifdef MAX
#undef MAX
#endif
template<typename T> inline T ABS (T x) { return (x>=0) ? x : -x; }
template<typename T> inline T MIN (T a, T b) { return (a<b) ? a : b; }
template<typename T> inline T MAX (T a, T b) { return (a>b) ? a : b; }
template<typename T> inline T CLIP (T v, T amin, T amax)
{ if (v < amin) return amin; else if (v > amax) return amax; else return v; }
/**
* Template method which swaps the vaulues of its two parameters.
*/
template<typename T> inline void SWAP(T &a, T &b) { T tmp = a; a = b; b = tmp; }
#if defined(ARRAYSIZE)
// VS2005beta2 introduces new stuff in winnt.h
#undef ARRAYSIZE
#endif
#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
#ifndef round
#define round(x) ((x > 0.0) ? floor((x) + 0.5) : ceil((x) - 0.5))
#endif
#endif

View File

@ -24,10 +24,7 @@
#define COMMON_VECTOR3D_H
#include <cmath>
#ifndef PI
#define PI 3.14159265358979323846
#endif
#include <common/sys.h>
class Vector3d {
public:
@ -40,18 +37,18 @@ public:
float& z() { return _coords[2]; }
float z() const { return _coords[2]; }
Vector3d() { this->x() = 0; this->y() = 0; this->z() = 0; }
Vector3d() { x() = 0; y() = 0; z() = 0; }
Vector3d(float x, float y, float z) {
this->x() = x; this->y() = y; this->z() = z;
Vector3d(float lx, float ly, float lz) {
x() = lx; y() = ly; z() = lz;
}
Vector3d(const Vector3d &v) {
x() = v.x(); y() = v.y(); z() = v.z();
}
void set(float x, float y, float z) {
this->x() = x; this->y() = y; this->z() = z;
void set(float lx, float ly, float lz) {
x() = lx; y() = ly; z() = lz;
}
Vector3d& operator =(const Vector3d &v) {
@ -99,7 +96,7 @@ public:
float yaw;
// find the angle on the upper half of the unit circle
yaw = std::acos(a) * (180.0f / (float)PI);
yaw = std::acos(a) * (180.0f / LOCAL_PI);
if (b < 0.0f)
// adjust for the lower half of the unit circle
return 360.0f - yaw;
@ -169,4 +166,28 @@ inline bool operator ==(const Vector3d& v1, const Vector3d& v2) {
return v1.x() == v2.x() && v1.y() == v2.y() && v1.z() == v2.z();
}
#if defined(SYSTEM_BIG_ENDIAN)
inline float get_float(const char *data) {
const unsigned char *udata = reinterpret_cast<const unsigned char *>(data);
unsigned char fdata[4];
fdata[0] = udata[3];
fdata[1] = udata[2];
fdata[2] = udata[1];
fdata[3] = udata[0];
return *(reinterpret_cast<const float *>(fdata));
}
#else
inline float get_float(const char *data) {
return *(reinterpret_cast<const float *>(data));
}
#endif
inline Vector3d get_vector3d(const char *data) {
return Vector3d(get_float(data), get_float(data + 4), get_float(data + 8));
}
#endif

41
common/zlib.cpp Normal file
View File

@ -0,0 +1,41 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2008 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#include "common/zlib.h"
#if defined(USE_ZLIB)
#ifdef __SYMBIAN32__
#include <zlib\zlib.h>
#else
#include <zlib.h>
#endif
namespace Common {
int uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long srcLen) {
return ::uncompress(dst, dstLen, src, srcLen);
}
} // end of namespace Common
#endif

48
common/zlib.h Normal file
View File

@ -0,0 +1,48 @@
/* Residual - Virtual machine to run LucasArts' 3D adventure games
* Copyright (C) 2003-2008 The ScummVM-Residual Team (www.scummvm.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#include "common/sys.h"
#if defined(USE_ZLIB)
#ifndef COMMON_ZLIB_H
#define COMMON_ZLIB_H
#ifdef __SYMBIAN32__
#include <zlib\zlib.h>
#else
#include <zlib.h>
#endif
namespace Common {
enum {
ZLIB_OK = Z_OK
};
int uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long srcLen);
} // end of namespace Common
#endif
#endif

1516
config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

1626
config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

1238
configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -20,11 +20,11 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "ScummVM Team\0"
VALUE "CompanyName", "ScummVM-Residual Team\0"
VALUE "FileDescription", "http://www.scummvm.org/\0"
VALUE "FileVersion", "SVN\0"
VALUE "InternalName", "residual\0"
VALUE "LegalCopyright", "Copyright © 2003-2007 The ScummVM Team\0"
VALUE "LegalCopyright", "Copyright © 2003-2008 The ScummVM Team\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "residual.exe\0"
VALUE "PrivateBuild", "\0"

View File

@ -127,7 +127,7 @@ bool Actor::isTurning() const {
void Actor::walkForward() {
float dist = g_engine->perSecond(_walkRate);
float yaw_rad = _yaw * (M_PI / 180), pitch_rad = _pitch * (M_PI / 180);
float yaw_rad = _yaw * (LOCAL_PI / 180), pitch_rad = _pitch * (LOCAL_PI / 180);
//float yaw;
Vector3d forwardVec(-std::sin(yaw_rad) * std::cos(pitch_rad),
std::cos(yaw_rad) * std::cos(pitch_rad),
@ -178,7 +178,7 @@ void Actor::walkForward() {
break;
}
ei.angleWithEdge *= (float)(180.0 / M_PI);
ei.angleWithEdge *= (float)(180 / LOCAL_PI);
int turnDir = 1;
if (ei.angleWithEdge > 90) {
ei.angleWithEdge = 180 - ei.angleWithEdge;
@ -196,7 +196,7 @@ void Actor::walkForward() {
}
Vector3d Actor::puckVector() const {
float yaw_rad = _yaw * (M_PI / 180);
float yaw_rad = _yaw * (LOCAL_PI / 180);
Vector3d forwardVec(-std::sin(yaw_rad), std::cos(yaw_rad), 0);
Sector *sector = g_engine->currScene()->findPointSector(_pos, 0x1000);
@ -280,12 +280,12 @@ void Actor::turn(int dir) {
}
float Actor::angleTo(const Actor &a) const {
float yaw_rad = _yaw * (M_PI / 180);
float yaw_rad = _yaw * (LOCAL_PI / 180);
Vector3d forwardVec(-std::sin(yaw_rad), std::cos(yaw_rad), 0);
Vector3d delta = a.pos() - _pos;
delta.z() = 0;
return angle(forwardVec, delta) * (180 / M_PI);
return angle(forwardVec, delta) * (180 / LOCAL_PI);
}
float Actor::yawTo(Vector3d p) const {
@ -294,7 +294,7 @@ float Actor::yawTo(Vector3d p) const {
if (dpos.x() == 0 && dpos.y() == 0)
return 0;
else
return std::atan2(-dpos.x(), dpos.y()) * (180 / M_PI);
return std::atan2(-dpos.x(), dpos.y()) * (180 / LOCAL_PI);
}
void Actor::sayLine(const char *msg, const char *msgId) {

View File

@ -48,7 +48,7 @@ void DriverRonin::setupCamera(float fov, float nclip, float fclip, float roll)
clearMatrixStack();
float cot_fov = 1 / std::tan(fov * (M_PI / 180 / 2));
float cot_fov = 1 / std::tan(fov * (LOCAL_PI / 180 / 2));
float frustum[4][4] = {
{ (-640/2) * cot_fov, 0, 0, 0 },
{ 0, (480/2 / 0.75) * cot_fov, 0, 0 },

View File

@ -23,7 +23,7 @@
#ifndef BACKEND_DRIVER_H
#define BACKEND_DRIVER_H
#include "common/platform.h"
#include "common/sys.h"
#include "common/vector3d.h"
#include "common/mutex.h"

7
engine/backend/module.mk Normal file
View File

@ -0,0 +1,7 @@
MODULE := engine/backend
MODULE_OBJS := \
default-timer.o
# Include common rules
include $(srcdir)/rules.mk

View File

@ -21,6 +21,7 @@
*/
#include "common/debug.h"
#include "common/endian.h"
#include "engine/colormap.h"
#include "engine/material.h"
@ -82,7 +83,7 @@ void DriverGL::setupCamera(float fov, float nclip, float fclip, float roll) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float right = nclip * std::tan(fov / 2 * (M_PI / 180));
float right = nclip * std::tan(fov / 2 * (LOCAL_PI / 180));
glFrustum(-right, right, -right * 0.75, right * 0.75, nclip, fclip);
glMatrixMode(GL_MODELVIEW);

View File

@ -23,7 +23,7 @@
#ifndef BACKEND_DRIVER_GL_H
#define BACKEND_DRIVER_GL_H
#include "common/platform.h"
#include "common/sys.h"
#include "common/vector3d.h"
#include "engine/color.h"

View File

@ -24,6 +24,10 @@
#include "engine/backend/sdl/driver_sdl.h"
#ifdef _WIN32
#include <windows.h>
#endif
// NOTE: This is not a complete driver, it needs to be subclassed
// to provide rendering functionality.
@ -436,3 +440,17 @@ void DriverSDL::quit() {
if (SDL_PushEvent(&event) != 0)
error("Unable to push exit event!");
}
#if defined (WIN32)
int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*iShowCmd*/) {
SDL_SetModuleHandle(GetModuleHandle(NULL));
return main(__argc, __argv);
}
#endif
int main(int argc, char *argv[]) {
int res = residual_main(argc, argv);
return res;
}

View File

@ -20,6 +20,8 @@
*
*/
#include "common/sys.h"
#include "common/endian.h"
#include "common/debug.h"
#include "engine/colormap.h"
@ -147,7 +149,7 @@ void DriverTinyGL::setupCamera(float fov, float nclip, float fclip, float roll)
tglMatrixMode(TGL_PROJECTION);
tglLoadIdentity();
float right = nclip * std::tan(fov / 2 * (M_PI / 180));
float right = nclip * std::tan(fov / 2 * (LOCAL_PI / 180));
tglFrustum(-right, right, -right * 0.75, right * 0.75, nclip, fclip);
tglMatrixMode(TGL_MODELVIEW);

View File

@ -23,7 +23,7 @@
#ifndef BACKEND_DRIVER_TINYGL_H
#define BACKEND_DRIVER_TINYGL_H
#include "common/platform.h"
#include "common/sys.h"
#include "common/vector3d.h"
#include "engine/color.h"

View File

@ -0,0 +1,12 @@
MODULE := engine/backend/sdl
MODULE_OBJS := \
driver_gl.o \
driver_sdl.o \
driver_tinygl.o
MODULE_DIRS += \
engine/backend/sdl/
# We don't use the rules.mk here on purpose
OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS)

View File

@ -21,8 +21,8 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/debug.h"
#include "common/endian.h"
#include "engine/bitmap.h"
#include "engine/smush/smush.h"

View File

@ -23,7 +23,7 @@
#ifndef COLOR_H
#define COLOR_H
#include "common/platform.h"
#include "common/sys.h"
class Color {
public:

View File

@ -21,6 +21,7 @@
*/
#include "common/sys.h"
#include "common/endian.h"
#include "common/debug.h"
#include "engine/colormap.h"
@ -877,30 +878,30 @@ void Costume::Chore::update() {
}
Costume::Component *Costume::loadComponent (tag32 tag, Costume::Component *parent, int parentID, const char *name, Costume::Component *prevComponent) {
if (tag == MKID('MMDL'))
if (FROM_BE_32(tag) == MKID_BE('MMDL'))
return new MainModelComponent(parent, parentID, name, prevComponent, tag);
else if (tag == MKID('MODL'))
else if (FROM_BE_32(tag) == MKID_BE('MODL'))
return new ModelComponent(parent, parentID, name, prevComponent, tag);
else if (tag == MKID('CMAP'))
else if (FROM_BE_32(tag) == MKID_BE('CMAP'))
return new ColormapComponent(parent, parentID, name, tag);
else if (tag == MKID('KEYF'))
else if (FROM_BE_32(tag) == MKID_BE('KEYF'))
return new KeyframeComponent(parent, parentID, name, tag);
else if (tag == MKID('MESH'))
else if (FROM_BE_32(tag) == MKID_BE('MESH'))
return new MeshComponent(parent, parentID, name, tag);
else if (tag == MKID('LUAV'))
else if (FROM_BE_32(tag) == MKID_BE('LUAV'))
return new LuaVarComponent(parent, parentID, name, tag);
else if (tag == MKID('IMLS'))
else if (FROM_BE_32(tag) == MKID_BE('IMLS'))
return new SoundComponent(parent, parentID, name, tag);
else if (tag == MKID('BKND'))
else if (FROM_BE_32(tag) == MKID_BE('BKND'))
return new BitmapComponent(parent, parentID, name, tag);
else if (tag == MKID('MAT '))
else if (FROM_BE_32(tag) == MKID_BE('MAT '))
return new MaterialComponent(parent, parentID, name, tag);
else if (tag == MKID('SPRT'))
else if (FROM_BE_32(tag) == MKID_BE('SPRT'))
return NULL;// new SpriteComponent(parent, parentID, name);
char t[4];
std::memcpy(t, &tag, sizeof(tag32));
error("Unknown tag '%c%c%c%c', name '%s'\n", t[0], t[1], t[2], t[3], name);
error("loadComponent: Unknown tag '%c%c%c%c', name '%s'\n", t[0], t[1], t[2], t[3], name);
return NULL;
}
@ -911,7 +912,7 @@ Model::HierNode *Costume::getModelNodes()
continue;
// Needs to handle Main Models (pigeons) and normal Models
// (when Manny climbs the rope)
if (_components[i]->tag() == MKID('MMDL'))
if (_components[i]->tag() == MKID_BE('MMDL'))
return dynamic_cast<ModelComponent *>(_components[i])->hierarchy();
}
return NULL;

View File

@ -49,6 +49,8 @@ int g_flags = 0;
#ifdef _WIN32
#include <windows.h>
WIN32_FIND_DATAA g_find_file_data;
HANDLE g_searchFile;
bool g_firstFind;

View File

@ -207,19 +207,6 @@ extern int g_imuseState;
extern Actor *g_currentUpdatedActor;
#ifdef _WIN32
extern WIN32_FIND_DATAA g_find_file_data;
extern HANDLE g_searchFile;
extern bool g_firstFind;
#else
extern char g_find_file_data[100];
extern DIR *g_searchFile;
#endif
void vimaInit(uint16 *destTable);
void decompressVima(const byte *src, int16 *dest, int destLen, uint16 *destTable);

View File

@ -21,7 +21,7 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/endian.h"
#include "common/debug.h"
#include "engine/font.h"

View File

@ -23,7 +23,7 @@
#ifndef FONT_H
#define FONT_H
#include "common/platform.h"
#include "common/sys.h"
#include "engine/resource.h"

View File

@ -21,7 +21,6 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/debug.h"
#include "common/timer.h"
#include "common/mutex.h"

View File

@ -24,7 +24,6 @@
#define IMUSE_H
#include "common/sys.h"
#include "common/platform.h"
#include "common/debug.h"
#include "engine/lua.h"

View File

@ -21,7 +21,7 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/endian.h"
#include "common/debug.h"
#include "engine/resource.h"

View File

@ -24,7 +24,6 @@
#define MCMP_MGR_H
#include "common/sys.h"
#include "common/platform.h"
#include "common/debug.h"
#include "common/timer.h"

View File

@ -21,7 +21,6 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/debug.h"
#include "engine/imuse/imuse.h"

View File

@ -21,7 +21,6 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/debug.h"
#include "common/timer.h"
#include "common/mutex.h"

View File

@ -21,7 +21,7 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/endian.h"
#include "common/debug.h"
#include "common/timer.h"
@ -73,7 +73,7 @@ void ImuseSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps) {
}
void ImuseSndMgr::parseSoundHeader(byte *ptr, SoundDesc *sound, int &headerSize) {
if (READ_UINT32(ptr) == MKID('RIFF')) {
if (READ_BE_UINT32(ptr) == MKID_BE('RIFF')) {
sound->region = new Region[1];
sound->jump = new Jump[0];
sound->numJumps = 0;
@ -84,7 +84,7 @@ void ImuseSndMgr::parseSoundHeader(byte *ptr, SoundDesc *sound, int &headerSize)
sound->freq = READ_LE_UINT32(ptr + 24);
sound->channels = *(ptr + 22);
headerSize = 44;
} else if (READ_UINT32(ptr) == MKID('iMUS')) {
} else if (READ_BE_UINT32(ptr) == MKID_BE('iMUS')) {
uint32 tag;
int32 size = 0;
byte *s_ptr = ptr;

View File

@ -24,7 +24,6 @@
#define IMUSE_SNDMGR_H
#include "common/sys.h"
#include "common/platform.h"
#include "common/debug.h"
#include "common/timer.h"

View File

@ -21,7 +21,6 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/debug.h"
#include "engine/imuse/imuse.h"

View File

@ -24,7 +24,6 @@
#define IMUSE_TABLES_H
#include "common/sys.h"
#include "common/platform.h"
#include "common/debug.h"
#include "engine/lua.h"

View File

@ -21,7 +21,6 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/debug.h"
#include "common/mutex.h"

View File

@ -24,7 +24,6 @@
#define IMUSE_TRACK_H
#include "common/sys.h"
#include "common/platform.h"
#include "common/debug.h"
#include "engine/lua.h"

13
engine/imuse/module.mk Normal file
View File

@ -0,0 +1,13 @@
MODULE := engine/imuse
MODULE_OBJS := \
imuse.o \
imuse_mcmp_mgr.o \
imuse_music.o \
imuse_script.o \
imuse_sndmgr.o \
imuse_tables.o \
imuse_track.o
# Include common rules
include $(srcdir)/rules.mk

View File

@ -21,7 +21,7 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/endian.h"
#include "common/debug.h"
#include "engine/keyframe.h"

View File

@ -21,7 +21,7 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/endian.h"
#include "engine/lab.h"
#include <algorithm>

View File

@ -21,7 +21,7 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/endian.h"
#include "common/debug.h"
#include "engine/lipsynch.h"

View File

@ -23,7 +23,8 @@
#ifndef LIPSYNCH_H
#define LIPSYNCH_H
#include "common/platform.h"
#include "common/sys.h"
#include "engine/resource.h"
#include <list>

View File

@ -21,6 +21,8 @@
*/
#include "common/sys.h"
#include "common/endian.h"
#include "common/util.h"
#include "common/debug.h"
#include "engine/lua.h"
@ -50,6 +52,21 @@
extern Imuse *g_imuse;
#ifdef _WIN32
#include <windows.h>
extern WIN32_FIND_DATAA g_find_file_data;
extern HANDLE g_searchFile;
extern bool g_firstFind;
#else
extern char g_find_file_data[100];
extern DIR *g_searchFile;
#endif
#define strmatch(src, dst) (strlen(src) == strlen(dst) && strcmp(src, dst) == 0)
#define DEBUG_FUNCTION() debugFunction("Function", __FUNCTION__)
@ -58,35 +75,35 @@ static void stubWarning(char *funcName);
static inline bool isObject(int num) {
lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == MKID('STAT'))
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('STAT'))
return true;
return false;
}
static inline bool isActor(int num) {
lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == MKID('ACTR'))
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('ACTR'))
return true;
return false;
}
static inline bool isColor(int num) {
lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == MKID('COLR'))
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('COLR'))
return true;
return false;
}
static inline bool isFont(int num) {
lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == MKID('FONT'))
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('FONT'))
return true;
return false;
}
static inline bool isBitmapObject(int num) {
lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == MKID('VBUF'))
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('VBUF'))
return true;
return false;
}
@ -94,7 +111,7 @@ static inline bool isBitmapObject(int num) {
// Helper functions to ensure the arguments we get are what we expect
static inline ObjectState *check_object(int num) {
lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == MKID('STAT'))
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('STAT'))
return static_cast<ObjectState *>(lua_getuserdata(param));
luaL_argerror(num, "objectstate expected");
return NULL;
@ -102,7 +119,7 @@ static inline ObjectState *check_object(int num) {
static inline Actor *check_actor(int num) {
lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == MKID('ACTR'))
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('ACTR'))
return static_cast<Actor *>(lua_getuserdata(param));
luaL_argerror(num, "actor expected");
return NULL;
@ -110,7 +127,7 @@ static inline Actor *check_actor(int num) {
static inline Color *check_color(int num) {
lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == MKID('COLR'))
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('COLR'))
return static_cast<Color *>(lua_getuserdata(param));
luaL_argerror(num, "color expected");
return NULL;
@ -118,7 +135,7 @@ static inline Color *check_color(int num) {
static inline Font *check_font(int num) {
lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == MKID('FONT'))
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('FONT'))
return static_cast<Font *>(lua_getuserdata(param));
luaL_argerror(num, "font expected");
return NULL;
@ -126,7 +143,7 @@ static inline Font *check_font(int num) {
static inline PrimitiveObject *check_primobject(int num) {
lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == MKID('PRIM'))
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('PRIM'))
return static_cast<PrimitiveObject *>(lua_getuserdata(param));
luaL_argerror(num, "primitive expected");
return NULL;
@ -134,7 +151,7 @@ static inline PrimitiveObject *check_primobject(int num) {
static inline TextObject *check_textobject(int num) {
lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == MKID('TEXT'))
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('TEXT'))
return static_cast<TextObject *>(lua_getuserdata(param));
luaL_argerror(num, "textobject expected");
return NULL;
@ -142,7 +159,7 @@ static inline TextObject *check_textobject(int num) {
static inline Bitmap *check_bitmapobject(int num) {
lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == MKID('VBUF'))
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('VBUF'))
return static_cast<Bitmap *>(lua_getuserdata(param));
luaL_argerror(num, "image object expected");
return NULL;
@ -315,7 +332,7 @@ static void MakeColor() {
DEBUG_FUNCTION();
c = new Color (clamp_color(check_int(1)), clamp_color(check_int(2)), clamp_color(check_int(3)));
lua_pushusertag(c, MKID('COLR'));
lua_pushusertag(c, MKID_BE('COLR'));
}
static void GetColorComponents() {
@ -360,7 +377,7 @@ static void LoadActor() {
name = "<unnamed>";
else
name = luaL_check_string(1);
lua_pushusertag(new Actor(name), MKID('ACTR'));
lua_pushusertag(new Actor(name), MKID_BE('ACTR'));
}
static void GetActorTimeScale() {
@ -388,7 +405,7 @@ static void GetCameraActor() {
DEBUG_FUNCTION();
stubWarning("VERIFY: GetCameraActor");
act = g_engine->selectedActor();
lua_pushusertag(act, MKID('ACTR'));
lua_pushusertag(act, MKID_BE('ACTR'));
}
static void SetSayLineDefaults() {
@ -439,7 +456,7 @@ static void GetActorTalkColor() {
DEBUG_FUNCTION();
act = check_actor(1);
c = new Color(act->talkColor());
lua_pushusertag(c, MKID('COLR'));
lua_pushusertag(c, MKID_BE('COLR'));
}
static void SetActorRestChore() {
@ -1254,8 +1271,8 @@ static void RotateVector() {
rotateObject = getIndexedTableValue(param2, 2);
rotate = lua_getnumber(rotateObject);
Vector3d baseVector(std::sin(0.0f), std::cos(0.0f), 0);
currAngle = angle(baseVector, vec1) * (180 / M_PI);
newAngle = (currAngle - rotate) * (M_PI / 180);
currAngle = angle(baseVector, vec1) * (180 / LOCAL_PI);
newAngle = (currAngle - rotate) * (LOCAL_PI / 180);
Vector3d vec2(std::sin(newAngle), std::cos(newAngle), 0);
vec2 *= vec1.magnitude();
@ -1388,7 +1405,7 @@ static void GetVisibleThings() {
// Consider the active actor visible
if (sel == (*i) || sel->angleTo(*(*i)) < 90) {
lua_pushobject(result);
lua_pushusertag(*i, MKID('ACTR'));
lua_pushusertag(*i, MKID_BE('ACTR'));
lua_pushnumber(1);
lua_settable();
}
@ -2265,7 +2282,7 @@ static void GetImage() {
bitmapName = luaL_check_string(1);
Bitmap *image = g_resourceloader->loadBitmap(bitmapName);
image->luaRef();
lua_pushusertag(image, MKID('VBUF'));
lua_pushusertag(image, MKID_BE('VBUF'));
}
static void FreeImage() {
@ -2469,7 +2486,7 @@ static void MakeTextObject() {
textObject->createBitmap();
g_engine->registerTextObject(textObject);
lua_pushusertag(textObject, MKID('TEXT'));
lua_pushusertag(textObject, MKID_BE('TEXT'));
lua_pushnumber(textObject->getBitmapWidth());
lua_pushnumber(textObject->getBitmapHeight());
}
@ -2660,7 +2677,7 @@ static void DrawPolygon() {
lua_pushobject(tableObj2);
lua_pushstring("color");
lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID('COLR')) {
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID_BE('COLR')) {
color = static_cast<Color *>(lua_getuserdata(colorObj));
}
}
@ -2668,7 +2685,7 @@ static void DrawPolygon() {
PrimitiveObject *p = new PrimitiveObject();
p->createPolygon(x1, y1, x2, y2, x3, y3, x4, y4, color);
g_engine->registerPrimitiveObject(p);
lua_pushusertag(p, MKID('PRIM'));
lua_pushusertag(p, MKID_BE('PRIM'));
}
static void DrawLine() {
@ -2690,7 +2707,7 @@ static void DrawLine() {
lua_pushobject(tableObj);
lua_pushstring("color");
lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID('COLR')) {
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID_BE('COLR')) {
color = static_cast<Color *>(lua_getuserdata(colorObj));
}
}
@ -2698,7 +2715,7 @@ static void DrawLine() {
PrimitiveObject *p = new PrimitiveObject();
p->createLine(x1, x2, y1, y2, color);
g_engine->registerPrimitiveObject(p);
lua_pushusertag(p, MKID('PRIM'));
lua_pushusertag(p, MKID_BE('PRIM'));
}
static void ChangePrimitive() {
@ -2734,7 +2751,7 @@ static void ChangePrimitive() {
lua_pushobject(tableObj);
lua_pushstring("color");
lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID('COLR')) {
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID_BE('COLR')) {
color = static_cast<Color *>(lua_getuserdata(colorObj));
pmodify->setColor(color);
}
@ -2781,7 +2798,7 @@ static void DrawRectangle() {
lua_pushobject(tableObj);
lua_pushstring("color");
lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID('COLR')) {
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID_BE('COLR')) {
color = static_cast<Color *>(lua_getuserdata(colorObj));
}
@ -2795,7 +2812,7 @@ static void DrawRectangle() {
PrimitiveObject *p = new PrimitiveObject();
p->createRectangle(x1, x2, y1, y2, color, filled);
g_engine->registerPrimitiveObject(p);
lua_pushusertag(p, MKID('PRIM'));
lua_pushusertag(p, MKID_BE('PRIM'));
}
static void BlastRect() {
@ -2819,7 +2836,7 @@ static void BlastRect() {
lua_pushobject(tableObj);
lua_pushstring("color");
lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID('COLR')) {
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID_BE('COLR')) {
color = static_cast<Color *>(lua_getuserdata(colorObj));
}
@ -2878,7 +2895,7 @@ static void NewObjectState() {
state = new ObjectState(setupID, pos, bitmap, zbitmap, visible);
g_engine->currScene()->addObjectState(state);
lua_pushusertag(state, MKID('STAT'));
lua_pushusertag(state, MKID_BE('STAT'));
}
static void FreeObjectState() {
@ -2894,7 +2911,7 @@ static void SendObjectToBack() {
DEBUG_FUNCTION();
param = lua_getparam(1);
if (lua_isuserdata(param) && lua_tag(param) == MKID('STAT')) {
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('STAT')) {
ObjectState *state = static_cast<ObjectState *>(lua_getuserdata(param));
// moving object to top in list ?
g_engine->currScene()->moveObjectStateToFirst(state);
@ -2906,7 +2923,7 @@ static void SendObjectToFront() {
DEBUG_FUNCTION();
param = lua_getparam(1);
if (lua_isuserdata(param) && lua_tag(param) == MKID('STAT')) {
if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('STAT')) {
ObjectState *state = static_cast<ObjectState *>(lua_getuserdata(param));
// moving object to last in list ?
g_engine->currScene()->moveObjectStateToLast(state);
@ -2942,7 +2959,7 @@ static void ScreenShot() {
g_engine->setMode(mode);
if (screenshot) {
screenshot->luaRef();
lua_pushusertag(screenshot, MKID('VBUF'));
lua_pushusertag(screenshot, MKID_BE('VBUF'));
} else {
lua_pushnil();
}
@ -2968,7 +2985,7 @@ static void GetSaveGameImage() {
screenshot = new Bitmap(data, width, height, "screenshot");
if (screenshot) {
screenshot->luaRef();
lua_pushusertag(screenshot, MKID('VBUF'));
lua_pushusertag(screenshot, MKID_BE('VBUF'));
} else {
lua_pushnil();
error("Could not restore screenshot from file!");
@ -3099,7 +3116,7 @@ static void LockFont() {
Font *result = g_resourceloader->loadFont(fontName);
if (result) {
result->luaRef();
lua_pushusertag(result, MKID('FONT'));
lua_pushusertag(result, MKID_BE('FONT'));
}
}
}
@ -3231,10 +3248,10 @@ static void debugFunction(char *debugMessage, const char *funcName) {
else if (lua_istable(lua_getparam(i)))
fprintf(output, "{...}");
else if (lua_isuserdata(lua_getparam(i))) {
if (lua_tag(lua_getparam(i)) == MKID('ACTR')) {
if (lua_tag(lua_getparam(i)) == MKID_BE('ACTR')) {
Actor *a = check_actor(i);
fprintf(output, "<actor \"%s\">", a->name());
} else if (lua_tag(lua_getparam(i)) == MKID('COLR')) {
} else if (lua_tag(lua_getparam(i)) == MKID_BE('COLR')) {
Color *c = check_color(i);
fprintf(output, "<color #%02x%02x%02x>", c->red(), c->green(), c->blue());
} else

View File

@ -23,6 +23,8 @@
#ifndef LUA_HH
#define LUA_HH
#include "common/vector3d.h"
#include "engine/lua/lua.h"
#include "engine/lua/lualib.h"
#include "engine/lua/luadebug.h"

View File

@ -12,13 +12,13 @@
#include "lua.h"
#include "lualib.h"
#ifndef PI
#define PI ((double)3.14159265358979323846)
#ifndef LOCAL_PI
#define LOCAL_PI (3.14159265358979323846)
#endif
#define FROMRAD(a) ((a)*(180.0/PI))
#define TORAD(a) ((a)*(PI/180.0))
#define FROMRAD(a) ((a)*(180.0/LOCAL_PI))
#define TORAD(a) ((a)*(LOCAL_PI/180.0))
static void math_abs (void)
@ -105,12 +105,12 @@ static void math_exp (void)
static void math_deg (void)
{
lua_pushnumber(luaL_check_number(1)*(180.0/PI));
lua_pushnumber(luaL_check_number(1)*(180.0/LOCAL_PI));
}
static void math_rad (void)
{
lua_pushnumber(luaL_check_number(1)*(PI/180.0));
lua_pushnumber(luaL_check_number(1)*(LOCAL_PI/180.0));
}
static void math_frexp (void) {
@ -211,6 +211,6 @@ void lua_mathlibopen (void)
lua_pushcfunction(math_pow);
lua_pushnumber(0); /* to get its tag */
lua_settagmethod(lua_tag(lua_pop()), "pow");
lua_pushnumber(PI); lua_setglobal("PI");
lua_pushnumber(LOCAL_PI); lua_setglobal("PI");
}

30
engine/lua/module.mk Normal file
View File

@ -0,0 +1,30 @@
MODULE := engine/lua
MODULE_OBJS := \
lapi.o \
lauxlib.o \
lbuffer.o \
lbuiltin.o \
ldo.o \
lfunc.o \
lgc.o \
liolib.o \
llex.o \
lmathlib.o \
lmem.o \
lobject.o \
lparser.o \
lrestore.o \
lsave.o \
lstate.o \
lstring.o \
lstrlib.o \
ltable.o \
ltask.o \
ltm.o \
lundump.o \
lvm.o \
lzio.o
# Include common rules
include $(srcdir)/rules.mk

View File

@ -22,6 +22,7 @@
#include "common/sys.h"
#include "common/debug.h"
#include "common/timer.h"
#include "engine/bitmap.h"
#include "engine/resource.h"
@ -29,7 +30,6 @@
#include "engine/registry.h"
#include "engine/localize.h"
#include "engine/engine.h"
#include "common/timer.h"
#include "engine/smush/smush.h"
#include "engine/backend/sdl/driver_gl.h"
@ -42,16 +42,6 @@
#include <SDL.h>
#include <SDL_video.h>
#if defined (WIN32) && !defined (_MSC_VER)
int WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*iShowCmd*/) {
return main(__argc, __argv);
}
#endif
#ifdef _MSC_VER
#undef main
#endif
// Hacky global toggles for experimental/debug code
bool ZBUFFER_GLOBAL, SHOWFPS_GLOBAL, TINYGL_GLOBAL;
enDebugLevels debugLevel = DEBUG_NONE;
@ -89,7 +79,7 @@ static bool parseBoolStr(const char *val) {
void quit();
int main(int argc, char *argv[]) {
extern "C" int residual_main(int argc, char *argv[]) {
int i;
g_registry = new Registry();

View File

@ -21,7 +21,7 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/endian.h"
#include "common/debug.h"
#include "engine/material.h"

View File

@ -21,7 +21,7 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/endian.h"
#include "common/debug.h"
#include "engine/model.h"

28
engine/module.mk Normal file
View File

@ -0,0 +1,28 @@
MODULE := engine
MODULE_OBJS := \
actor.o \
bitmap.o \
costume.o \
engine.o \
font.o \
keyframe.o \
lab.o \
lipsynch.o \
localize.o \
lua.o \
main.o \
material.o \
model.o \
objectstate.o \
primitives.o \
registry.o \
resource.o \
savegame.o \
scene.o \
textobject.o \
textsplit.o \
walkplane.o
# Include common rules
include $(srcdir)/rules.mk

View File

@ -40,6 +40,10 @@
#include <string>
#include <algorithm>
#ifdef _WIN32
#include <windows.h>
#endif
static void makeLower(std::string& s) {
std::transform(s.begin(), s.end(), s.begin(), tolower);
}

View File

@ -21,7 +21,7 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/endian.h"
#include "common/debug.h"
#include "engine/smush/blocky16.h"

View File

@ -23,7 +23,7 @@
#ifndef BLOCKY16_H
#define BLOCKY16_H
#include "common/platform.h"
#include "common/sys.h"
class Blocky16 {
private:

9
engine/smush/module.mk Normal file
View File

@ -0,0 +1,9 @@
MODULE := engine/smush
MODULE_OBJS := \
blocky16.o \
smush.o \
vima.o
# Include common rules
include $(srcdir)/rules.mk

View File

@ -21,7 +21,7 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/endian.h"
#include "common/debug.h"
#include "common/timer.h"

View File

@ -24,7 +24,6 @@
#define SMUSH_PLAYER_H
#include "common/sys.h"
#include "common/platform.h"
#include "common/debug.h"
#include "engine/smush/blocky16.h"

View File

@ -21,7 +21,7 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/endian.h"
#include "common/debug.h"
static int16 imcTable1[] = {

View File

@ -21,6 +21,7 @@
*/
#include "common/sys.h"
#include "common/util.h"
#include "engine/textobject.h"
#include "engine/engine.h"

View File

@ -115,7 +115,7 @@ void glopLight(GLContext *c, TGLParam *p) {
assert(a == 180 || (a >= 0 && a <= 90));
l->spot_cutoff=a;
if (a != 180)
l->cos_spot_cutoff = (float)(cos(a * PI / 180.0));
l->cos_spot_cutoff = (float)(cos(a * LOCAL_PI / 180.0));
}
break;
case TGL_CONSTANT_ATTENUATION:

View File

@ -104,7 +104,7 @@ void glopRotate(GLContext *c, TGLParam *p) {
float angle;
int dir_code;
angle = (float)(p[1].f * PI / 180.0);
angle = (float)(p[1].f * LOCAL_PI / 180.0);
u[0] = p[2].f;
u[1] = p[3].f;
u[2] = p[4].f;

28
engine/tinygl/module.mk Normal file
View File

@ -0,0 +1,28 @@
MODULE := engine/tinygl
MODULE_OBJS := \
api.o \
arrays.o \
clear.o \
clip.o \
error.o \
get.o \
image_util.o \
init.o \
light.o \
list.o \
matrix.o \
memory.o \
misc.o \
msghandling.o \
select.o \
specbuf.o \
texture.o \
vertex.o \
zbuffer.o \
zline.o \
zmath.o \
ztriangle.o
# Include common rules
include $(srcdir)/rules.mk

View File

@ -322,10 +322,6 @@ GLContext *gl_get_context(void);
void gl_fatal_error(char *format, ...);
#ifndef PI
#define PI 3.14159265358979323846
#endif
// specular buffer "api"
GLSpecBuf *specbuf_get_buffer(GLContext *c, const int shininess_i, const float shininess);
@ -335,6 +331,10 @@ GLSpecBuf *specbuf_get_buffer(GLContext *c, const int shininess_i, const float s
#define dprintf
#endif
#ifndef LOCAL_PI
#define LOCAL_PI (3.14159265358979323846)
#endif
// glopXXX functions
#define ADD_OP(a,b,c) void glop ## a (GLContext *, TGLParam *);

View File

@ -21,13 +21,15 @@
*/
#include "common/sys.h"
#include "common/debug.h"
#include "common/endian.h"
#include "common/list.h"
#include "common/util.h"
#include "engine/backend/driver.h"
#include "mixer/mixer.h"
#include "mixer/audiostream.h"
#include "mixer/mixer.h"
// This used to be an inline template function, but
// buggy template function handling in MSVC6 forced
@ -44,6 +46,11 @@ namespace Audio {
#pragma mark --- LinearMemoryStream ---
#pragma mark -
inline int32 calculatePlayTime(int rate, int samples) {
int32 seconds = samples / rate;
int32 milliseconds = (1000 * (samples % rate)) / rate;
return seconds * 1000 + milliseconds;
}
/**
* A simple raw audio stream, purely memory based. It operates on a single
@ -64,23 +71,26 @@ protected:
const byte *_loopEnd;
const int _rate;
const byte *_origPtr;
const int32 _playtime;
public:
LinearMemoryStream(int rate, const byte *ptr, uint len, uint loopOffset, uint loopLen, bool autoFreeMemory)
: _ptr(ptr), _end(ptr+len), _loopPtr(0), _loopEnd(0), _rate(rate) {
: _ptr(ptr), _end(ptr+len), _loopPtr(0), _loopEnd(0), _rate(rate), _playtime(calculatePlayTime(rate, len / (is16Bit ? 2 : 1) / (stereo ? 2 : 1))) {
// Verify the buffer sizes are sane
if (is16Bit && stereo)
if (is16Bit && stereo) {
assert((len & 3) == 0 && (loopLen & 3) == 0);
else if (is16Bit || stereo)
} else if (is16Bit || stereo) {
assert((len & 1) == 0 && (loopLen & 1) == 0);
}
if (loopLen) {
_loopPtr = _ptr + loopOffset;
_loopEnd = _loopPtr + loopLen;
}
if (stereo) // Stereo requires even sized data
if (stereo) { // Stereo requires even sized data
assert(len % 2 == 0);
}
_origPtr = autoFreeMemory ? ptr : 0;
}
@ -89,10 +99,11 @@ public:
}
int readBuffer(int16 *buffer, const int numSamples);
bool isStereo() const { return stereo; }
bool endOfData() const { return _ptr >= _end; }
bool isStereo() const { return stereo; }
bool endOfData() const { return _ptr >= _end; }
int getRate() const { return _rate; }
int getRate() const { return _rate; }
int32 getTotalPlayTime() const { return _playtime; }
};
template<bool stereo, bool is16Bit, bool isUnsigned, bool isLE>
@ -242,7 +253,7 @@ int AppendableMemoryStream<stereo, is16Bit, isUnsigned, isLE>::readBuffer(int16
assert(buf.start <= _pos && _pos <= buf.end);
const int samplesLeftInCurBuffer = buf.end - _pos;
if (samplesLeftInCurBuffer == 0) {
delete [] buf.start;
delete[] buf.start;
_bufferQueue.erase(_bufferQueue.begin());
_pos = 0;
continue;
@ -264,10 +275,11 @@ void AppendableMemoryStream<stereo, is16Bit, isUnsigned, isLE>::queueBuffer(byte
Common::StackLock lock(_mutex);
// Verify the buffer size is sane
if (is16Bit && stereo)
if (is16Bit && stereo) {
assert((size & 3) == 0);
else if (is16Bit || stereo)
} else if (is16Bit || stereo) {
assert((size & 1) == 0);
}
// Verify that the stream has not yet been finalized (by a call to finish())
assert(!_finalized);

View File

@ -24,7 +24,6 @@
#define AUDIOSTREAM_H
#include "common/sys.h"
#include "common/platform.h"
namespace Audio {
@ -90,7 +89,7 @@ AudioStream *makeLinearInputStream(const byte *ptr, uint32 len, int rate, byte f
/**
* An audio stream to which additional data can be appended on-the-fly.
* Used by SMUSH, iMuseDigital, and the Kyrandia 3 VQA player.
* Used by SMUSH, iMuseDigital, the Kyrandia 3 VQA player, etc.
*/
class AppendableAudioStream : public Audio::AudioStream {
public:
@ -107,7 +106,7 @@ public:
/**
* Mark the stream as finished, that is, signal that no further data
* will be appended to it. Only after this has been done can the
* AppendableAudioStream ever 'end' (
* AppendableAudioStream ever 'end'
*/
virtual void finish() = 0;
};

View File

@ -21,7 +21,7 @@
*/
#include "common/sys.h"
#include "common/platform.h"
#include "common/util.h"
#include "common/debug.h"
#include "engine/backend/driver.h"

View File

@ -24,7 +24,6 @@
#define SOUND_MIXER_H
#include "common/sys.h"
#include "common/platform.h"
#include "common/mutex.h"
namespace Audio {

18
mixer/module.mk Normal file
View File

@ -0,0 +1,18 @@
MODULE := mixer
MODULE_OBJS := \
audiostream.o \
mixer.o \
rate.o
ifndef USE_ARM_SOUND_ASM
MODULE_OBJS += \
rate.o
else
MODULE_OBJS += \
rate_arm.o \
rate_arm_asm.o
endif
# Include common rules
include $(srcdir)/rules.mk

View File

@ -29,6 +29,7 @@
*/
#include "common/sys.h"
#include "common/util.h"
#include "common/debug.h"
#include "common/frac.h"

View File

@ -23,7 +23,7 @@
#ifndef SOUND_RATE_H
#define SOUND_RATE_H
#include "common/platform.h"
#include "common/sys.h"
class AudioStream;

177
ports.mk Normal file
View File

@ -0,0 +1,177 @@
# This file contains port specific Makefile rules. It is automatically
# included by the default (main) Makefile.
#
# $URL$
# $Id$
#
# UNIX specific
#
install: all
$(INSTALL) -d "$(DESTDIR)$(BINDIR)"
$(INSTALL) -c -s -m 755 "$(srcdir)/residual$(EXEEXT)" "$(DESTDIR)$(BINDIR)/residual$(EXEEXT)"
#$(INSTALL) -d "$(DESTDIR)$(MANDIR)/man6/"
#$(INSTALL) -c -m 644 "$(srcdir)/dists/residual.6" "$(DESTDIR)$(MANDIR)/man6/residual.6"
#$(INSTALL) -d "$(DESTDIR)$(PREFIX)/share/pixmaps/"
#$(INSTALL) -c -m 644 "$(srcdir)/icons/residual.xpm" "$(DESTDIR)$(PREFIX)/share/pixmaps/residual.xpm"
#$(INSTALL) -d "$(DESTDIR)$(PREFIX)/share/doc/residual/"
$(INSTALL) -c -m 644 "$(srcdir)/AUTHORS" "$(srcdir)/COPYING" "$(srcdir)/COPYRIGHT" "$(srcdir)/NEWS" "$(srcdir)/README" "$(DESTDIR)$(PREFIX)/share/doc/residual/"
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/residual/"
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) "$(DESTDIR)$(DATADIR)/residual/"
uninstall:
rm -f "$(DESTDIR)$(BINDIR)/residual$(EXEEXT)"
#rm -f "$(DESTDIR)$(MANDIR)/man6/residual.6"
#rm -f "$(DESTDIR)$(PREFIX)/share/pixmaps/residual.xpm"
#rm -rf "$(DESTDIR)$(PREFIX)/share/doc/residual/"
#rm -rf "$(DESTDIR)$(DATADIR)/residual/"
deb:
ln -sf dists/debian;
debian/prepare
fakeroot debian/rules binary
# Special target to create a application wrapper for Mac OS X
bundle_name = Residual.app
bundle: scummvm-static $(srcdir)/dists/macosx/Info.plist
mkdir -p $(bundle_name)/Contents/MacOS
mkdir -p $(bundle_name)/Contents/Resources
echo "APPL????" > $(bundle_name)/Contents/PkgInfo
cp $(srcdir)/dists/macosx/Info.plist $(bundle_name)/Contents/
cp $(srcdir)/icons/residual.icns $(bundle_name)/Contents/Resources/
cp $(srcdir)/dists/pred.dic $(bundle_name)/Contents/Resources/
cp $(DIST_FILES_THEMES) $(bundle_name)/Contents/Resources/
cp $(DIST_FILES_ENGINEDATA) $(bundle_name)/Contents/Resources/
$(srcdir)/tools/credits.pl --rtf > $(bundle_name)/Contents/Resources/Credits.rtf
chmod 644 $(bundle_name)/Contents/Resources/*
cp residual-static $(bundle_name)/Contents/MacOS/residual
chmod 755 $(bundle_name)/Contents/MacOS/residual
strip $(bundle_name)/Contents/MacOS/residual
iphonebundle: $(srcdir)/dists/iphone/Info.plist
mkdir -p $(bundle_name)
cp $(srcdir)/dists/iphone/Info.plist $(bundle_name)/
cp $(srcdir)/dists/pred.dic $(bundle_name)/
cp $(DIST_FILES_THEMES) $(bundle_name)/
cp $(DIST_FILES_ENGINEDATA) $(bundle_name)/
cp residual $(bundle_name)/Residual
cp $(srcdir)/dists/iphone/icon.png $(bundle_name)/icon.png
cp $(srcdir)/dists/iphone/Default.png $(bundle_name)/Default.png
# location of additional libs for OS X usually /sw/ for fink or
# /opt/local/ for darwinports
OSXOPT=/sw
# Location of static libs for the iPhone
ifeq ($(BACKEND), iphone)
OSXOPT=/usr/local/arm-apple-darwin
else
# Static libaries, used for the scummvm-static and iphone targets
OSX_STATIC_LIBS := `$(OSXOPT)/bin/sdl-config --static-libs`
endif
ifdef USE_VORBIS
OSX_STATIC_LIBS += \
$(OSXOPT)/lib/libvorbisfile.a \
$(OSXOPT)/lib/libvorbis.a \
$(OSXOPT)/lib/libogg.a
endif
ifdef USE_TREMOR
OSX_STATIC_LIBS += $(OSXOPT)/lib/libvorbisidec.a
endif
ifdef USE_FLAC
OSX_STATIC_LIBS += $(OSXOPT)/lib/libFLAC.a
endif
ifdef USE_MAD
OSX_STATIC_LIBS += $(OSXOPT)/lib/libmad.a
endif
ifdef USE_MPEG2
OSX_STATIC_LIBS += $(OSXOPT)/lib/libmpeg2.a
endif
# Special target to create a static linked binary for Mac OS X.
# We use -force_cpusubtype_ALL to ensure the binary runs on every
# PowerPC machine.
residual-static: $(OBJS)
$(CXX) $(LDFLAGS) -force_cpusubtype_ALL -o residual-static $(OBJS) \
-framework CoreMIDI \
$(OSX_STATIC_LIBS) \
-lSystemStubs \
-lz
# $(OSXOPT)/lib/libz.a
# Special target to create a static linked binary for the iPhone
iphone: $(OBJS)
$(CXX) $(LDFLAGS) -o residual $(OBJS) \
$(OSX_STATIC_LIBS) \
-framework UIKit -framework CoreGraphics -framework CoreSurface \
-framework LayerKit -framework GraphicsServices -framework CoreFoundation \
-framework Foundation -framework AudioToolbox -framework CoreAudio \
-lobjc -lz
# Special target to create a snapshot disk image for Mac OS X
# TODO: Replace AUTHORS by Credits.rtf
osxsnap: bundle credits
mkdir Residual-snapshot
cp $(srcdir)/AUTHORS ./Residual-snapshot/Authors
cp $(srcdir)/COPYING ./Residual-snapshot/License
cp $(srcdir)/COPYRIGHT ./Residual-snapshot/Copyright\ Holders
cp $(srcdir)/NEWS ./Residual-snapshot/News
cp $(srcdir)/README ./Residual-snapshot/Residual\ ReadMe
/Developer/Tools/SetFile -t ttro -c ttxt ./Residual-snapshot/*
/Developer/Tools/CpMac -r $(bundle_name) ./Residual-snapshot/
cp $(srcdir)/dists/macosx/DS_Store ./Residual-snapshot/.DS_Store
cp $(srcdir)/dists/macosx/background.jpg ./Residual-snapshot/background.jpg
/Developer/Tools/SetFile -a V ./Residual-snapshot/.DS_Store
/Developer/Tools/SetFile -a V ./Residual-snapshot/background.jpg
hdiutil create -ov -format UDZO -imagekey zlib-level=9 -fs HFS+ \
-srcfolder Residual-snapshot \
-volname "Residual snapshot" \
Residual-snapshot.dmg
rm -rf Residual-snapshot
#
# Windows specific
#
residualico.o: $(srcdir)/icons/residual.ico
$(WINDRES) -I$(srcdir) $(srcdir)/dists/residual.rc residualico.o
# Special target to create a win32 snapshot binary
win32dist: residual$(EXEEXT)
mkdir -p $(WIN32PATH)
#strip residual.exe -o $(WIN32PATH)/residual$(EXEEXT)
#cp $(srcdir)/AUTHORS $(WIN32PATH)/AUTHORS.txt
cp $(srcdir)/COPYING $(WIN32PATH)/COPYING.txt
#cp $(srcdir)/COPYRIGHT $(WIN32PATH)/COPYRIGHT.txt
#cp $(srcdir)/NEWS $(WIN32PATH)/NEWS.txt
cp $(srcdir)/README $(WIN32PATH)/README.txt
cp /usr/local/README-SDL.txt $(WIN32PATH)
cp /usr/local/bin/SDL.dll $(WIN32PATH)
u2d $(WIN32PATH)/*.txt
#
# AmigaOS specific
#
# Special target to create an AmigaOS snapshot installation
aos4dist: residual
mkdir -p $(AOS4PATH)
strip -R.comment $< -o $(AOS4PATH)/$<_SVN
cp icons/residual.info $(AOS4PATH)/$<_SVN.info
cp $(DIST_FILES_THEMES) $(AOS4PATH)/themes/
cp $(DIST_FILES_ENGINEDATA) $(AOS4PATH)/extras/
#cp $(srcdir)/AUTHORS $(AOS4PATH)/AUTHORS.txt
cp $(srcdir)/COPYING $(AOS4PATH)/COPYING.txt
#cp $(srcdir)/COPYRIGHT $(AOS4PATH)/COPYRIGHT.txt
#cp $(srcdir)/NEWS $(AOS4PATH)/NEWS.txt
cp $(srcdir)/README $(AOS4PATH)/README.txt
cp /sdk/local/documentation/SDL-1.2.9/README-SDL.txt $(AOS4PATH)
.PHONY: deb bundle osxsnap win32dist install uninstall

67
rules.mk Normal file
View File

@ -0,0 +1,67 @@
###############################################
# Common build rules, used by the sub modules and their module.mk files
#
# $URL$
# $Id$
###############################################
# Copy the list of objects to a new variable. The name of the new variable
# contains the module name, a trick we use so we can keep multiple different
# module object lists, one for each module.
MODULE_OBJS-$(MODULE) := $(addprefix $(MODULE)/, $(MODULE_OBJS))
# Add all involved directories to the MODULE_DIRS list
MODULE_DIRS += $(sort $(dir $(MODULE_OBJS-$(MODULE))))
ifdef TOOL_EXECUTABLE
################################################
# Build rule for (tool) executables.
# TODO: Refactor this, so that even our master executable can use this rule?
################################################
TOOL-$(MODULE) := $(MODULE)/$(TOOL_EXECUTABLE)$(EXEEXT)
$(TOOL-$(MODULE)): $(MODULE_OBJS-$(MODULE))
$(CXX) $(LDFLAGS) $+ -o $@
# Reset TOOL_EXECUTABLE var
TOOL_EXECUTABLE:=
# Add to "tools" target
tools: $(TOOL-$(MODULE))
# Pseudo target for comfort, allows for "make tools/skycpt", etc.
$(MODULE): $(TOOL-$(MODULE))
clean-tools: clean-$(MODULE)
else
################################################
# Build rule for static modules/plugins
################################################
MODULE_LIB-$(MODULE) := $(MODULE)/lib$(notdir $(MODULE)).a
# If not building as a plugin, add the object files to the main OBJS list
OBJS += $(MODULE_LIB-$(MODULE))
# Convenience library target
$(MODULE_LIB-$(MODULE)): $(MODULE_OBJS-$(MODULE))
-$(RM) $@
$(AR) $@ $+
$(RANLIB) $@
# Pseudo target for comfort, allows for "make common", "make gui" etc.
$(MODULE): $(MODULE_LIB-$(MODULE))
endif # TOOL_EXECUTABLE
###############################################
# Clean target, removes all object files. This looks a bit hackish, as we have to
# copy the content of MODULE_OBJS to another unique variable (the next module.mk
# will overwrite it after all). The same for the libMODULE.a library file.
###############################################
clean: clean-$(MODULE)
clean-$(MODULE): clean-% :
-$(RM) $(MODULE_OBJS-$*) $(MODULE_LIB-$*) $(PLUGIN-$*) $(TOOL-$*)
.PHONY: clean-$(MODULE) $(MODULE)